1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
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;
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.
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,
20 /*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
25 //#define PANGO_ENABLE_BACKEND
33 //#include <pango/pango.h>
35 #include <ltt/event.h>
39 #include <lttv/lttv.h>
40 #include <lttv/hook.h>
41 #include <lttv/state.h>
42 #include <lttvwindow/lttvwindow.h>
45 #include "eventhooks.h"
47 #include "processlist.h"
49 #include "cfv-private.h"
52 #define MAX_PATH_LEN 256
56 * Event Viewer's constructor hook
58 * This constructor is given as a parameter to the menuitem and toolbar button
59 * registration. It creates the list.
60 * @param tab A pointer to the parent tab.
61 * @return The widget created.
64 h_guicontrolflow(Tab
*tab
, LttvTracesetSelector
* s
, char * key
)
66 g_info("h_guicontrolflow, %p, %p, %s", tab
, s
, key
);
67 ControlFlowData
*control_flow_data
= guicontrolflow() ;
69 control_flow_data
->tab
= tab
;
71 //g_debug("time width2 : %u",time_window->time_width);
72 // Unreg done in the GuiControlFlow_Destructor
73 lttvwindow_register_time_window_notify(tab
,
74 update_time_window_hook
,
76 lttvwindow_register_current_time_notify(tab
,
77 update_current_time_hook
,
79 lttvwindow_register_redraw_notify(tab
,
82 lttvwindow_register_continue_notify(tab
,
87 return guicontrolflow_get_widget(control_flow_data
) ;
91 int event_selected_hook(void *hook_data
, void *call_data
)
93 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
94 guint
*event_number
= (guint
*) call_data
;
96 g_debug("DEBUG : event selected by main window : %u", *event_number
);
98 // control_flow_data->currently_Selected_Event = *event_number;
99 // control_flow_data->Selected_Event = TRUE ;
101 // tree_v_set_cursor(control_flow_data);
105 /* Hook called before drawing. Gets the initial context at the beginning of the
106 * drawing interval and copy it to the context in event_request.
108 int draw_before_hook(void *hook_data
, void *call_data
)
110 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
111 //EventsContext Events_Context = (EventsContext*)call_data;
113 //event_request->Events_Context = Events_Context;
119 * The draw event hook is called by the reading API to have a
120 * particular event drawn on the screen.
121 * @param hook_data ControlFlowData structure of the viewer.
122 * @param call_data Event context.
124 * This function basically draw lines and icons. Two types of lines are drawn :
125 * one small (3 pixels?) representing the state of the process and the second
126 * type is thicker (10 pixels?) representing on which CPU a process is running
127 * (and this only in running state).
129 * Extremums of the lines :
130 * x_min : time of the last event context for this process kept in memory.
131 * x_max : time of the current event.
132 * y : middle of the process in the process list. The process is found in the
133 * list, therefore is it's position in pixels.
135 * The choice of lines'color is defined by the context of the last event for this
138 int draw_event_hook(void *hook_data
, void *call_data
)
140 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
141 ControlFlowData
*control_flow_data
=
142 (ControlFlowData
*)events_request
->viewer_data
;
143 Tab
*tab
= control_flow_data
->tab
;
145 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
147 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
148 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
153 LttTime evtime
= ltt_event_time(e
);
154 TimeWindow time_window
=
155 lttvwindow_get_time_window(tab
);
157 LttTime end_time
= ltt_time_add(time_window
.start_time
,
158 time_window
.time_width
);
159 //if(time < time_beg || time > time_end) return;
160 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
161 || ltt_time_compare(evtime
, end_time
) == 1)
164 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
166 g_debug("schedchange!");
168 /* Add process to process list (if not present) and get drawing "y" from
169 * process position */
170 guint pid_out
, pid_in
;
171 LttvProcessState
*process_out
, *process_in
;
173 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
175 ProcessList
*process_list
=
176 guicontrolflow_get_process_list(control_flow_data
);
179 LttField
*f
= ltt_event_field(e
);
181 element
= ltt_field_member(f
,0);
182 pid_out
= ltt_event_get_long_unsigned(e
,element
);
183 element
= ltt_field_member(f
,1);
184 pid_in
= ltt_event_get_long_unsigned(e
,element
);
185 g_debug("out : %u in : %u", pid_out
, pid_in
);
188 /* Find process pid_out in the list... */
189 process_out
= lttv_state_find_process(tfs
, pid_out
);
190 if(process_out
== NULL
) return 0;
191 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
193 birth
= process_out
->creation_time
;
194 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
195 HashedProcessData
*hashed_process_data_out
= NULL
;
197 if(processlist_get_process_pixels(process_list
,
200 tfc
->t_context
->index
,
203 &hashed_process_data_out
) == 1)
205 /* Process not present */
206 processlist_add(process_list
,
209 tfc
->t_context
->index
,
212 &hashed_process_data_out
);
213 processlist_get_process_pixels(process_list
,
216 tfc
->t_context
->index
,
219 &hashed_process_data_out
);
220 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
225 /* Find process pid_in in the list... */
226 process_in
= lttv_state_find_process(tfs
, pid_in
);
227 if(process_in
== NULL
) return 0;
228 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
230 birth
= process_in
->creation_time
;
231 name
= strdup(g_quark_to_string(process_in
->name
));
232 HashedProcessData
*hashed_process_data_in
= NULL
;
234 if(processlist_get_process_pixels(process_list
,
237 tfc
->t_context
->index
,
240 &hashed_process_data_in
) == 1)
242 /* Process not present */
243 processlist_add(process_list
,
246 tfc
->t_context
->index
,
249 &hashed_process_data_in
);
250 processlist_get_process_pixels(process_list
,
253 tfc
->t_context
->index
,
256 &hashed_process_data_in
);
258 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
263 /* Find pixels corresponding to time of the event. If the time does
264 * not fit in the window, show a warning, not supposed to happend. */
266 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
268 LttTime time
= ltt_event_time(e
);
270 LttTime window_end
= ltt_time_add(time_window
.time_width
,
271 time_window
.start_time
);
274 convert_time_to_pixels(
275 time_window
.start_time
,
280 //assert(x <= width);
282 /* draw what represents the event for outgoing process. */
284 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
285 draw_context_out
->current
->modify_over
->x
= x
;
286 draw_context_out
->current
->modify_under
->x
= x
;
287 draw_context_out
->current
->modify_over
->y
= y_out
;
288 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
289 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
290 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
291 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
292 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
293 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
294 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
295 //draw_context_out->gc = widget->style->black_gc;
297 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
298 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
300 /* Draw the line/background of the out process */
301 if(draw_context_out
->previous
->middle
->x
== -1)
303 draw_context_out
->previous
->over
->x
=
304 control_flow_data
->drawing
->damage_begin
;
305 draw_context_out
->previous
->middle
->x
=
306 control_flow_data
->drawing
->damage_begin
;
307 draw_context_out
->previous
->under
->x
=
308 control_flow_data
->drawing
->damage_begin
;
310 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
313 draw_context_out
->current
->middle
->x
= x
;
314 draw_context_out
->current
->over
->x
= x
;
315 draw_context_out
->current
->under
->x
= x
;
316 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
317 draw_context_out
->current
->over
->y
= y_out
;
318 draw_context_out
->current
->under
->y
= y_out
+ height
;
319 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
320 draw_context_out
->previous
->over
->y
= y_out
;
321 draw_context_out
->previous
->under
->y
= y_out
+ height
;
323 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
324 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
326 if(process_out
->state
->s
== LTTV_STATE_RUN
)
328 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
329 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
331 PropertiesBG prop_bg
;
332 prop_bg
.color
= g_new(GdkColor
,1);
336 prop_bg
.color
->red
= 0x1515;
337 prop_bg
.color
->green
= 0x1515;
338 prop_bg
.color
->blue
= 0x8c8c;
341 prop_bg
.color
->red
= 0x4e4e;
342 prop_bg
.color
->green
= 0xa9a9;
343 prop_bg
.color
->blue
= 0xa4a4;
346 prop_bg
.color
->red
= 0x7a7a;
347 prop_bg
.color
->green
= 0x4a4a;
348 prop_bg
.color
->blue
= 0x8b8b;
351 prop_bg
.color
->red
= 0x8080;
352 prop_bg
.color
->green
= 0x7777;
353 prop_bg
.color
->blue
= 0x4747;
356 prop_bg
.color
->red
= 0xe7e7;
357 prop_bg
.color
->green
= 0xe7e7;
358 prop_bg
.color
->blue
= 0xe7e7;
361 g_debug("calling from draw_event");
362 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
363 g_free(prop_bg
.color
);
364 gdk_gc_unref(draw_context_out
->gc
);
367 draw_context_out
->gc
= widget
->style
->black_gc
;
369 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
370 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
371 PropertiesText prop_text_out
;
372 prop_text_out
.foreground
= &colorfg_out
;
373 prop_text_out
.background
= &colorbg_out
;
374 prop_text_out
.size
= 6;
375 prop_text_out
.position
= OVER
;
377 /* color of text : status of the process */
378 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
380 prop_text_out
.foreground
->red
= 0xffff;
381 prop_text_out
.foreground
->green
= 0xffff;
382 prop_text_out
.foreground
->blue
= 0xffff;
384 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
386 prop_text_out
.foreground
->red
= 0x0fff;
387 prop_text_out
.foreground
->green
= 0xffff;
388 prop_text_out
.foreground
->blue
= 0xfff0;
390 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
392 prop_text_out
.foreground
->red
= 0xffff;
393 prop_text_out
.foreground
->green
= 0xffff;
394 prop_text_out
.foreground
->blue
= 0x0000;
396 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
398 prop_text_out
.foreground
->red
= 0xffff;
399 prop_text_out
.foreground
->green
= 0x0000;
400 prop_text_out
.foreground
->blue
= 0xffff;
402 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
404 prop_text_out
.foreground
->red
= 0xffff;
405 prop_text_out
.foreground
->green
= 0x0000;
406 prop_text_out
.foreground
->blue
= 0x0000;
408 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
410 prop_text_out
.foreground
->red
= 0x0000;
411 prop_text_out
.foreground
->green
= 0xffff;
412 prop_text_out
.foreground
->blue
= 0x0000;
416 prop_text_out
.foreground
->red
= 0xffff;
417 prop_text_out
.foreground
->green
= 0xffff;
418 prop_text_out
.foreground
->blue
= 0xffff;
422 /* Print status of the process : U, WF, WC, E, W, R */
423 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
424 prop_text_out
.text
= "U->";
425 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
426 prop_text_out
.text
= "WF->";
427 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
428 prop_text_out
.text
= "WC->";
429 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
430 prop_text_out
.text
= "E->";
431 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
432 prop_text_out
.text
= "W->";
433 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
434 prop_text_out
.text
= "R->";
436 prop_text_out
.text
= "U";
438 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
439 //gdk_gc_unref(draw_context_out->gc);
441 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
442 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
444 PropertiesLine prop_line_out
;
445 prop_line_out
.color
= g_new(GdkColor
,1);
446 prop_line_out
.line_width
= 2;
447 prop_line_out
.style
= GDK_LINE_SOLID
;
448 prop_line_out
.position
= MIDDLE
;
450 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
452 /* color of line : status of the process */
453 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
455 prop_line_out
.color
->red
= 0xffff;
456 prop_line_out
.color
->green
= 0xffff;
457 prop_line_out
.color
->blue
= 0xffff;
459 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
461 prop_line_out
.color
->red
= 0x0fff;
462 prop_line_out
.color
->green
= 0xffff;
463 prop_line_out
.color
->blue
= 0xfff0;
465 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
467 prop_line_out
.color
->red
= 0xffff;
468 prop_line_out
.color
->green
= 0xffff;
469 prop_line_out
.color
->blue
= 0x0000;
471 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
473 prop_line_out
.color
->red
= 0xffff;
474 prop_line_out
.color
->green
= 0x0000;
475 prop_line_out
.color
->blue
= 0xffff;
477 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
479 prop_line_out
.color
->red
= 0xffff;
480 prop_line_out
.color
->green
= 0x0000;
481 prop_line_out
.color
->blue
= 0x0000;
483 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
485 prop_line_out
.color
->red
= 0x0000;
486 prop_line_out
.color
->green
= 0xffff;
487 prop_line_out
.color
->blue
= 0x0000;
491 prop_line_out
.color
->red
= 0xffff;
492 prop_line_out
.color
->green
= 0xffff;
493 prop_line_out
.color
->blue
= 0xffff;
496 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
497 g_free(prop_line_out
.color
);
498 gdk_gc_unref(draw_context_out
->gc
);
499 /* Note : finishing line will have to be added when trace read over. */
501 /* Finally, update the drawing context of the pid_in. */
503 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
504 draw_context_in
->current
->modify_over
->x
= x
;
505 draw_context_in
->current
->modify_under
->x
= x
;
506 draw_context_in
->current
->modify_over
->y
= y_in
;
507 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
508 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
509 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
510 widget
= control_flow_data
->drawing
->drawing_area
;
511 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
512 //draw_context_in->gc = widget->style->black_gc;
513 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
514 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
516 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
517 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
519 /* Draw the line/bg of the in process */
520 if(draw_context_in
->previous
->middle
->x
== -1)
522 draw_context_in
->previous
->over
->x
=
523 control_flow_data
->drawing
->damage_begin
;
524 draw_context_in
->previous
->middle
->x
=
525 control_flow_data
->drawing
->damage_begin
;
526 draw_context_in
->previous
->under
->x
=
527 control_flow_data
->drawing
->damage_begin
;
529 g_debug("in middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
533 draw_context_in
->current
->middle
->x
= x
;
534 draw_context_in
->current
->over
->x
= x
;
535 draw_context_in
->current
->under
->x
= x
;
536 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
537 draw_context_in
->current
->over
->y
= y_in
;
538 draw_context_in
->current
->under
->y
= y_in
+ height
;
539 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
540 draw_context_in
->previous
->over
->y
= y_in
;
541 draw_context_in
->previous
->under
->y
= y_in
+ height
;
543 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
544 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
547 if(process_in
->state
->s
== LTTV_STATE_RUN
)
549 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
550 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
552 PropertiesBG prop_bg
;
553 prop_bg
.color
= g_new(GdkColor
,1);
557 prop_bg
.color
->red
= 0x1515;
558 prop_bg
.color
->green
= 0x1515;
559 prop_bg
.color
->blue
= 0x8c8c;
562 prop_bg
.color
->red
= 0x4e4e;
563 prop_bg
.color
->green
= 0xa9a9;
564 prop_bg
.color
->blue
= 0xa4a4;
567 prop_bg
.color
->red
= 0x7a7a;
568 prop_bg
.color
->green
= 0x4a4a;
569 prop_bg
.color
->blue
= 0x8b8b;
572 prop_bg
.color
->red
= 0x8080;
573 prop_bg
.color
->green
= 0x7777;
574 prop_bg
.color
->blue
= 0x4747;
577 prop_bg
.color
->red
= 0xe7e7;
578 prop_bg
.color
->green
= 0xe7e7;
579 prop_bg
.color
->blue
= 0xe7e7;
583 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
584 g_free(prop_bg
.color
);
585 gdk_gc_unref(draw_context_in
->gc
);
588 draw_context_in
->gc
= widget
->style
->black_gc
;
590 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
591 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
592 PropertiesText prop_text_in
;
593 prop_text_in
.foreground
= &colorfg_in
;
594 prop_text_in
.background
= &colorbg_in
;
595 prop_text_in
.size
= 6;
596 prop_text_in
.position
= OVER
;
598 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
599 /* foreground of text : status of the process */
600 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
602 prop_text_in
.foreground
->red
= 0xffff;
603 prop_text_in
.foreground
->green
= 0xffff;
604 prop_text_in
.foreground
->blue
= 0xffff;
606 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
608 prop_text_in
.foreground
->red
= 0x0fff;
609 prop_text_in
.foreground
->green
= 0xffff;
610 prop_text_in
.foreground
->blue
= 0xfff0;
612 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
614 prop_text_in
.foreground
->red
= 0xffff;
615 prop_text_in
.foreground
->green
= 0xffff;
616 prop_text_in
.foreground
->blue
= 0x0000;
618 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
620 prop_text_in
.foreground
->red
= 0xffff;
621 prop_text_in
.foreground
->green
= 0x0000;
622 prop_text_in
.foreground
->blue
= 0xffff;
624 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
626 prop_text_in
.foreground
->red
= 0xffff;
627 prop_text_in
.foreground
->green
= 0x0000;
628 prop_text_in
.foreground
->blue
= 0x0000;
630 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
632 prop_text_in
.foreground
->red
= 0x0000;
633 prop_text_in
.foreground
->green
= 0xffff;
634 prop_text_in
.foreground
->blue
= 0x0000;
638 prop_text_in
.foreground
->red
= 0xffff;
639 prop_text_in
.foreground
->green
= 0xffff;
640 prop_text_in
.foreground
->blue
= 0xffff;
645 /* Print status of the process : U, WF, WC, E, W, R */
646 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
647 prop_text_in
.text
= "U->";
648 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
649 prop_text_in
.text
= "WF->";
650 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
651 prop_text_in
.text
= "WC->";
652 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
653 prop_text_in
.text
= "E->";
654 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
655 prop_text_in
.text
= "W->";
656 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
657 prop_text_in
.text
= "R->";
659 prop_text_in
.text
= "U";
661 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
662 //gdk_gc_unref(draw_context_in->gc);
664 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
665 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
667 PropertiesLine prop_line_in
;
668 prop_line_in
.color
= g_new(GdkColor
,1);
669 prop_line_in
.line_width
= 2;
670 prop_line_in
.style
= GDK_LINE_SOLID
;
671 prop_line_in
.position
= MIDDLE
;
673 /* color of line : status of the process */
674 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
676 prop_line_in
.color
->red
= 0xffff;
677 prop_line_in
.color
->green
= 0xffff;
678 prop_line_in
.color
->blue
= 0xffff;
680 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
682 prop_line_in
.color
->red
= 0x0fff;
683 prop_line_in
.color
->green
= 0xffff;
684 prop_line_in
.color
->blue
= 0xfff0;
686 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
688 prop_line_in
.color
->red
= 0xffff;
689 prop_line_in
.color
->green
= 0xffff;
690 prop_line_in
.color
->blue
= 0x0000;
692 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
694 prop_line_in
.color
->red
= 0xffff;
695 prop_line_in
.color
->green
= 0x0000;
696 prop_line_in
.color
->blue
= 0xffff;
698 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
700 prop_line_in
.color
->red
= 0xffff;
701 prop_line_in
.color
->green
= 0x0000;
702 prop_line_in
.color
->blue
= 0x0000;
704 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
706 prop_line_in
.color
->red
= 0x0000;
707 prop_line_in
.color
->green
= 0xffff;
708 prop_line_in
.color
->blue
= 0x0000;
712 prop_line_in
.color
->red
= 0xffff;
713 prop_line_in
.color
->green
= 0xffff;
714 prop_line_in
.color
->blue
= 0xffff;
717 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
718 g_free(prop_line_in
.color
);
719 gdk_gc_unref(draw_context_in
->gc
);
726 GString
*string
= g_string_new("");;
727 gboolean field_names
= TRUE
, state
= TRUE
;
729 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
730 g_string_append_printf(string
,"\n");
733 g_string_append_printf(string
, " %s",
734 g_quark_to_string(tfs
->process
->state
->s
));
737 g_info("%s",string
->str
);
739 g_string_free(string
, TRUE
);
741 /* End of text dump */
747 int draw_after_hook(void *hook_data
, void *call_data
)
749 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
750 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
752 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
754 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
755 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
761 LttTime evtime
= ltt_event_time(e
);
762 TimeWindow time_window
=
763 lttvwindow_get_time_window(control_flow_data
->tab
);
765 LttTime end_time
= ltt_time_add(time_window
.start_time
,
766 time_window
.time_width
);
767 //if(time < time_beg || time > time_end) return;
768 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
769 || ltt_time_compare(evtime
, end_time
) == 1)
773 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
775 g_debug("schedchange!");
777 /* Add process to process list (if not present) and get drawing "y" from
778 * process position */
779 guint pid_out
, pid_in
;
780 LttvProcessState
*process_out
, *process_in
;
782 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
784 ProcessList
*process_list
=
785 guicontrolflow_get_process_list(control_flow_data
);
788 LttField
*f
= ltt_event_field(e
);
790 element
= ltt_field_member(f
,0);
791 pid_out
= ltt_event_get_long_unsigned(e
,element
);
792 element
= ltt_field_member(f
,1);
793 pid_in
= ltt_event_get_long_unsigned(e
,element
);
794 //g_debug("out : %u in : %u", pid_out, pid_in);
797 /* Find process pid_out in the list... */
798 process_out
= lttv_state_find_process(tfs
, pid_out
);
799 if(process_out
== NULL
) return 0;
800 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
802 birth
= process_out
->creation_time
;
803 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
804 HashedProcessData
*hashed_process_data_out
= NULL
;
806 if(processlist_get_process_pixels(process_list
,
809 tfc
->t_context
->index
,
812 &hashed_process_data_out
) == 1)
814 /* Process not present */
815 processlist_add(process_list
,
818 tfc
->t_context
->index
,
821 &hashed_process_data_out
);
822 processlist_get_process_pixels(process_list
,
825 tfc
->t_context
->index
,
828 &hashed_process_data_out
);
829 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
834 /* Find process pid_in in the list... */
835 process_in
= lttv_state_find_process(tfs
, pid_in
);
836 if(process_in
== NULL
) return 0;
837 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
839 birth
= process_in
->creation_time
;
840 name
= strdup(g_quark_to_string(process_in
->name
));
841 HashedProcessData
*hashed_process_data_in
= NULL
;
843 if(processlist_get_process_pixels(process_list
,
846 tfc
->t_context
->index
,
849 &hashed_process_data_in
) == 1)
851 /* Process not present */
852 processlist_add(process_list
,
855 tfc
->t_context
->index
,
858 &hashed_process_data_in
);
859 processlist_get_process_pixels(process_list
,
862 tfc
->t_context
->index
,
865 &hashed_process_data_in
);
867 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
872 /* Find pixels corresponding to time of the event. If the time does
873 * not fit in the window, show a warning, not supposed to happend. */
875 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
877 //LttTime time = ltt_event_time(e);
879 //LttTime window_end = ltt_time_add(time_window->time_width,
880 // time_window->start_time);
883 //convert_time_to_pixels(
884 // time_window->start_time,
890 //assert(x <= width);
892 /* draw what represents the event for outgoing process. */
894 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
895 //draw_context_out->current->modify_over->x = x;
896 draw_context_out
->current
->modify_over
->y
= y_out
;
897 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
898 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
899 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
900 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
901 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
903 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
904 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
906 /*if(process_out->state->s == LTTV_STATE_RUN)
908 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
909 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
910 PropertiesBG prop_bg;
911 prop_bg.color = g_new(GdkColor,1);
913 prop_bg.color->red = 0xffff;
914 prop_bg.color->green = 0xffff;
915 prop_bg.color->blue = 0xffff;
917 draw_bg((void*)&prop_bg, (void*)draw_context_out);
918 g_free(prop_bg.color);
919 gdk_gc_unref(draw_context_out->gc);
922 draw_context_out
->gc
= widget
->style
->black_gc
;
924 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
925 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
926 PropertiesText prop_text_out
;
927 prop_text_out
.foreground
= &colorfg_out
;
928 prop_text_out
.background
= &colorbg_out
;
929 prop_text_out
.size
= 6;
930 prop_text_out
.position
= OVER
;
932 /* color of text : status of the process */
933 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
935 prop_text_out
.foreground
->red
= 0xffff;
936 prop_text_out
.foreground
->green
= 0xffff;
937 prop_text_out
.foreground
->blue
= 0xffff;
939 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
941 prop_text_out
.foreground
->red
= 0x0fff;
942 prop_text_out
.foreground
->green
= 0xffff;
943 prop_text_out
.foreground
->blue
= 0xfff0;
945 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
947 prop_text_out
.foreground
->red
= 0xffff;
948 prop_text_out
.foreground
->green
= 0xffff;
949 prop_text_out
.foreground
->blue
= 0x0000;
951 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
953 prop_text_out
.foreground
->red
= 0xffff;
954 prop_text_out
.foreground
->green
= 0x0000;
955 prop_text_out
.foreground
->blue
= 0xffff;
957 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
959 prop_text_out
.foreground
->red
= 0xffff;
960 prop_text_out
.foreground
->green
= 0x0000;
961 prop_text_out
.foreground
->blue
= 0x0000;
963 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
965 prop_text_out
.foreground
->red
= 0x0000;
966 prop_text_out
.foreground
->green
= 0xffff;
967 prop_text_out
.foreground
->blue
= 0x0000;
971 prop_text_out
.foreground
->red
= 0xffff;
972 prop_text_out
.foreground
->green
= 0xffff;
973 prop_text_out
.foreground
->blue
= 0xffff;
976 /* Print status of the process : U, WF, WC, E, W, R */
977 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
978 prop_text_out
.text
= "U";
979 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
980 prop_text_out
.text
= "WF";
981 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
982 prop_text_out
.text
= "WC";
983 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
984 prop_text_out
.text
= "E";
985 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
986 prop_text_out
.text
= "W";
987 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
988 prop_text_out
.text
= "R";
990 prop_text_out
.text
= "U";
992 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
994 //gdk_gc_unref(draw_context_out->gc);
996 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
997 draw_context_out
->current
->over
->y
= y_out
;
998 draw_context_out
->current
->under
->y
= y_out
+height
;
999 draw_context_out
->current
->status
= process_out
->state
->s
;
1001 /* for pid_out : remove previous, Prev = current, new current (default) */
1002 g_free(draw_context_out
->previous
->modify_under
);
1003 g_free(draw_context_out
->previous
->modify_middle
);
1004 g_free(draw_context_out
->previous
->modify_over
);
1005 g_free(draw_context_out
->previous
->under
);
1006 g_free(draw_context_out
->previous
->middle
);
1007 g_free(draw_context_out
->previous
->over
);
1008 g_free(draw_context_out
->previous
);
1010 draw_context_out
->previous
= draw_context_out
->current
;
1012 draw_context_out
->current
= g_new(DrawInfo
,1);
1013 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
1014 draw_context_out
->current
->over
->x
= -1;
1015 draw_context_out
->current
->over
->y
= -1;
1016 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1017 draw_context_out
->current
->middle
->x
= -1;
1018 draw_context_out
->current
->middle
->y
= -1;
1019 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1020 draw_context_out
->current
->under
->x
= -1;
1021 draw_context_out
->current
->under
->y
= -1;
1022 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1023 draw_context_out
->current
->modify_over
->x
= -1;
1024 draw_context_out
->current
->modify_over
->y
= -1;
1025 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1026 draw_context_out
->current
->modify_middle
->x
= -1;
1027 draw_context_out
->current
->modify_middle
->y
= -1;
1028 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1029 draw_context_out
->current
->modify_under
->x
= -1;
1030 draw_context_out
->current
->modify_under
->y
= -1;
1031 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1033 /* Finally, update the drawing context of the pid_in. */
1035 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1036 //draw_context_in->current->modify_over->x = x;
1037 draw_context_in
->current
->modify_over
->y
= y_in
;
1038 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1039 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1040 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1041 widget
= control_flow_data
->drawing
->drawing_area
;
1042 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1044 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1045 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1047 /*if(process_in->state->s == LTTV_STATE_RUN)
1049 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1050 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1051 PropertiesBG prop_bg;
1052 prop_bg.color = g_new(GdkColor,1);
1054 prop_bg.color->red = 0xffff;
1055 prop_bg.color->green = 0xffff;
1056 prop_bg.color->blue = 0xffff;
1058 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1059 g_free(prop_bg.color);
1060 gdk_gc_unref(draw_context_in->gc);
1063 draw_context_in
->gc
= widget
->style
->black_gc
;
1065 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1066 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1067 PropertiesText prop_text_in
;
1068 prop_text_in
.foreground
= &colorfg_in
;
1069 prop_text_in
.background
= &colorbg_in
;
1070 prop_text_in
.size
= 6;
1071 prop_text_in
.position
= OVER
;
1073 /* foreground of text : status of the process */
1074 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1076 prop_text_in
.foreground
->red
= 0xffff;
1077 prop_text_in
.foreground
->green
= 0xffff;
1078 prop_text_in
.foreground
->blue
= 0xffff;
1080 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1082 prop_text_in
.foreground
->red
= 0x0fff;
1083 prop_text_in
.foreground
->green
= 0xffff;
1084 prop_text_in
.foreground
->blue
= 0xfff0;
1086 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1088 prop_text_in
.foreground
->red
= 0xffff;
1089 prop_text_in
.foreground
->green
= 0xffff;
1090 prop_text_in
.foreground
->blue
= 0x0000;
1092 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1094 prop_text_in
.foreground
->red
= 0xffff;
1095 prop_text_in
.foreground
->green
= 0x0000;
1096 prop_text_in
.foreground
->blue
= 0xffff;
1098 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1100 prop_text_in
.foreground
->red
= 0xffff;
1101 prop_text_in
.foreground
->green
= 0x0000;
1102 prop_text_in
.foreground
->blue
= 0x0000;
1104 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1106 prop_text_in
.foreground
->red
= 0x0000;
1107 prop_text_in
.foreground
->green
= 0xffff;
1108 prop_text_in
.foreground
->blue
= 0x0000;
1112 prop_text_in
.foreground
->red
= 0xffff;
1113 prop_text_in
.foreground
->green
= 0xffff;
1114 prop_text_in
.foreground
->blue
= 0xffff;
1118 /* Print status of the process : U, WF, WC, E, W, R */
1119 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1120 prop_text_in
.text
= "U";
1121 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1122 prop_text_in
.text
= "WF";
1123 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1124 prop_text_in
.text
= "WC";
1125 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1126 prop_text_in
.text
= "E";
1127 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1128 prop_text_in
.text
= "W";
1129 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1130 prop_text_in
.text
= "R";
1132 prop_text_in
.text
= "U";
1134 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1137 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1140 prop_text_in
.foreground
= &colorfg_in
;
1141 prop_text_in
.background
= &colorbg_in
;
1142 prop_text_in
.foreground
->red
= 0xffff;
1143 prop_text_in
.foreground
->green
= 0xffff;
1144 prop_text_in
.foreground
->blue
= 0xffff;
1145 prop_text_in
.size
= 6;
1146 prop_text_in
.position
= UNDER
;
1148 prop_text_in
.text
= g_new(gchar
, 260);
1149 strcpy(prop_text_in
.text
, "CPU ");
1150 snprintf(tmp
, 255, "%u", tfc
->index
);
1151 strcat(prop_text_in
.text
, tmp
);
1153 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1154 g_free(prop_text_in
.text
);
1158 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1159 draw_context_in
->current
->over
->y
= y_in
;
1160 draw_context_in
->current
->under
->y
= y_in
+height
;
1161 draw_context_in
->current
->status
= process_in
->state
->s
;
1163 /* for pid_in : remove previous, Prev = current, new current (default) */
1164 g_free(draw_context_in
->previous
->modify_under
);
1165 g_free(draw_context_in
->previous
->modify_middle
);
1166 g_free(draw_context_in
->previous
->modify_over
);
1167 g_free(draw_context_in
->previous
->under
);
1168 g_free(draw_context_in
->previous
->middle
);
1169 g_free(draw_context_in
->previous
->over
);
1170 g_free(draw_context_in
->previous
);
1172 draw_context_in
->previous
= draw_context_in
->current
;
1174 draw_context_in
->current
= g_new(DrawInfo
,1);
1175 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1176 draw_context_in
->current
->over
->x
= -1;
1177 draw_context_in
->current
->over
->y
= -1;
1178 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1179 draw_context_in
->current
->middle
->x
= -1;
1180 draw_context_in
->current
->middle
->y
= -1;
1181 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1182 draw_context_in
->current
->under
->x
= -1;
1183 draw_context_in
->current
->under
->y
= -1;
1184 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1185 draw_context_in
->current
->modify_over
->x
= -1;
1186 draw_context_in
->current
->modify_over
->y
= -1;
1187 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1188 draw_context_in
->current
->modify_middle
->x
= -1;
1189 draw_context_in
->current
->modify_middle
->y
= -1;
1190 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1191 draw_context_in
->current
->modify_under
->x
= -1;
1192 draw_context_in
->current
->modify_under
->y
= -1;
1193 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1203 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1205 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1206 Drawing_t
*drawing
= control_flow_data
->drawing
;
1208 const TimeWindowNotifyData
*time_window_nofify_data
=
1209 ((const TimeWindowNotifyData
*)call_data
);
1211 TimeWindow
*old_time_window
=
1212 time_window_nofify_data
->old_time_window
;
1213 TimeWindow
*new_time_window
=
1214 time_window_nofify_data
->new_time_window
;
1216 /* Update the ruler */
1217 drawing_update_ruler(control_flow_data
->drawing
,
1221 /* Two cases : zoom in/out or scrolling */
1223 /* In order to make sure we can reuse the old drawing, the scale must
1224 * be the same and the new time interval being partly located in the
1225 * currently shown time interval. (reuse is only for scrolling)
1228 g_info("Old time window HOOK : %u, %u to %u, %u",
1229 old_time_window
->start_time
.tv_sec
,
1230 old_time_window
->start_time
.tv_nsec
,
1231 old_time_window
->time_width
.tv_sec
,
1232 old_time_window
->time_width
.tv_nsec
);
1234 g_info("New time window HOOK : %u, %u to %u, %u",
1235 new_time_window
->start_time
.tv_sec
,
1236 new_time_window
->start_time
.tv_nsec
,
1237 new_time_window
->time_width
.tv_sec
,
1238 new_time_window
->time_width
.tv_nsec
);
1240 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1241 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1243 /* Same scale (scrolling) */
1244 g_info("scrolling");
1245 LttTime
*ns
= &new_time_window
->start_time
;
1246 LttTime
*os
= &old_time_window
->start_time
;
1247 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1248 old_time_window
->time_width
);
1249 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1250 new_time_window
->time_width
);
1252 //if(ns<os+w && os+w<ns+w)
1253 //if(ns<old_end && os<ns)
1254 if(ltt_time_compare(*ns
, old_end
) == -1
1255 && ltt_time_compare(*os
, *ns
) == -1)
1257 g_info("scrolling near right");
1258 /* Scroll right, keep right part of the screen */
1260 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1261 convert_time_to_pixels(
1268 /* Copy old data to new location */
1269 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1270 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1271 control_flow_data
->drawing
->pixmap
,
1276 /* Clear the data request background, but not SAFETY */
1277 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1278 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1281 control_flow_data
->drawing
->width
- x
, // do not overlap
1282 control_flow_data
->drawing
->height
+SAFETY
);
1284 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1286 control_flow_data
->drawing
->width
- x
,
1287 control_flow_data
->drawing
->height
);
1289 /* Get new data for the rest. */
1290 drawing_data_request(control_flow_data
->drawing
,
1291 &control_flow_data
->drawing
->pixmap
,
1293 control_flow_data
->drawing
->width
- x
,
1294 control_flow_data
->drawing
->height
);
1298 //if(ns<os && os<ns+w)
1299 //if(ns<os && os<new_end)
1300 if(ltt_time_compare(*ns
,*os
) == -1
1301 && ltt_time_compare(*os
,new_end
) == -1)
1303 g_info("scrolling near left");
1304 /* Scroll left, keep left part of the screen */
1306 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1307 convert_time_to_pixels(
1314 /* Copy old data to new location */
1315 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1316 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1317 control_flow_data
->drawing
->pixmap
,
1322 *old_time_window
= *new_time_window
;
1324 /* Clean the data request background */
1325 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1326 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1329 x
, // do not overlap
1330 control_flow_data
->drawing
->height
+SAFETY
);
1332 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1334 control_flow_data
->drawing
->width
- x
,
1335 control_flow_data
->drawing
->height
);
1337 /* Get new data for the rest. */
1338 drawing_data_request(control_flow_data
->drawing
,
1339 &control_flow_data
->drawing
->pixmap
,
1342 control_flow_data
->drawing
->height
);
1345 if(ltt_time_compare(*ns
,*os
) == 0)
1347 g_info("not scrolling");
1349 g_info("scrolling far");
1350 /* Cannot reuse any part of the screen : far jump */
1353 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1354 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1357 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1358 control_flow_data
->drawing
->height
+SAFETY
);
1360 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1362 control_flow_data
->drawing
->width
,
1363 control_flow_data
->drawing
->height
);
1365 drawing_data_request(control_flow_data
->drawing
,
1366 &control_flow_data
->drawing
->pixmap
,
1368 control_flow_data
->drawing
->width
,
1369 control_flow_data
->drawing
->height
);
1375 /* Different scale (zoom) */
1378 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1379 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1382 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1383 control_flow_data
->drawing
->height
+SAFETY
);
1385 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1387 control_flow_data
->drawing
->width
,
1388 control_flow_data
->drawing
->height
);
1390 drawing_data_request(control_flow_data
->drawing
,
1391 &control_flow_data
->drawing
->pixmap
,
1393 control_flow_data
->drawing
->width
,
1394 control_flow_data
->drawing
->height
);
1403 gint
redraw_notify(void *hook_data
, void *call_data
)
1405 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1406 Drawing_t
*drawing
= control_flow_data
->drawing
;
1407 GtkWidget
*widget
= drawing
->drawing_area
;
1409 drawing
->damage_begin
= 0;
1410 drawing
->damage_end
= widget
->allocation
.width
;
1414 gdk_draw_rectangle (drawing
->pixmap
,
1415 widget
->style
->black_gc
,
1418 widget
->allocation
.width
+SAFETY
,
1419 widget
->allocation
.height
+SAFETY
);
1422 if(drawing
->damage_begin
< drawing
->damage_end
)
1424 drawing_data_request(drawing
,
1426 drawing
->damage_begin
,
1428 drawing
->damage_end
-drawing
->damage_begin
,
1429 widget
->allocation
.height
);
1432 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1442 gint
continue_notify(void *hook_data
, void *call_data
)
1444 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1445 Drawing_t
*drawing
= control_flow_data
->drawing
;
1446 GtkWidget
*widget
= drawing
->drawing_area
;
1448 g_assert(widget
->allocation
.width
== drawing
->damage_end
);
1450 if(drawing
->damage_begin
< drawing
->damage_end
)
1452 drawing_data_request(drawing
,
1454 drawing
->damage_begin
,
1456 drawing
->damage_end
-drawing
->damage_begin
,
1457 widget
->allocation
.height
);
1464 gint
after_process_traceset_hook(void *hook_data
, void *call_data
)
1466 //ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1467 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1469 ControlFlowData
*control_flow_data
=
1470 (ControlFlowData
*)events_request
->viewer_data
;
1473 drawing_data_request_end(events_request
,
1474 (LttvTracesetState
*)call_data
);
1480 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1482 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1483 Drawing_t
*drawing
= control_flow_data
->drawing
;
1485 LttTime current_time
= *((LttTime
*)call_data
);
1487 TimeWindow time_window
=
1488 lttvwindow_get_time_window(control_flow_data
->tab
);
1490 LttTime time_begin
= time_window
.start_time
;
1491 LttTime width
= time_window
.time_width
;
1492 LttTime half_width
= ltt_time_div(width
,2.0);
1493 LttTime time_end
= ltt_time_add(time_begin
, width
);
1495 LttvTracesetContext
* tsc
=
1496 lttvwindow_get_traceset_context(control_flow_data
->tab
);
1498 LttTime trace_start
= tsc
->time_span
.start_time
;
1499 LttTime trace_end
= tsc
->time_span
.end_time
;
1501 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
1502 current_time
.tv_nsec
);
1506 /* If current time is inside time interval, just move the highlight
1509 /* Else, we have to change the time interval. We have to tell it
1510 * to the main window. */
1511 /* The time interval change will take care of placing the current
1512 * time at the center of the visible area, or nearest possible if we are
1513 * at one end of the trace. */
1516 if(ltt_time_compare(current_time
, time_begin
) == -1)
1518 TimeWindow new_time_window
;
1520 if(ltt_time_compare(current_time
,
1521 ltt_time_add(trace_start
,half_width
)) == -1)
1522 time_begin
= trace_start
;
1524 time_begin
= ltt_time_sub(current_time
,half_width
);
1526 new_time_window
.start_time
= time_begin
;
1527 new_time_window
.time_width
= width
;
1529 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1531 else if(ltt_time_compare(current_time
, time_end
) == 1)
1533 TimeWindow new_time_window
;
1535 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1536 time_begin
= ltt_time_sub(trace_end
,width
);
1538 time_begin
= ltt_time_sub(current_time
,half_width
);
1540 new_time_window
.start_time
= time_begin
;
1541 new_time_window
.time_width
= width
;
1543 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1546 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1547 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1555 typedef struct _ClosureData
{
1556 EventsRequest
*events_request
;
1557 LttvTracesetState
*tss
;
1561 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1563 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1564 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1565 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1567 ControlFlowData
*control_flow_data
=
1568 closure_data
->events_request
->viewer_data
;
1570 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1572 /* Get y position of process */
1575 processlist_get_pixels_from_data( control_flow_data
->process_list
,
1577 hashed_process_data
,
1580 /* Get last state of process */
1581 LttvTraceContext
*tc
=
1582 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
1583 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)closure_data
->tss
;
1585 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
1586 LttvProcessState
*process
;
1588 /* We do not provide a cpu_name argument assuming that this is not the
1589 idle job (pid 0) and thus its pid is unique across all cpus */
1590 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
1592 /* Draw the closing line */
1593 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
1594 if(draw_context
->previous
->middle
->x
== -1)
1596 draw_context
->previous
->over
->x
=
1597 control_flow_data
->drawing
->damage_begin
;
1598 draw_context
->previous
->middle
->x
=
1599 control_flow_data
->drawing
->damage_begin
;
1600 draw_context
->previous
->under
->x
=
1601 control_flow_data
->drawing
->damage_begin
;
1603 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
1606 /* Find pixels corresponding to current time . If the time does
1607 * not fit in the window, show a warning, not supposed to happend. */
1609 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1611 TimeWindow time_window
=
1612 lttvwindow_get_time_window(control_flow_data
->tab
);
1614 LttTime time
= lttv_traceset_context_get_current_tfc(tsc
)->timestamp
;
1616 LttTime window_end
= ltt_time_add(time_window
.time_width
,
1617 time_window
.start_time
);
1619 convert_time_to_pixels(
1620 time_window
.start_time
,
1626 draw_context
->current
->middle
->x
= x
;
1627 draw_context
->current
->over
->x
= x
;
1628 draw_context
->current
->under
->x
= x
;
1629 draw_context
->current
->middle
->y
= y
+ height
/2;
1630 draw_context
->current
->over
->y
= y
;
1631 draw_context
->current
->under
->y
= y
+ height
;
1632 draw_context
->previous
->middle
->y
= y
+ height
/2;
1633 draw_context
->previous
->over
->y
= y
;
1634 draw_context
->previous
->under
->y
= y
+ height
;
1635 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
1636 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1637 //draw_context->gc = widget->style->black_gc;
1638 draw_context
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
1639 gdk_gc_copy(draw_context
->gc
, widget
->style
->black_gc
);
1641 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
1643 PropertiesBG prop_bg
;
1644 prop_bg
.color
= g_new(GdkColor
,1);
1646 /*switch(tfc->index) {
1648 prop_bg.color->red = 0x1515;
1649 prop_bg.color->green = 0x1515;
1650 prop_bg.color->blue = 0x8c8c;
1653 prop_bg.color->red = 0x4e4e;
1654 prop_bg.color->green = 0xa9a9;
1655 prop_bg.color->blue = 0xa4a4;
1658 prop_bg.color->red = 0x7a7a;
1659 prop_bg.color->green = 0x4a4a;
1660 prop_bg.color->blue = 0x8b8b;
1663 prop_bg.color->red = 0x8080;
1664 prop_bg.color->green = 0x7777;
1665 prop_bg.color->blue = 0x4747;
1668 prop_bg.color->red = 0xe7e7;
1669 prop_bg.color->green = 0xe7e7;
1670 prop_bg.color->blue = 0xe7e7;
1674 g_debug("calling from closure");
1675 //FIXME : I need the cpu number in process's state to draw this.
1676 //draw_bg((void*)&prop_bg, (void*)draw_context);
1677 g_free(prop_bg
.color
);
1681 PropertiesLine prop_line
;
1682 prop_line
.color
= g_new(GdkColor
,1);
1683 prop_line
.line_width
= 2;
1684 prop_line
.style
= GDK_LINE_SOLID
;
1685 prop_line
.position
= MIDDLE
;
1687 /* color of line : status of the process */
1690 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
1692 prop_line
.color
->red
= 0xffff;
1693 prop_line
.color
->green
= 0xffff;
1694 prop_line
.color
->blue
= 0xffff;
1696 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
1698 prop_line
.color
->red
= 0x0fff;
1699 prop_line
.color
->green
= 0xffff;
1700 prop_line
.color
->blue
= 0xfff0;
1702 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
1704 prop_line
.color
->red
= 0xffff;
1705 prop_line
.color
->green
= 0xffff;
1706 prop_line
.color
->blue
= 0x0000;
1708 else if(process
->state
->s
== LTTV_STATE_EXIT
)
1710 prop_line
.color
->red
= 0xffff;
1711 prop_line
.color
->green
= 0x0000;
1712 prop_line
.color
->blue
= 0xffff;
1714 else if(process
->state
->s
== LTTV_STATE_WAIT
)
1716 prop_line
.color
->red
= 0xffff;
1717 prop_line
.color
->green
= 0x0000;
1718 prop_line
.color
->blue
= 0x0000;
1720 else if(process
->state
->s
== LTTV_STATE_RUN
)
1722 prop_line
.color
->red
= 0x0000;
1723 prop_line
.color
->green
= 0xffff;
1724 prop_line
.color
->blue
= 0x0000;
1728 prop_line
.color
->red
= 0xffff;
1729 prop_line
.color
->green
= 0xffff;
1730 prop_line
.color
->blue
= 0xffff;
1736 prop_line
.color
->red
= 0xffff;
1737 prop_line
.color
->green
= 0xffff;
1738 prop_line
.color
->blue
= 0xffff;
1741 draw_line((void*)&prop_line
, (void*)draw_context
);
1742 g_free(prop_line
.color
);
1743 gdk_gc_unref(draw_context
->gc
);
1745 /* Reset draw_context of the process for next request */
1747 hashed_process_data
->draw_context
->drawable
= NULL
;
1748 hashed_process_data
->draw_context
->gc
= NULL
;
1749 hashed_process_data
->draw_context
->pango_layout
= NULL
;
1750 hashed_process_data
->draw_context
->current
->over
->x
= -1;
1751 hashed_process_data
->draw_context
->current
->over
->y
= -1;
1752 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
1753 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
1754 hashed_process_data
->draw_context
->current
->under
->x
= -1;
1755 hashed_process_data
->draw_context
->current
->under
->y
= -1;
1756 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
1757 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
1758 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
1759 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
1760 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
1761 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
1762 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
1763 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
1764 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
1765 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
1766 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
1767 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
1768 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
1769 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
1770 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
1771 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
1772 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
1773 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
1774 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
1775 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
1779 int before_data_request(void *hook_data
, void *call_data
)
1781 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1782 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
1784 drawing_data_request_begin(events_request
, tss
);
1793 * new default prev and current
1794 * then finally remove reading hooks.
1796 int after_data_request(void *hook_data
, void *call_data
)
1798 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1799 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1800 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
1802 ProcessList
*process_list
=
1803 guicontrolflow_get_process_list(control_flow_data
);
1805 ClosureData closure_data
;
1806 closure_data
.events_request
= (EventsRequest
*)hook_data
;
1807 closure_data
.tss
= tss
;
1809 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
1810 (void*)&closure_data
);
1812 /* Request expose */
1813 drawing_data_request_end(events_request
, tss
);