basic lttvwindow works
[lttv.git] / ltt / branches / poly / lttv / modules / gui / controlflow / eventhooks.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19
20 /*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
23
24
25 //#define PANGO_ENABLE_BACKEND
26 #include <gtk/gtk.h>
27 #include <gdk/gdk.h>
28 #include <glib.h>
29 #include <assert.h>
30 #include <string.h>
31 #include <stdio.h>
32
33 //#include <pango/pango.h>
34
35 #include <ltt/event.h>
36 #include <ltt/time.h>
37 #include <ltt/type.h>
38
39 #include <lttv/lttv.h>
40 #include <lttv/hook.h>
41 #include <lttv/state.h>
42 #include <lttvwindow/lttvwindow.h>
43
44
45 #include "eventhooks.h"
46 #include "cfv.h"
47 #include "processlist.h"
48 #include "drawing.h"
49 #include "cfv-private.h"
50
51
52 #define MAX_PATH_LEN 256
53
54
55 /**
56 * Event Viewer's constructor hook
57 *
58 * This constructor is given as a parameter to the menuitem and toolbar button
59 * registration. It creates the list.
60 * @param mw A pointer to the parent window.
61 * @return The widget created.
62 */
63 GtkWidget *
64 h_guicontrolflow(MainWindow *mw, LttvTracesetSelector * s, char * key)
65 {
66 g_info("h_guicontrolflow, %p, %p, %s", mw, s, key);
67 ControlFlowData *control_flow_data = guicontrolflow() ;
68
69 control_flow_data->mw = mw;
70
71 //g_debug("time width2 : %u",time_window->time_width);
72 // Unreg done in the GuiControlFlow_Destructor
73 lttvwindow_register_time_window_notify(mw,
74 update_time_window_hook,
75 control_flow_data);
76 lttvwindow_register_current_time_notify(mw,
77 update_current_time_hook,
78 control_flow_data);
79 return guicontrolflow_get_widget(control_flow_data) ;
80
81 }
82
83 int event_selected_hook(void *hook_data, void *call_data)
84 {
85 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
86 guint *event_number = (guint*) call_data;
87
88 g_debug("DEBUG : event selected by main window : %u", *event_number);
89
90 // control_flow_data->currently_Selected_Event = *event_number;
91 // control_flow_data->Selected_Event = TRUE ;
92
93 // tree_v_set_cursor(control_flow_data);
94
95 }
96
97 /* Hook called before drawing. Gets the initial context at the beginning of the
98 * drawing interval and copy it to the context in event_request.
99 */
100 int draw_before_hook(void *hook_data, void *call_data)
101 {
102 EventRequest *event_request = (EventRequest*)hook_data;
103 //EventsContext Events_Context = (EventsContext*)call_data;
104
105 //event_request->Events_Context = Events_Context;
106
107 return 0;
108 }
109
110 /*
111 * The draw event hook is called by the reading API to have a
112 * particular event drawn on the screen.
113 * @param hook_data ControlFlowData structure of the viewer.
114 * @param call_data Event context.
115 *
116 * This function basically draw lines and icons. Two types of lines are drawn :
117 * one small (3 pixels?) representing the state of the process and the second
118 * type is thicker (10 pixels?) representing on which CPU a process is running
119 * (and this only in running state).
120 *
121 * Extremums of the lines :
122 * x_min : time of the last event context for this process kept in memory.
123 * x_max : time of the current event.
124 * y : middle of the process in the process list. The process is found in the
125 * list, therefore is it's position in pixels.
126 *
127 * The choice of lines'color is defined by the context of the last event for this
128 * process.
129 */
130 int draw_event_hook(void *hook_data, void *call_data)
131 {
132 EventRequest *event_request = (EventRequest*)hook_data;
133 ControlFlowData *control_flow_data = event_request->control_flow_data;
134 MainWindow *mw = control_flow_data->mw;
135
136 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
137
138 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
139 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
140
141 LttEvent *e;
142 e = tfc->e;
143
144 LttTime evtime = ltt_event_time(e);
145 const TimeWindow *time_window =
146 lttvwindow_get_time_window(mw);
147
148 LttTime end_time = ltt_time_add(time_window->start_time,
149 time_window->time_width);
150 //if(time < time_beg || time > time_end) return;
151 if(ltt_time_compare(evtime, time_window->start_time) == -1
152 || ltt_time_compare(evtime, end_time) == 1)
153 return;
154
155 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
156 {
157 g_debug("schedchange!");
158
159 /* Add process to process list (if not present) and get drawing "y" from
160 * process position */
161 guint pid_out, pid_in;
162 LttvProcessState *process_out, *process_in;
163 LttTime birth;
164 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
165
166 ProcessList *process_list =
167 guicontrolflow_get_process_list(event_request->control_flow_data);
168
169
170 LttField *f = ltt_event_field(e);
171 LttField *element;
172 element = ltt_field_member(f,0);
173 pid_out = ltt_event_get_long_unsigned(e,element);
174 element = ltt_field_member(f,1);
175 pid_in = ltt_event_get_long_unsigned(e,element);
176 g_debug("out : %u in : %u", pid_out, pid_in);
177
178
179 /* Find process pid_out in the list... */
180 process_out = lttv_state_find_process(tfs, pid_out);
181 if(process_out == NULL) return 0;
182 g_debug("out : %s",g_quark_to_string(process_out->state->s));
183
184 birth = process_out->creation_time;
185 gchar *name = strdup(g_quark_to_string(process_out->name));
186 HashedProcessData *hashed_process_data_out = NULL;
187
188 if(processlist_get_process_pixels(process_list,
189 pid_out,
190 &birth,
191 tfc->t_context->index,
192 &y_out,
193 &height,
194 &hashed_process_data_out) == 1)
195 {
196 /* Process not present */
197 processlist_add(process_list,
198 pid_out,
199 &birth,
200 tfc->t_context->index,
201 name,
202 &pl_height,
203 &hashed_process_data_out);
204 processlist_get_process_pixels(process_list,
205 pid_out,
206 &birth,
207 tfc->t_context->index,
208 &y_out,
209 &height,
210 &hashed_process_data_out);
211 drawing_insert_square( event_request->control_flow_data->drawing, y_out, height);
212 }
213
214 g_free(name);
215
216 /* Find process pid_in in the list... */
217 process_in = lttv_state_find_process(tfs, pid_in);
218 if(process_in == NULL) return 0;
219 g_debug("in : %s",g_quark_to_string(process_in->state->s));
220
221 birth = process_in->creation_time;
222 name = strdup(g_quark_to_string(process_in->name));
223 HashedProcessData *hashed_process_data_in = NULL;
224
225 if(processlist_get_process_pixels(process_list,
226 pid_in,
227 &birth,
228 tfc->t_context->index,
229 &y_in,
230 &height,
231 &hashed_process_data_in) == 1)
232 {
233 /* Process not present */
234 processlist_add(process_list,
235 pid_in,
236 &birth,
237 tfc->t_context->index,
238 name,
239 &pl_height,
240 &hashed_process_data_in);
241 processlist_get_process_pixels(process_list,
242 pid_in,
243 &birth,
244 tfc->t_context->index,
245 &y_in,
246 &height,
247 &hashed_process_data_in);
248
249 drawing_insert_square( event_request->control_flow_data->drawing, y_in, height);
250 }
251 g_free(name);
252
253
254 /* Find pixels corresponding to time of the event. If the time does
255 * not fit in the window, show a warning, not supposed to happend. */
256 guint x = 0;
257 guint width = control_flow_data->drawing->drawing_area->allocation.width;
258
259 LttTime time = ltt_event_time(e);
260
261 LttTime window_end = ltt_time_add(time_window->time_width,
262 time_window->start_time);
263
264
265 convert_time_to_pixels(
266 time_window->start_time,
267 window_end,
268 time,
269 width,
270 &x);
271 //assert(x <= width);
272
273 /* draw what represents the event for outgoing process. */
274
275 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
276 draw_context_out->current->modify_over->x = x;
277 draw_context_out->current->modify_under->x = x;
278 draw_context_out->current->modify_over->y = y_out;
279 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
280 draw_context_out->drawable = control_flow_data->drawing->pixmap;
281 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
282 GtkWidget *widget = control_flow_data->drawing->drawing_area;
283 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
284 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
285 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
286 //draw_context_out->gc = widget->style->black_gc;
287
288 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
289 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
290
291 /* Draw the line/background of the out process */
292 if(draw_context_out->previous->middle->x == -1)
293 {
294 draw_context_out->previous->over->x = event_request->x_begin;
295 draw_context_out->previous->middle->x = event_request->x_begin;
296 draw_context_out->previous->under->x = event_request->x_begin;
297
298 g_debug("out middle x_beg : %u",event_request->x_begin);
299 }
300
301 draw_context_out->current->middle->x = x;
302 draw_context_out->current->over->x = x;
303 draw_context_out->current->under->x = x;
304 draw_context_out->current->middle->y = y_out + height/2;
305 draw_context_out->current->over->y = y_out;
306 draw_context_out->current->under->y = y_out + height;
307 draw_context_out->previous->middle->y = y_out + height/2;
308 draw_context_out->previous->over->y = y_out;
309 draw_context_out->previous->under->y = y_out + height;
310
311 draw_context_out->drawable = control_flow_data->drawing->pixmap;
312 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
313
314 if(process_out->state->s == LTTV_STATE_RUN)
315 {
316 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
317 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
318
319 PropertiesBG prop_bg;
320 prop_bg.color = g_new(GdkColor,1);
321
322 switch(tfc->index) {
323 case 0:
324 prop_bg.color->red = 0x1515;
325 prop_bg.color->green = 0x1515;
326 prop_bg.color->blue = 0x8c8c;
327 break;
328 case 1:
329 prop_bg.color->red = 0x4e4e;
330 prop_bg.color->green = 0xa9a9;
331 prop_bg.color->blue = 0xa4a4;
332 break;
333 case 2:
334 prop_bg.color->red = 0x7a7a;
335 prop_bg.color->green = 0x4a4a;
336 prop_bg.color->blue = 0x8b8b;
337 break;
338 case 3:
339 prop_bg.color->red = 0x8080;
340 prop_bg.color->green = 0x7777;
341 prop_bg.color->blue = 0x4747;
342 break;
343 default:
344 prop_bg.color->red = 0xe7e7;
345 prop_bg.color->green = 0xe7e7;
346 prop_bg.color->blue = 0xe7e7;
347 }
348
349 g_debug("calling from draw_event");
350 draw_bg((void*)&prop_bg, (void*)draw_context_out);
351 g_free(prop_bg.color);
352 gdk_gc_unref(draw_context_out->gc);
353 }
354
355 draw_context_out->gc = widget->style->black_gc;
356
357 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
358 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
359 PropertiesText prop_text_out;
360 prop_text_out.foreground = &colorfg_out;
361 prop_text_out.background = &colorbg_out;
362 prop_text_out.size = 6;
363 prop_text_out.position = OVER;
364
365 /* color of text : status of the process */
366 if(process_out->state->s == LTTV_STATE_UNNAMED)
367 {
368 prop_text_out.foreground->red = 0xffff;
369 prop_text_out.foreground->green = 0xffff;
370 prop_text_out.foreground->blue = 0xffff;
371 }
372 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
373 {
374 prop_text_out.foreground->red = 0x0fff;
375 prop_text_out.foreground->green = 0xffff;
376 prop_text_out.foreground->blue = 0xfff0;
377 }
378 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
379 {
380 prop_text_out.foreground->red = 0xffff;
381 prop_text_out.foreground->green = 0xffff;
382 prop_text_out.foreground->blue = 0x0000;
383 }
384 else if(process_out->state->s == LTTV_STATE_EXIT)
385 {
386 prop_text_out.foreground->red = 0xffff;
387 prop_text_out.foreground->green = 0x0000;
388 prop_text_out.foreground->blue = 0xffff;
389 }
390 else if(process_out->state->s == LTTV_STATE_WAIT)
391 {
392 prop_text_out.foreground->red = 0xffff;
393 prop_text_out.foreground->green = 0x0000;
394 prop_text_out.foreground->blue = 0x0000;
395 }
396 else if(process_out->state->s == LTTV_STATE_RUN)
397 {
398 prop_text_out.foreground->red = 0x0000;
399 prop_text_out.foreground->green = 0xffff;
400 prop_text_out.foreground->blue = 0x0000;
401 }
402 else
403 {
404 prop_text_out.foreground->red = 0xffff;
405 prop_text_out.foreground->green = 0xffff;
406 prop_text_out.foreground->blue = 0xffff;
407 }
408
409
410 /* Print status of the process : U, WF, WC, E, W, R */
411 if(process_out->state->s == LTTV_STATE_UNNAMED)
412 prop_text_out.text = "U->";
413 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
414 prop_text_out.text = "WF->";
415 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
416 prop_text_out.text = "WC->";
417 else if(process_out->state->s == LTTV_STATE_EXIT)
418 prop_text_out.text = "E->";
419 else if(process_out->state->s == LTTV_STATE_WAIT)
420 prop_text_out.text = "W->";
421 else if(process_out->state->s == LTTV_STATE_RUN)
422 prop_text_out.text = "R->";
423 else
424 prop_text_out.text = "U";
425
426 draw_text((void*)&prop_text_out, (void*)draw_context_out);
427 //gdk_gc_unref(draw_context_out->gc);
428
429 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
430 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
431
432 PropertiesLine prop_line_out;
433 prop_line_out.color = g_new(GdkColor,1);
434 prop_line_out.line_width = 2;
435 prop_line_out.style = GDK_LINE_SOLID;
436 prop_line_out.position = MIDDLE;
437
438 g_debug("out state : %s", g_quark_to_string(process_out->state->s));
439
440 /* color of line : status of the process */
441 if(process_out->state->s == LTTV_STATE_UNNAMED)
442 {
443 prop_line_out.color->red = 0xffff;
444 prop_line_out.color->green = 0xffff;
445 prop_line_out.color->blue = 0xffff;
446 }
447 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
448 {
449 prop_line_out.color->red = 0x0fff;
450 prop_line_out.color->green = 0xffff;
451 prop_line_out.color->blue = 0xfff0;
452 }
453 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
454 {
455 prop_line_out.color->red = 0xffff;
456 prop_line_out.color->green = 0xffff;
457 prop_line_out.color->blue = 0x0000;
458 }
459 else if(process_out->state->s == LTTV_STATE_EXIT)
460 {
461 prop_line_out.color->red = 0xffff;
462 prop_line_out.color->green = 0x0000;
463 prop_line_out.color->blue = 0xffff;
464 }
465 else if(process_out->state->s == LTTV_STATE_WAIT)
466 {
467 prop_line_out.color->red = 0xffff;
468 prop_line_out.color->green = 0x0000;
469 prop_line_out.color->blue = 0x0000;
470 }
471 else if(process_out->state->s == LTTV_STATE_RUN)
472 {
473 prop_line_out.color->red = 0x0000;
474 prop_line_out.color->green = 0xffff;
475 prop_line_out.color->blue = 0x0000;
476 }
477 else
478 {
479 prop_line_out.color->red = 0xffff;
480 prop_line_out.color->green = 0xffff;
481 prop_line_out.color->blue = 0xffff;
482 }
483
484 draw_line((void*)&prop_line_out, (void*)draw_context_out);
485 g_free(prop_line_out.color);
486 gdk_gc_unref(draw_context_out->gc);
487 /* Note : finishing line will have to be added when trace read over. */
488
489 /* Finally, update the drawing context of the pid_in. */
490
491 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
492 draw_context_in->current->modify_over->x = x;
493 draw_context_in->current->modify_under->x = x;
494 draw_context_in->current->modify_over->y = y_in;
495 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
496 draw_context_in->drawable = control_flow_data->drawing->pixmap;
497 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
498 widget = control_flow_data->drawing->drawing_area;
499 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
500 //draw_context_in->gc = widget->style->black_gc;
501 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
502 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
503
504 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
505 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
506
507 /* Draw the line/bg of the in process */
508 if(draw_context_in->previous->middle->x == -1)
509 {
510 draw_context_in->previous->middle->x = event_request->x_begin;
511 draw_context_in->previous->over->x = event_request->x_begin;
512 draw_context_in->previous->under->x = event_request->x_begin;
513 g_debug("in middle x_beg : %u",event_request->x_begin);
514 }
515
516 draw_context_in->current->middle->x = x;
517 draw_context_in->current->over->x = x;
518 draw_context_in->current->under->x = x;
519 draw_context_in->current->middle->y = y_in + height/2;
520 draw_context_in->current->over->y = y_in;
521 draw_context_in->current->under->y = y_in + height;
522 draw_context_in->previous->middle->y = y_in + height/2;
523 draw_context_in->previous->over->y = y_in;
524 draw_context_in->previous->under->y = y_in + height;
525
526 draw_context_in->drawable = control_flow_data->drawing->pixmap;
527 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
528
529
530 if(process_in->state->s == LTTV_STATE_RUN)
531 {
532 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
533 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
534
535 PropertiesBG prop_bg;
536 prop_bg.color = g_new(GdkColor,1);
537
538 switch(tfc->index) {
539 case 0:
540 prop_bg.color->red = 0x1515;
541 prop_bg.color->green = 0x1515;
542 prop_bg.color->blue = 0x8c8c;
543 break;
544 case 1:
545 prop_bg.color->red = 0x4e4e;
546 prop_bg.color->green = 0xa9a9;
547 prop_bg.color->blue = 0xa4a4;
548 break;
549 case 2:
550 prop_bg.color->red = 0x7a7a;
551 prop_bg.color->green = 0x4a4a;
552 prop_bg.color->blue = 0x8b8b;
553 break;
554 case 3:
555 prop_bg.color->red = 0x8080;
556 prop_bg.color->green = 0x7777;
557 prop_bg.color->blue = 0x4747;
558 break;
559 default:
560 prop_bg.color->red = 0xe7e7;
561 prop_bg.color->green = 0xe7e7;
562 prop_bg.color->blue = 0xe7e7;
563 }
564
565
566 draw_bg((void*)&prop_bg, (void*)draw_context_in);
567 g_free(prop_bg.color);
568 gdk_gc_unref(draw_context_in->gc);
569 }
570
571 draw_context_in->gc = widget->style->black_gc;
572
573 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
574 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
575 PropertiesText prop_text_in;
576 prop_text_in.foreground = &colorfg_in;
577 prop_text_in.background = &colorbg_in;
578 prop_text_in.size = 6;
579 prop_text_in.position = OVER;
580
581 g_debug("in state : %s", g_quark_to_string(process_in->state->s));
582 /* foreground of text : status of the process */
583 if(process_in->state->s == LTTV_STATE_UNNAMED)
584 {
585 prop_text_in.foreground->red = 0xffff;
586 prop_text_in.foreground->green = 0xffff;
587 prop_text_in.foreground->blue = 0xffff;
588 }
589 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
590 {
591 prop_text_in.foreground->red = 0x0fff;
592 prop_text_in.foreground->green = 0xffff;
593 prop_text_in.foreground->blue = 0xfff0;
594 }
595 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
596 {
597 prop_text_in.foreground->red = 0xffff;
598 prop_text_in.foreground->green = 0xffff;
599 prop_text_in.foreground->blue = 0x0000;
600 }
601 else if(process_in->state->s == LTTV_STATE_EXIT)
602 {
603 prop_text_in.foreground->red = 0xffff;
604 prop_text_in.foreground->green = 0x0000;
605 prop_text_in.foreground->blue = 0xffff;
606 }
607 else if(process_in->state->s == LTTV_STATE_WAIT)
608 {
609 prop_text_in.foreground->red = 0xffff;
610 prop_text_in.foreground->green = 0x0000;
611 prop_text_in.foreground->blue = 0x0000;
612 }
613 else if(process_in->state->s == LTTV_STATE_RUN)
614 {
615 prop_text_in.foreground->red = 0x0000;
616 prop_text_in.foreground->green = 0xffff;
617 prop_text_in.foreground->blue = 0x0000;
618 }
619 else
620 {
621 prop_text_in.foreground->red = 0xffff;
622 prop_text_in.foreground->green = 0xffff;
623 prop_text_in.foreground->blue = 0xffff;
624 }
625
626
627
628 /* Print status of the process : U, WF, WC, E, W, R */
629 if(process_in->state->s == LTTV_STATE_UNNAMED)
630 prop_text_in.text = "U->";
631 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
632 prop_text_in.text = "WF->";
633 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
634 prop_text_in.text = "WC->";
635 else if(process_in->state->s == LTTV_STATE_EXIT)
636 prop_text_in.text = "E->";
637 else if(process_in->state->s == LTTV_STATE_WAIT)
638 prop_text_in.text = "W->";
639 else if(process_in->state->s == LTTV_STATE_RUN)
640 prop_text_in.text = "R->";
641 else
642 prop_text_in.text = "U";
643
644 draw_text((void*)&prop_text_in, (void*)draw_context_in);
645 //gdk_gc_unref(draw_context_in->gc);
646
647 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
648 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
649
650 PropertiesLine prop_line_in;
651 prop_line_in.color = g_new(GdkColor,1);
652 prop_line_in.line_width = 2;
653 prop_line_in.style = GDK_LINE_SOLID;
654 prop_line_in.position = MIDDLE;
655
656 /* color of line : status of the process */
657 if(process_in->state->s == LTTV_STATE_UNNAMED)
658 {
659 prop_line_in.color->red = 0xffff;
660 prop_line_in.color->green = 0xffff;
661 prop_line_in.color->blue = 0xffff;
662 }
663 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
664 {
665 prop_line_in.color->red = 0x0fff;
666 prop_line_in.color->green = 0xffff;
667 prop_line_in.color->blue = 0xfff0;
668 }
669 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
670 {
671 prop_line_in.color->red = 0xffff;
672 prop_line_in.color->green = 0xffff;
673 prop_line_in.color->blue = 0x0000;
674 }
675 else if(process_in->state->s == LTTV_STATE_EXIT)
676 {
677 prop_line_in.color->red = 0xffff;
678 prop_line_in.color->green = 0x0000;
679 prop_line_in.color->blue = 0xffff;
680 }
681 else if(process_in->state->s == LTTV_STATE_WAIT)
682 {
683 prop_line_in.color->red = 0xffff;
684 prop_line_in.color->green = 0x0000;
685 prop_line_in.color->blue = 0x0000;
686 }
687 else if(process_in->state->s == LTTV_STATE_RUN)
688 {
689 prop_line_in.color->red = 0x0000;
690 prop_line_in.color->green = 0xffff;
691 prop_line_in.color->blue = 0x0000;
692 }
693 else
694 {
695 prop_line_in.color->red = 0xffff;
696 prop_line_in.color->green = 0xffff;
697 prop_line_in.color->blue = 0xffff;
698 }
699
700 draw_line((void*)&prop_line_in, (void*)draw_context_in);
701 g_free(prop_line_in.color);
702 gdk_gc_unref(draw_context_in->gc);
703 }
704
705 return 0;
706
707 /* Temp dump */
708 #ifdef DONTSHOW
709 GString *string = g_string_new("");;
710 gboolean field_names = TRUE, state = TRUE;
711
712 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
713 g_string_append_printf(string,"\n");
714
715 if(state) {
716 g_string_append_printf(string, " %s",
717 g_quark_to_string(tfs->process->state->s));
718 }
719
720 g_info("%s",string->str);
721
722 g_string_free(string, TRUE);
723
724 /* End of text dump */
725 #endif //DONTSHOW
726
727 }
728
729
730 int draw_after_hook(void *hook_data, void *call_data)
731 {
732 EventRequest *event_request = (EventRequest*)hook_data;
733 ControlFlowData *control_flow_data = event_request->control_flow_data;
734
735 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
736
737 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
738 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
739
740
741 LttEvent *e;
742 e = tfc->e;
743
744 LttTime evtime = ltt_event_time(e);
745 const TimeWindow *time_window =
746 lttvwindow_get_time_window(control_flow_data->mw);
747
748 LttTime end_time = ltt_time_add(time_window->start_time,
749 time_window->time_width);
750 //if(time < time_beg || time > time_end) return;
751 if(ltt_time_compare(evtime, time_window->start_time) == -1
752 || ltt_time_compare(evtime, end_time) == 1)
753 return;
754
755
756 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
757 {
758 g_debug("schedchange!");
759
760 /* Add process to process list (if not present) and get drawing "y" from
761 * process position */
762 guint pid_out, pid_in;
763 LttvProcessState *process_out, *process_in;
764 LttTime birth;
765 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
766
767 ProcessList *process_list =
768 guicontrolflow_get_process_list(event_request->control_flow_data);
769
770
771 LttField *f = ltt_event_field(e);
772 LttField *element;
773 element = ltt_field_member(f,0);
774 pid_out = ltt_event_get_long_unsigned(e,element);
775 element = ltt_field_member(f,1);
776 pid_in = ltt_event_get_long_unsigned(e,element);
777 //g_debug("out : %u in : %u", pid_out, pid_in);
778
779
780 /* Find process pid_out in the list... */
781 process_out = lttv_state_find_process(tfs, pid_out);
782 if(process_out == NULL) return 0;
783 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
784
785 birth = process_out->creation_time;
786 gchar *name = strdup(g_quark_to_string(process_out->name));
787 HashedProcessData *hashed_process_data_out = NULL;
788
789 if(processlist_get_process_pixels(process_list,
790 pid_out,
791 &birth,
792 tfc->t_context->index,
793 &y_out,
794 &height,
795 &hashed_process_data_out) == 1)
796 {
797 /* Process not present */
798 processlist_add(process_list,
799 pid_out,
800 &birth,
801 tfc->t_context->index,
802 name,
803 &pl_height,
804 &hashed_process_data_out);
805 processlist_get_process_pixels(process_list,
806 pid_out,
807 &birth,
808 tfc->t_context->index,
809 &y_out,
810 &height,
811 &hashed_process_data_out);
812 drawing_insert_square( event_request->control_flow_data->drawing, y_out, height);
813 }
814
815 g_free(name);
816
817 /* Find process pid_in in the list... */
818 process_in = lttv_state_find_process(tfs, pid_in);
819 if(process_in == NULL) return 0;
820 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
821
822 birth = process_in->creation_time;
823 name = strdup(g_quark_to_string(process_in->name));
824 HashedProcessData *hashed_process_data_in = NULL;
825
826 if(processlist_get_process_pixels(process_list,
827 pid_in,
828 &birth,
829 tfc->t_context->index,
830 &y_in,
831 &height,
832 &hashed_process_data_in) == 1)
833 {
834 /* Process not present */
835 processlist_add(process_list,
836 pid_in,
837 &birth,
838 tfc->t_context->index,
839 name,
840 &pl_height,
841 &hashed_process_data_in);
842 processlist_get_process_pixels(process_list,
843 pid_in,
844 &birth,
845 tfc->t_context->index,
846 &y_in,
847 &height,
848 &hashed_process_data_in);
849
850 drawing_insert_square( event_request->control_flow_data->drawing, y_in, height);
851 }
852 g_free(name);
853
854
855 /* Find pixels corresponding to time of the event. If the time does
856 * not fit in the window, show a warning, not supposed to happend. */
857 //guint x = 0;
858 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
859
860 //LttTime time = ltt_event_time(e);
861
862 //LttTime window_end = ltt_time_add(time_window->time_width,
863 // time_window->start_time);
864
865
866 //convert_time_to_pixels(
867 // time_window->start_time,
868 // window_end,
869 // time,
870 // width,
871 // &x);
872
873 //assert(x <= width);
874
875 /* draw what represents the event for outgoing process. */
876
877 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
878 //draw_context_out->current->modify_over->x = x;
879 draw_context_out->current->modify_over->y = y_out;
880 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
881 draw_context_out->drawable = control_flow_data->drawing->pixmap;
882 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
883 GtkWidget *widget = control_flow_data->drawing->drawing_area;
884 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
885
886 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
887 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
888
889 /*if(process_out->state->s == LTTV_STATE_RUN)
890 {
891 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
892 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
893 PropertiesBG prop_bg;
894 prop_bg.color = g_new(GdkColor,1);
895
896 prop_bg.color->red = 0xffff;
897 prop_bg.color->green = 0xffff;
898 prop_bg.color->blue = 0xffff;
899
900 draw_bg((void*)&prop_bg, (void*)draw_context_out);
901 g_free(prop_bg.color);
902 gdk_gc_unref(draw_context_out->gc);
903 }*/
904
905 draw_context_out->gc = widget->style->black_gc;
906
907 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
908 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
909 PropertiesText prop_text_out;
910 prop_text_out.foreground = &colorfg_out;
911 prop_text_out.background = &colorbg_out;
912 prop_text_out.size = 6;
913 prop_text_out.position = OVER;
914
915 /* color of text : status of the process */
916 if(process_out->state->s == LTTV_STATE_UNNAMED)
917 {
918 prop_text_out.foreground->red = 0xffff;
919 prop_text_out.foreground->green = 0xffff;
920 prop_text_out.foreground->blue = 0xffff;
921 }
922 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
923 {
924 prop_text_out.foreground->red = 0x0fff;
925 prop_text_out.foreground->green = 0xffff;
926 prop_text_out.foreground->blue = 0xfff0;
927 }
928 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
929 {
930 prop_text_out.foreground->red = 0xffff;
931 prop_text_out.foreground->green = 0xffff;
932 prop_text_out.foreground->blue = 0x0000;
933 }
934 else if(process_out->state->s == LTTV_STATE_EXIT)
935 {
936 prop_text_out.foreground->red = 0xffff;
937 prop_text_out.foreground->green = 0x0000;
938 prop_text_out.foreground->blue = 0xffff;
939 }
940 else if(process_out->state->s == LTTV_STATE_WAIT)
941 {
942 prop_text_out.foreground->red = 0xffff;
943 prop_text_out.foreground->green = 0x0000;
944 prop_text_out.foreground->blue = 0x0000;
945 }
946 else if(process_out->state->s == LTTV_STATE_RUN)
947 {
948 prop_text_out.foreground->red = 0x0000;
949 prop_text_out.foreground->green = 0xffff;
950 prop_text_out.foreground->blue = 0x0000;
951 }
952 else
953 {
954 prop_text_out.foreground->red = 0xffff;
955 prop_text_out.foreground->green = 0xffff;
956 prop_text_out.foreground->blue = 0xffff;
957 }
958
959 /* Print status of the process : U, WF, WC, E, W, R */
960 if(process_out->state->s == LTTV_STATE_UNNAMED)
961 prop_text_out.text = "U";
962 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
963 prop_text_out.text = "WF";
964 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
965 prop_text_out.text = "WC";
966 else if(process_out->state->s == LTTV_STATE_EXIT)
967 prop_text_out.text = "E";
968 else if(process_out->state->s == LTTV_STATE_WAIT)
969 prop_text_out.text = "W";
970 else if(process_out->state->s == LTTV_STATE_RUN)
971 prop_text_out.text = "R";
972 else
973 prop_text_out.text = "U";
974
975 draw_text((void*)&prop_text_out, (void*)draw_context_out);
976
977 //gdk_gc_unref(draw_context_out->gc);
978
979 draw_context_out->current->middle->y = y_out+height/2;
980 draw_context_out->current->over->y = y_out;
981 draw_context_out->current->under->y = y_out+height;
982 draw_context_out->current->status = process_out->state->s;
983
984 /* for pid_out : remove previous, Prev = current, new current (default) */
985 g_free(draw_context_out->previous->modify_under);
986 g_free(draw_context_out->previous->modify_middle);
987 g_free(draw_context_out->previous->modify_over);
988 g_free(draw_context_out->previous->under);
989 g_free(draw_context_out->previous->middle);
990 g_free(draw_context_out->previous->over);
991 g_free(draw_context_out->previous);
992
993 draw_context_out->previous = draw_context_out->current;
994
995 draw_context_out->current = g_new(DrawInfo,1);
996 draw_context_out->current->over = g_new(ItemInfo,1);
997 draw_context_out->current->over->x = -1;
998 draw_context_out->current->over->y = -1;
999 draw_context_out->current->middle = g_new(ItemInfo,1);
1000 draw_context_out->current->middle->x = -1;
1001 draw_context_out->current->middle->y = -1;
1002 draw_context_out->current->under = g_new(ItemInfo,1);
1003 draw_context_out->current->under->x = -1;
1004 draw_context_out->current->under->y = -1;
1005 draw_context_out->current->modify_over = g_new(ItemInfo,1);
1006 draw_context_out->current->modify_over->x = -1;
1007 draw_context_out->current->modify_over->y = -1;
1008 draw_context_out->current->modify_middle = g_new(ItemInfo,1);
1009 draw_context_out->current->modify_middle->x = -1;
1010 draw_context_out->current->modify_middle->y = -1;
1011 draw_context_out->current->modify_under = g_new(ItemInfo,1);
1012 draw_context_out->current->modify_under->x = -1;
1013 draw_context_out->current->modify_under->y = -1;
1014 draw_context_out->current->status = LTTV_STATE_UNNAMED;
1015
1016 /* Finally, update the drawing context of the pid_in. */
1017
1018 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
1019 //draw_context_in->current->modify_over->x = x;
1020 draw_context_in->current->modify_over->y = y_in;
1021 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
1022 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1023 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1024 widget = control_flow_data->drawing->drawing_area;
1025 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1026
1027 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1028 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1029
1030 /*if(process_in->state->s == LTTV_STATE_RUN)
1031 {
1032 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1033 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1034 PropertiesBG prop_bg;
1035 prop_bg.color = g_new(GdkColor,1);
1036
1037 prop_bg.color->red = 0xffff;
1038 prop_bg.color->green = 0xffff;
1039 prop_bg.color->blue = 0xffff;
1040
1041 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1042 g_free(prop_bg.color);
1043 gdk_gc_unref(draw_context_in->gc);
1044 }*/
1045
1046 draw_context_in->gc = widget->style->black_gc;
1047
1048 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
1049 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
1050 PropertiesText prop_text_in;
1051 prop_text_in.foreground = &colorfg_in;
1052 prop_text_in.background = &colorbg_in;
1053 prop_text_in.size = 6;
1054 prop_text_in.position = OVER;
1055
1056 /* foreground of text : status of the process */
1057 if(process_in->state->s == LTTV_STATE_UNNAMED)
1058 {
1059 prop_text_in.foreground->red = 0xffff;
1060 prop_text_in.foreground->green = 0xffff;
1061 prop_text_in.foreground->blue = 0xffff;
1062 }
1063 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1064 {
1065 prop_text_in.foreground->red = 0x0fff;
1066 prop_text_in.foreground->green = 0xffff;
1067 prop_text_in.foreground->blue = 0xfff0;
1068 }
1069 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1070 {
1071 prop_text_in.foreground->red = 0xffff;
1072 prop_text_in.foreground->green = 0xffff;
1073 prop_text_in.foreground->blue = 0x0000;
1074 }
1075 else if(process_in->state->s == LTTV_STATE_EXIT)
1076 {
1077 prop_text_in.foreground->red = 0xffff;
1078 prop_text_in.foreground->green = 0x0000;
1079 prop_text_in.foreground->blue = 0xffff;
1080 }
1081 else if(process_in->state->s == LTTV_STATE_WAIT)
1082 {
1083 prop_text_in.foreground->red = 0xffff;
1084 prop_text_in.foreground->green = 0x0000;
1085 prop_text_in.foreground->blue = 0x0000;
1086 }
1087 else if(process_in->state->s == LTTV_STATE_RUN)
1088 {
1089 prop_text_in.foreground->red = 0x0000;
1090 prop_text_in.foreground->green = 0xffff;
1091 prop_text_in.foreground->blue = 0x0000;
1092 }
1093 else
1094 {
1095 prop_text_in.foreground->red = 0xffff;
1096 prop_text_in.foreground->green = 0xffff;
1097 prop_text_in.foreground->blue = 0xffff;
1098 }
1099
1100
1101 /* Print status of the process : U, WF, WC, E, W, R */
1102 if(process_in->state->s == LTTV_STATE_UNNAMED)
1103 prop_text_in.text = "U";
1104 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1105 prop_text_in.text = "WF";
1106 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1107 prop_text_in.text = "WC";
1108 else if(process_in->state->s == LTTV_STATE_EXIT)
1109 prop_text_in.text = "E";
1110 else if(process_in->state->s == LTTV_STATE_WAIT)
1111 prop_text_in.text = "W";
1112 else if(process_in->state->s == LTTV_STATE_RUN)
1113 prop_text_in.text = "R";
1114 else
1115 prop_text_in.text = "U";
1116
1117 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1118
1119
1120 if(process_in->state->s == LTTV_STATE_RUN)
1121 {
1122 gchar tmp[255];
1123 prop_text_in.foreground = &colorfg_in;
1124 prop_text_in.background = &colorbg_in;
1125 prop_text_in.foreground->red = 0xffff;
1126 prop_text_in.foreground->green = 0xffff;
1127 prop_text_in.foreground->blue = 0xffff;
1128 prop_text_in.size = 6;
1129 prop_text_in.position = UNDER;
1130
1131 prop_text_in.text = g_new(gchar, 260);
1132 strcpy(prop_text_in.text, "CPU ");
1133 snprintf(tmp, 255, "%u", tfc->index);
1134 strcat(prop_text_in.text, tmp);
1135
1136 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1137 g_free(prop_text_in.text);
1138 }
1139
1140
1141 draw_context_in->current->middle->y = y_in+height/2;
1142 draw_context_in->current->over->y = y_in;
1143 draw_context_in->current->under->y = y_in+height;
1144 draw_context_in->current->status = process_in->state->s;
1145
1146 /* for pid_in : remove previous, Prev = current, new current (default) */
1147 g_free(draw_context_in->previous->modify_under);
1148 g_free(draw_context_in->previous->modify_middle);
1149 g_free(draw_context_in->previous->modify_over);
1150 g_free(draw_context_in->previous->under);
1151 g_free(draw_context_in->previous->middle);
1152 g_free(draw_context_in->previous->over);
1153 g_free(draw_context_in->previous);
1154
1155 draw_context_in->previous = draw_context_in->current;
1156
1157 draw_context_in->current = g_new(DrawInfo,1);
1158 draw_context_in->current->over = g_new(ItemInfo,1);
1159 draw_context_in->current->over->x = -1;
1160 draw_context_in->current->over->y = -1;
1161 draw_context_in->current->middle = g_new(ItemInfo,1);
1162 draw_context_in->current->middle->x = -1;
1163 draw_context_in->current->middle->y = -1;
1164 draw_context_in->current->under = g_new(ItemInfo,1);
1165 draw_context_in->current->under->x = -1;
1166 draw_context_in->current->under->y = -1;
1167 draw_context_in->current->modify_over = g_new(ItemInfo,1);
1168 draw_context_in->current->modify_over->x = -1;
1169 draw_context_in->current->modify_over->y = -1;
1170 draw_context_in->current->modify_middle = g_new(ItemInfo,1);
1171 draw_context_in->current->modify_middle->x = -1;
1172 draw_context_in->current->modify_middle->y = -1;
1173 draw_context_in->current->modify_under = g_new(ItemInfo,1);
1174 draw_context_in->current->modify_under->x = -1;
1175 draw_context_in->current->modify_under->y = -1;
1176 draw_context_in->current->status = LTTV_STATE_UNNAMED;
1177
1178 }
1179
1180 return 0;
1181 }
1182
1183
1184
1185
1186 gint update_time_window_hook(void *hook_data, void *call_data)
1187 {
1188 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1189 Drawing_t *drawing = control_flow_data->drawing;
1190
1191 const TimeWindowNotifyData *time_window_nofify_data =
1192 ((const TimeWindowNotifyData *)call_data);
1193
1194 TimeWindow *old_time_window =
1195 time_window_nofify_data->old_time_window;
1196 TimeWindow *new_time_window =
1197 time_window_nofify_data->new_time_window;
1198
1199 /* Update the ruler */
1200 drawing_update_ruler(control_flow_data->drawing,
1201 new_time_window);
1202
1203
1204 /* Two cases : zoom in/out or scrolling */
1205
1206 /* In order to make sure we can reuse the old drawing, the scale must
1207 * be the same and the new time interval being partly located in the
1208 * currently shown time interval. (reuse is only for scrolling)
1209 */
1210
1211 g_info("Old time window HOOK : %u, %u to %u, %u",
1212 old_time_window->start_time.tv_sec,
1213 old_time_window->start_time.tv_nsec,
1214 old_time_window->time_width.tv_sec,
1215 old_time_window->time_width.tv_nsec);
1216
1217 g_info("New time window HOOK : %u, %u to %u, %u",
1218 new_time_window->start_time.tv_sec,
1219 new_time_window->start_time.tv_nsec,
1220 new_time_window->time_width.tv_sec,
1221 new_time_window->time_width.tv_nsec);
1222
1223 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
1224 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
1225 {
1226 /* Same scale (scrolling) */
1227 g_info("scrolling");
1228 LttTime *ns = &new_time_window->start_time;
1229 LttTime *os = &old_time_window->start_time;
1230 LttTime old_end = ltt_time_add(old_time_window->start_time,
1231 old_time_window->time_width);
1232 LttTime new_end = ltt_time_add(new_time_window->start_time,
1233 new_time_window->time_width);
1234 //if(ns<os+w<ns+w)
1235 //if(ns<os+w && os+w<ns+w)
1236 //if(ns<old_end && os<ns)
1237 if(ltt_time_compare(*ns, old_end) == -1
1238 && ltt_time_compare(*os, *ns) == -1)
1239 {
1240 g_info("scrolling near right");
1241 /* Scroll right, keep right part of the screen */
1242 guint x = 0;
1243 guint width = control_flow_data->drawing->drawing_area->allocation.width;
1244 convert_time_to_pixels(
1245 *os,
1246 old_end,
1247 *ns,
1248 width,
1249 &x);
1250
1251 /* Copy old data to new location */
1252 gdk_draw_drawable (control_flow_data->drawing->pixmap,
1253 control_flow_data->drawing->drawing_area->style->black_gc,
1254 control_flow_data->drawing->pixmap,
1255 x, 0,
1256 0, 0,
1257 -1, -1);
1258
1259 /* Clear the data request background, but not SAFETY */
1260 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1261 control_flow_data->drawing->drawing_area->style->black_gc,
1262 TRUE,
1263 x+SAFETY, 0,
1264 control_flow_data->drawing->width - x, // do not overlap
1265 control_flow_data->drawing->height+SAFETY);
1266
1267 gtk_widget_queue_draw_area (drawing->drawing_area,
1268 0,0,
1269 control_flow_data->drawing->width - x,
1270 control_flow_data->drawing->height);
1271
1272 /* Get new data for the rest. */
1273 drawing_data_request(control_flow_data->drawing,
1274 &control_flow_data->drawing->pixmap,
1275 x, 0,
1276 control_flow_data->drawing->width - x,
1277 control_flow_data->drawing->height);
1278
1279 } else {
1280 //if(ns<os<ns+w)
1281 //if(ns<os && os<ns+w)
1282 //if(ns<os && os<new_end)
1283 if(ltt_time_compare(*ns,*os) == -1
1284 && ltt_time_compare(*os,new_end) == -1)
1285 {
1286 g_info("scrolling near left");
1287 /* Scroll left, keep left part of the screen */
1288 guint x = 0;
1289 guint width = control_flow_data->drawing->drawing_area->allocation.width;
1290 convert_time_to_pixels(
1291 *ns,
1292 new_end,
1293 *os,
1294 width,
1295 &x);
1296
1297 /* Copy old data to new location */
1298 gdk_draw_drawable (control_flow_data->drawing->pixmap,
1299 control_flow_data->drawing->drawing_area->style->black_gc,
1300 control_flow_data->drawing->pixmap,
1301 0, 0,
1302 x, 0,
1303 -1, -1);
1304
1305 *old_time_window = *new_time_window;
1306
1307 /* Clean the data request background */
1308 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1309 control_flow_data->drawing->drawing_area->style->black_gc,
1310 TRUE,
1311 0, 0,
1312 x, // do not overlap
1313 control_flow_data->drawing->height+SAFETY);
1314
1315 gtk_widget_queue_draw_area (drawing->drawing_area,
1316 x,0,
1317 control_flow_data->drawing->width - x,
1318 control_flow_data->drawing->height);
1319
1320 /* Get new data for the rest. */
1321 drawing_data_request(control_flow_data->drawing,
1322 &control_flow_data->drawing->pixmap,
1323 0, 0,
1324 x,
1325 control_flow_data->drawing->height);
1326
1327 } else {
1328 if(ltt_time_compare(*ns,*os) == 0)
1329 {
1330 g_info("not scrolling");
1331 } else {
1332 g_info("scrolling far");
1333 /* Cannot reuse any part of the screen : far jump */
1334
1335
1336 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1337 control_flow_data->drawing->drawing_area->style->black_gc,
1338 TRUE,
1339 0, 0,
1340 control_flow_data->drawing->width+SAFETY, // do not overlap
1341 control_flow_data->drawing->height+SAFETY);
1342
1343 gtk_widget_queue_draw_area (drawing->drawing_area,
1344 0,0,
1345 control_flow_data->drawing->width,
1346 control_flow_data->drawing->height);
1347
1348 drawing_data_request(control_flow_data->drawing,
1349 &control_flow_data->drawing->pixmap,
1350 0, 0,
1351 control_flow_data->drawing->width,
1352 control_flow_data->drawing->height);
1353
1354 }
1355 }
1356 }
1357 } else {
1358 /* Different scale (zoom) */
1359 g_info("zoom");
1360
1361 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1362 control_flow_data->drawing->drawing_area->style->black_gc,
1363 TRUE,
1364 0, 0,
1365 control_flow_data->drawing->width+SAFETY, // do not overlap
1366 control_flow_data->drawing->height+SAFETY);
1367
1368 gtk_widget_queue_draw_area (drawing->drawing_area,
1369 0,0,
1370 control_flow_data->drawing->width,
1371 control_flow_data->drawing->height);
1372
1373 drawing_data_request(control_flow_data->drawing,
1374 &control_flow_data->drawing->pixmap,
1375 0, 0,
1376 control_flow_data->drawing->width,
1377 control_flow_data->drawing->height);
1378
1379 }
1380
1381
1382
1383 return 0;
1384 }
1385
1386 gint after_process_traceset_hook(void *hook_data, void *call_data)
1387 {
1388 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1389 TimeRequest *time_request = (TimeRequest *)call_data;
1390
1391 drawing_data_request_end(control_flow_data->drawing,
1392 time_request->time_window);
1393 return 0;
1394 }
1395
1396
1397
1398 gint update_current_time_hook(void *hook_data, void *call_data)
1399 {
1400 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
1401 Drawing_t *drawing = control_flow_data->drawing;
1402
1403 LttTime current_time = *((LttTime*)call_data);
1404
1405 const TimeWindow *time_window =
1406 lttvwindow_get_time_window(control_flow_data->mw);
1407
1408 LttTime time_begin = time_window->start_time;
1409 LttTime width = time_window->time_width;
1410 LttTime half_width = ltt_time_div(width,2.0);
1411 LttTime time_end = ltt_time_add(time_begin, width);
1412
1413 LttvTracesetContext * tsc =
1414 lttvwindow_get_traceset_context(control_flow_data->mw);
1415
1416 LttTime trace_start = tsc->Time_Span->startTime;
1417 LttTime trace_end = tsc->Time_Span->endTime;
1418
1419 g_info("New current time HOOK : %u, %u", current_time.tv_sec,
1420 current_time.tv_nsec);
1421
1422
1423
1424 /* If current time is inside time interval, just move the highlight
1425 * bar */
1426
1427 /* Else, we have to change the time interval. We have to tell it
1428 * to the main window. */
1429 /* The time interval change will take care of placing the current
1430 * time at the center of the visible area, or nearest possible if we are
1431 * at one end of the trace. */
1432
1433
1434 if(ltt_time_compare(current_time, time_begin) == -1)
1435 {
1436 TimeWindow new_time_window;
1437
1438 if(ltt_time_compare(current_time,
1439 ltt_time_add(trace_start,half_width)) == -1)
1440 time_begin = trace_start;
1441 else
1442 time_begin = ltt_time_sub(current_time,half_width);
1443
1444 new_time_window.start_time = time_begin;
1445 new_time_window.time_width = width;
1446
1447 lttvwindow_report_time_window(control_flow_data->mw, &new_time_window);
1448 }
1449 else if(ltt_time_compare(current_time, time_end) == 1)
1450 {
1451 TimeWindow new_time_window;
1452
1453 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) == 1)
1454 time_begin = ltt_time_sub(trace_end,width);
1455 else
1456 time_begin = ltt_time_sub(current_time,half_width);
1457
1458 new_time_window.start_time = time_begin;
1459 new_time_window.time_width = width;
1460
1461 lttvwindow_report_time_window(control_flow_data->mw, &new_time_window);
1462
1463 }
1464 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1465 gtk_widget_queue_draw_area(drawing->drawing_area,
1466 0,0,
1467 drawing->width,
1468 drawing->height);
1469
1470 return 0;
1471 }
1472
1473 typedef struct _ClosureData {
1474 EventRequest *event_request;
1475 LttvTracesetState *tss;
1476 } ClosureData;
1477
1478
1479 void draw_closure(gpointer key, gpointer value, gpointer user_data)
1480 {
1481 ProcessInfo *process_info = (ProcessInfo*)key;
1482 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
1483 ClosureData *closure_data = (ClosureData*)user_data;
1484
1485 ControlFlowData *control_flow_data =
1486 closure_data->event_request->control_flow_data;
1487
1488 GtkWidget *widget = control_flow_data->drawing->drawing_area;
1489
1490 /* Get y position of process */
1491 gint y=0, height=0;
1492
1493 processlist_get_pixels_from_data( control_flow_data->process_list,
1494 process_info,
1495 hashed_process_data,
1496 &y,
1497 &height);
1498 /* Get last state of process */
1499 LttvTraceContext *tc =
1500 ((LttvTracesetContext*)closure_data->tss)->traces[process_info->trace_num];
1501 //LttvTracefileContext *tfc = (LttvTracefileContext *)closure_data->ts;
1502
1503 LttvTraceState *ts = (LttvTraceState*)tc;
1504 LttvProcessState *process;
1505
1506 /* We do not provide a cpu_name argument assuming that this is not the
1507 idle job (pid 0) and thus its pid is unique across all cpus */
1508 process = lttv_state_find_process_from_trace(ts, 0, process_info->pid);
1509
1510 /* Draw the closing line */
1511 DrawContext *draw_context = hashed_process_data->draw_context;
1512 if(draw_context->previous->middle->x == -1)
1513 {
1514 draw_context->previous->middle->x = closure_data->event_request->x_begin;
1515 draw_context->previous->over->x = closure_data->event_request->x_begin;
1516 draw_context->previous->under->x = closure_data->event_request->x_begin;
1517 g_debug("out middle x_beg : %u",closure_data->event_request->x_begin);
1518 }
1519
1520 draw_context->current->middle->x = closure_data->event_request->x_end;
1521 draw_context->current->over->x = closure_data->event_request->x_end;
1522 draw_context->current->under->x = closure_data->event_request->x_end;
1523 draw_context->current->middle->y = y + height/2;
1524 draw_context->current->over->y = y ;
1525 draw_context->current->under->y = y + height;
1526 draw_context->previous->middle->y = y + height/2;
1527 draw_context->previous->over->y = y ;
1528 draw_context->previous->under->y = y + height;
1529 draw_context->drawable = control_flow_data->drawing->pixmap;
1530 draw_context->pango_layout = control_flow_data->drawing->pango_layout;
1531 //draw_context->gc = widget->style->black_gc;
1532 draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1533 gdk_gc_copy(draw_context->gc, widget->style->black_gc);
1534
1535 if(process != NULL && process->state->s == LTTV_STATE_RUN)
1536 {
1537 PropertiesBG prop_bg;
1538 prop_bg.color = g_new(GdkColor,1);
1539
1540 /*switch(tfc->index) {
1541 case 0:
1542 prop_bg.color->red = 0x1515;
1543 prop_bg.color->green = 0x1515;
1544 prop_bg.color->blue = 0x8c8c;
1545 break;
1546 case 1:
1547 prop_bg.color->red = 0x4e4e;
1548 prop_bg.color->green = 0xa9a9;
1549 prop_bg.color->blue = 0xa4a4;
1550 break;
1551 case 2:
1552 prop_bg.color->red = 0x7a7a;
1553 prop_bg.color->green = 0x4a4a;
1554 prop_bg.color->blue = 0x8b8b;
1555 break;
1556 case 3:
1557 prop_bg.color->red = 0x8080;
1558 prop_bg.color->green = 0x7777;
1559 prop_bg.color->blue = 0x4747;
1560 break;
1561 default:
1562 prop_bg.color->red = 0xe7e7;
1563 prop_bg.color->green = 0xe7e7;
1564 prop_bg.color->blue = 0xe7e7;
1565 }
1566 */
1567
1568 g_debug("calling from closure");
1569 //FIXME : I need the cpu number in process's state to draw this.
1570 //draw_bg((void*)&prop_bg, (void*)draw_context);
1571 g_free(prop_bg.color);
1572 }
1573
1574
1575 PropertiesLine prop_line;
1576 prop_line.color = g_new(GdkColor,1);
1577 prop_line.line_width = 2;
1578 prop_line.style = GDK_LINE_SOLID;
1579 prop_line.position = MIDDLE;
1580
1581 /* color of line : status of the process */
1582 if(process != NULL)
1583 {
1584 if(process->state->s == LTTV_STATE_UNNAMED)
1585 {
1586 prop_line.color->red = 0xffff;
1587 prop_line.color->green = 0xffff;
1588 prop_line.color->blue = 0xffff;
1589 }
1590 else if(process->state->s == LTTV_STATE_WAIT_FORK)
1591 {
1592 prop_line.color->red = 0x0fff;
1593 prop_line.color->green = 0xffff;
1594 prop_line.color->blue = 0xfff0;
1595 }
1596 else if(process->state->s == LTTV_STATE_WAIT_CPU)
1597 {
1598 prop_line.color->red = 0xffff;
1599 prop_line.color->green = 0xffff;
1600 prop_line.color->blue = 0x0000;
1601 }
1602 else if(process->state->s == LTTV_STATE_EXIT)
1603 {
1604 prop_line.color->red = 0xffff;
1605 prop_line.color->green = 0x0000;
1606 prop_line.color->blue = 0xffff;
1607 }
1608 else if(process->state->s == LTTV_STATE_WAIT)
1609 {
1610 prop_line.color->red = 0xffff;
1611 prop_line.color->green = 0x0000;
1612 prop_line.color->blue = 0x0000;
1613 }
1614 else if(process->state->s == LTTV_STATE_RUN)
1615 {
1616 prop_line.color->red = 0x0000;
1617 prop_line.color->green = 0xffff;
1618 prop_line.color->blue = 0x0000;
1619 }
1620 else
1621 {
1622 prop_line.color->red = 0xffff;
1623 prop_line.color->green = 0xffff;
1624 prop_line.color->blue = 0xffff;
1625 }
1626
1627 }
1628 else
1629 {
1630 prop_line.color->red = 0xffff;
1631 prop_line.color->green = 0xffff;
1632 prop_line.color->blue = 0xffff;
1633 }
1634
1635 draw_line((void*)&prop_line, (void*)draw_context);
1636 g_free(prop_line.color);
1637 gdk_gc_unref(draw_context->gc);
1638
1639 /* Reset draw_context of the process for next request */
1640
1641 hashed_process_data->draw_context->drawable = NULL;
1642 hashed_process_data->draw_context->gc = NULL;
1643 hashed_process_data->draw_context->pango_layout = NULL;
1644 hashed_process_data->draw_context->current->over->x = -1;
1645 hashed_process_data->draw_context->current->over->y = -1;
1646 hashed_process_data->draw_context->current->middle->x = -1;
1647 hashed_process_data->draw_context->current->middle->y = -1;
1648 hashed_process_data->draw_context->current->under->x = -1;
1649 hashed_process_data->draw_context->current->under->y = -1;
1650 hashed_process_data->draw_context->current->modify_over->x = -1;
1651 hashed_process_data->draw_context->current->modify_over->y = -1;
1652 hashed_process_data->draw_context->current->modify_middle->x = -1;
1653 hashed_process_data->draw_context->current->modify_middle->y = -1;
1654 hashed_process_data->draw_context->current->modify_under->x = -1;
1655 hashed_process_data->draw_context->current->modify_under->y = -1;
1656 hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED;
1657 hashed_process_data->draw_context->previous->over->x = -1;
1658 hashed_process_data->draw_context->previous->over->y = -1;
1659 hashed_process_data->draw_context->previous->middle->x = -1;
1660 hashed_process_data->draw_context->previous->middle->y = -1;
1661 hashed_process_data->draw_context->previous->under->x = -1;
1662 hashed_process_data->draw_context->previous->under->y = -1;
1663 hashed_process_data->draw_context->previous->modify_over->x = -1;
1664 hashed_process_data->draw_context->previous->modify_over->y = -1;
1665 hashed_process_data->draw_context->previous->modify_middle->x = -1;
1666 hashed_process_data->draw_context->previous->modify_middle->y = -1;
1667 hashed_process_data->draw_context->previous->modify_under->x = -1;
1668 hashed_process_data->draw_context->previous->modify_under->y = -1;
1669 hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED;
1670
1671
1672 }
1673
1674 /*
1675 * for each process
1676 * draw closing line
1677 * new default prev and current
1678 * then finally remove reading hooks.
1679 */
1680 int after_data_request(void *hook_data, void *call_data)
1681 {
1682 EventRequest *event_request = (EventRequest*)hook_data;
1683 ControlFlowData *control_flow_data = event_request->control_flow_data;
1684
1685 ProcessList *process_list =
1686 guicontrolflow_get_process_list(event_request->control_flow_data);
1687
1688 ClosureData closure_data;
1689 closure_data.event_request = (EventRequest*)hook_data;
1690 closure_data.tss = (LttvTracesetState*)call_data;
1691
1692 g_hash_table_foreach(process_list->process_hash, draw_closure,
1693 (void*)&closure_data);
1694
1695 /* Remove reading hooks */
1696 // Cannot do this here, will break processtrace!
1697 //drawing_data_request_end(control_flow_data->drawing);
1698
1699 }
1700
This page took 0.066866 seconds and 4 git commands to generate.