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>
43 #include <lttvwindow/lttvwindowtraces.h>
46 #include "eventhooks.h"
48 #include "processlist.h"
50 #include "cfv-private.h"
53 #define MAX_PATH_LEN 256
56 /* Action to do when background computation completed.
58 * Eventually, will have to check that every requested traces are finished
59 * before doing the redraw.
62 gint
background_ready(void *hook_data
, void *call_data
)
64 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
65 LttvTrace
*trace
= (LttvTrace
*)call_data
;
67 g_debug("control flow viewer : background computation data ready.");
69 redraw_notify(control_flow_data
, NULL
);
75 /* Request background computation. Verify if it is in progress or ready first.
77 * Right now, for all loaded traces.
79 * Later : must be only for each trace in the tab's traceset.
81 void request_background_data(ControlFlowData
*control_flow_data
)
83 gint num_traces
= lttvwindowtraces_get_number();
87 LttvHooks
*background_ready_hook
=
89 lttv_hooks_add(background_ready_hook
, background_ready
, control_flow_data
,
92 for(i
=0;i
<num_traces
;i
++) {
93 trace
= lttvwindowtraces_get_trace(i
);
95 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace
)==FALSE
) {
97 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
99 /* We first remove requests that could have been done for the same
100 * information. Happens when two viewers ask for it before servicing
103 lttvwindowtraces_background_request_remove(trace
, "state");
104 lttvwindowtraces_background_request_queue(trace
,
106 lttvwindowtraces_background_notify_queue(control_flow_data
,
110 background_ready_hook
);
111 } else { /* in progress */
113 lttvwindowtraces_background_notify_current(control_flow_data
,
117 background_ready_hook
);
123 lttv_hooks_destroy(background_ready_hook
);
130 * Event Viewer's constructor hook
132 * This constructor is given as a parameter to the menuitem and toolbar button
133 * registration. It creates the list.
134 * @param tab A pointer to the parent tab.
135 * @return The widget created.
138 h_guicontrolflow(Tab
*tab
, LttvTracesetSelector
* s
, char * key
)
140 g_info("h_guicontrolflow, %p, %p, %s", tab
, s
, key
);
141 ControlFlowData
*control_flow_data
= guicontrolflow() ;
143 control_flow_data
->tab
= tab
;
145 //g_debug("time width2 : %u",time_window->time_width);
146 // Unreg done in the GuiControlFlow_Destructor
147 lttvwindow_register_traceset_notify(tab
,
151 lttvwindow_register_time_window_notify(tab
,
152 update_time_window_hook
,
154 lttvwindow_register_current_time_notify(tab
,
155 update_current_time_hook
,
157 lttvwindow_register_redraw_notify(tab
,
160 lttvwindow_register_continue_notify(tab
,
163 request_background_data(control_flow_data
);
166 return guicontrolflow_get_widget(control_flow_data
) ;
170 int event_selected_hook(void *hook_data
, void *call_data
)
172 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
173 guint
*event_number
= (guint
*) call_data
;
175 g_debug("DEBUG : event selected by main window : %u", *event_number
);
177 // control_flow_data->currently_Selected_Event = *event_number;
178 // control_flow_data->Selected_Event = TRUE ;
180 // tree_v_set_cursor(control_flow_data);
184 /* Hook called before drawing. Gets the initial context at the beginning of the
185 * drawing interval and copy it to the context in event_request.
187 int draw_before_hook(void *hook_data
, void *call_data
)
189 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
190 //EventsContext Events_Context = (EventsContext*)call_data;
192 //event_request->Events_Context = Events_Context;
198 * The draw event hook is called by the reading API to have a
199 * particular event drawn on the screen.
200 * @param hook_data ControlFlowData structure of the viewer.
201 * @param call_data Event context.
203 * This function basically draw lines and icons. Two types of lines are drawn :
204 * one small (3 pixels?) representing the state of the process and the second
205 * type is thicker (10 pixels?) representing on which CPU a process is running
206 * (and this only in running state).
208 * Extremums of the lines :
209 * x_min : time of the last event context for this process kept in memory.
210 * x_max : time of the current event.
211 * y : middle of the process in the process list. The process is found in the
212 * list, therefore is it's position in pixels.
214 * The choice of lines'color is defined by the context of the last event for this
217 int draw_event_hook(void *hook_data
, void *call_data
)
219 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
220 ControlFlowData
*control_flow_data
=
221 (ControlFlowData
*)events_request
->viewer_data
;
222 Tab
*tab
= control_flow_data
->tab
;
224 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
226 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
227 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
232 LttTime evtime
= ltt_event_time(e
);
233 TimeWindow time_window
=
234 lttvwindow_get_time_window(tab
);
236 LttTime end_time
= ltt_time_add(time_window
.start_time
,
237 time_window
.time_width
);
238 //if(time < time_beg || time > time_end) return;
239 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
240 || ltt_time_compare(evtime
, end_time
) == 1)
243 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
245 g_debug("schedchange!");
247 /* Add process to process list (if not present) and get drawing "y" from
248 * process position */
249 guint pid_out
, pid_in
;
250 LttvProcessState
*process_out
, *process_in
;
252 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
254 ProcessList
*process_list
=
255 guicontrolflow_get_process_list(control_flow_data
);
258 LttField
*f
= ltt_event_field(e
);
260 element
= ltt_field_member(f
,0);
261 pid_out
= ltt_event_get_long_unsigned(e
,element
);
262 element
= ltt_field_member(f
,1);
263 pid_in
= ltt_event_get_long_unsigned(e
,element
);
264 g_debug("out : %u in : %u", pid_out
, pid_in
);
267 /* Find process pid_out in the list... */
268 process_out
= lttv_state_find_process(tfs
, pid_out
);
269 if(process_out
== NULL
) return 0;
270 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
272 birth
= process_out
->creation_time
;
273 const gchar
*name
= g_quark_to_string(process_out
->name
);
274 HashedProcessData
*hashed_process_data_out
= NULL
;
276 if(processlist_get_process_pixels(process_list
,
279 tfc
->t_context
->index
,
282 &hashed_process_data_out
) == 1)
284 /* Process not present */
285 processlist_add(process_list
,
288 tfc
->t_context
->index
,
291 &hashed_process_data_out
);
292 g_assert(processlist_get_process_pixels(process_list
,
295 tfc
->t_context
->index
,
298 &hashed_process_data_out
)==0);
299 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
303 /* Find process pid_in in the list... */
304 process_in
= lttv_state_find_process(tfs
, pid_in
);
305 if(process_in
== NULL
) return 0;
306 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
308 birth
= process_in
->creation_time
;
309 name
= g_quark_to_string(process_in
->name
);
310 HashedProcessData
*hashed_process_data_in
= NULL
;
312 if(processlist_get_process_pixels(process_list
,
315 tfc
->t_context
->index
,
318 &hashed_process_data_in
) == 1)
320 /* Process not present */
321 processlist_add(process_list
,
324 tfc
->t_context
->index
,
327 &hashed_process_data_in
);
328 processlist_get_process_pixels(process_list
,
331 tfc
->t_context
->index
,
334 &hashed_process_data_in
);
336 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
341 /* Find pixels corresponding to time of the event. If the time does
342 * not fit in the window, show a warning, not supposed to happend. */
344 guint width
= control_flow_data
->drawing
->width
;
346 LttTime time
= ltt_event_time(e
);
348 LttTime window_end
= ltt_time_add(time_window
.time_width
,
349 time_window
.start_time
);
352 convert_time_to_pixels(
353 time_window
.start_time
,
358 //assert(x <= width);
360 /* draw what represents the event for outgoing process. */
362 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
363 draw_context_out
->current
->modify_over
->x
= x
;
364 draw_context_out
->current
->modify_under
->x
= x
;
365 draw_context_out
->current
->modify_over
->y
= y_out
;
366 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
367 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
368 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
369 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
370 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
371 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
372 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
373 //draw_context_out->gc = widget->style->black_gc;
375 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
376 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
378 /* Draw the line/background of the out process */
379 if(draw_context_out
->previous
->middle
->x
== -1)
381 draw_context_out
->previous
->over
->x
=
382 control_flow_data
->drawing
->damage_begin
;
383 draw_context_out
->previous
->middle
->x
=
384 control_flow_data
->drawing
->damage_begin
;
385 draw_context_out
->previous
->under
->x
=
386 control_flow_data
->drawing
->damage_begin
;
388 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
391 draw_context_out
->current
->middle
->x
= x
;
392 draw_context_out
->current
->over
->x
= x
;
393 draw_context_out
->current
->under
->x
= x
;
394 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
395 draw_context_out
->current
->over
->y
= y_out
;
396 draw_context_out
->current
->under
->y
= y_out
+ height
;
397 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
398 draw_context_out
->previous
->over
->y
= y_out
;
399 draw_context_out
->previous
->under
->y
= y_out
+ height
;
401 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
402 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
404 if(process_out
->state
->s
== LTTV_STATE_RUN
)
406 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
407 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
408 draw_context_out
->gc
= control_flow_data
->drawing
->gc
;
410 PropertiesBG prop_bg
;
411 prop_bg
.color
= g_new(GdkColor
,1);
415 prop_bg
.color
->red
= 0x1515;
416 prop_bg
.color
->green
= 0x1515;
417 prop_bg
.color
->blue
= 0x8c8c;
420 prop_bg
.color
->red
= 0x4e4e;
421 prop_bg
.color
->green
= 0xa9a9;
422 prop_bg
.color
->blue
= 0xa4a4;
425 prop_bg
.color
->red
= 0x7a7a;
426 prop_bg
.color
->green
= 0x4a4a;
427 prop_bg
.color
->blue
= 0x8b8b;
430 prop_bg
.color
->red
= 0x8080;
431 prop_bg
.color
->green
= 0x7777;
432 prop_bg
.color
->blue
= 0x4747;
435 prop_bg
.color
->red
= 0xe7e7;
436 prop_bg
.color
->green
= 0xe7e7;
437 prop_bg
.color
->blue
= 0xe7e7;
440 g_debug("calling from draw_event");
441 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
442 g_free(prop_bg
.color
);
443 //gdk_gc_unref(draw_context_out->gc);
446 draw_context_out
->gc
= widget
->style
->black_gc
;
448 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
449 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
450 PropertiesText prop_text_out
;
451 prop_text_out
.foreground
= &colorfg_out
;
452 prop_text_out
.background
= &colorbg_out
;
453 prop_text_out
.size
= 6;
454 prop_text_out
.position
= OVER
;
456 /* color of text : status of the process */
457 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
459 prop_text_out
.foreground
->red
= 0xffff;
460 prop_text_out
.foreground
->green
= 0xffff;
461 prop_text_out
.foreground
->blue
= 0xffff;
463 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
465 prop_text_out
.foreground
->red
= 0x0fff;
466 prop_text_out
.foreground
->green
= 0xffff;
467 prop_text_out
.foreground
->blue
= 0xfff0;
469 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
471 prop_text_out
.foreground
->red
= 0xffff;
472 prop_text_out
.foreground
->green
= 0xffff;
473 prop_text_out
.foreground
->blue
= 0x0000;
475 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
477 prop_text_out
.foreground
->red
= 0xffff;
478 prop_text_out
.foreground
->green
= 0x0000;
479 prop_text_out
.foreground
->blue
= 0xffff;
481 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
483 prop_text_out
.foreground
->red
= 0xffff;
484 prop_text_out
.foreground
->green
= 0x0000;
485 prop_text_out
.foreground
->blue
= 0x0000;
487 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
489 prop_text_out
.foreground
->red
= 0x0000;
490 prop_text_out
.foreground
->green
= 0xffff;
491 prop_text_out
.foreground
->blue
= 0x0000;
495 prop_text_out
.foreground
->red
= 0xffff;
496 prop_text_out
.foreground
->green
= 0xffff;
497 prop_text_out
.foreground
->blue
= 0xffff;
501 /* Print status of the process : U, WF, WC, E, W, R */
502 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
503 prop_text_out
.text
= "U->";
504 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
505 prop_text_out
.text
= "WF->";
506 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
507 prop_text_out
.text
= "WC->";
508 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
509 prop_text_out
.text
= "E->";
510 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
511 prop_text_out
.text
= "W->";
512 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
513 prop_text_out
.text
= "R->";
515 prop_text_out
.text
= "U";
517 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
518 //gdk_gc_unref(draw_context_out->gc);
520 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
521 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
522 draw_context_out
->gc
= control_flow_data
->drawing
->gc
;
524 PropertiesLine prop_line_out
;
525 prop_line_out
.color
= g_new(GdkColor
,1);
526 prop_line_out
.line_width
= 2;
527 prop_line_out
.style
= GDK_LINE_SOLID
;
528 prop_line_out
.position
= MIDDLE
;
530 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
532 /* color of line : status of the process */
533 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
535 prop_line_out
.color
->red
= 0xffff;
536 prop_line_out
.color
->green
= 0xffff;
537 prop_line_out
.color
->blue
= 0xffff;
539 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
541 prop_line_out
.color
->red
= 0x0fff;
542 prop_line_out
.color
->green
= 0xffff;
543 prop_line_out
.color
->blue
= 0xfff0;
545 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
547 prop_line_out
.color
->red
= 0xffff;
548 prop_line_out
.color
->green
= 0xffff;
549 prop_line_out
.color
->blue
= 0x0000;
551 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
553 prop_line_out
.color
->red
= 0xffff;
554 prop_line_out
.color
->green
= 0x0000;
555 prop_line_out
.color
->blue
= 0xffff;
557 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
559 prop_line_out
.color
->red
= 0xffff;
560 prop_line_out
.color
->green
= 0x0000;
561 prop_line_out
.color
->blue
= 0x0000;
563 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
565 prop_line_out
.color
->red
= 0x0000;
566 prop_line_out
.color
->green
= 0xffff;
567 prop_line_out
.color
->blue
= 0x0000;
571 prop_line_out
.color
->red
= 0xffff;
572 prop_line_out
.color
->green
= 0xffff;
573 prop_line_out
.color
->blue
= 0xffff;
576 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
577 g_free(prop_line_out
.color
);
578 //gdk_gc_unref(draw_context_out->gc);
579 /* Note : finishing line will have to be added when trace read over. */
581 /* Finally, update the drawing context of the pid_in. */
583 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
584 draw_context_in
->current
->modify_over
->x
= x
;
585 draw_context_in
->current
->modify_under
->x
= x
;
586 draw_context_in
->current
->modify_over
->y
= y_in
;
587 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
588 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
589 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
590 widget
= control_flow_data
->drawing
->drawing_area
;
591 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
592 //draw_context_in->gc = widget->style->black_gc;
593 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
594 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
596 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
597 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
599 /* Draw the line/bg of the in process */
600 if(draw_context_in
->previous
->middle
->x
== -1)
602 draw_context_in
->previous
->over
->x
=
603 control_flow_data
->drawing
->damage_begin
;
604 draw_context_in
->previous
->middle
->x
=
605 control_flow_data
->drawing
->damage_begin
;
606 draw_context_in
->previous
->under
->x
=
607 control_flow_data
->drawing
->damage_begin
;
609 g_debug("in middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
613 draw_context_in
->current
->middle
->x
= x
;
614 draw_context_in
->current
->over
->x
= x
;
615 draw_context_in
->current
->under
->x
= x
;
616 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
617 draw_context_in
->current
->over
->y
= y_in
;
618 draw_context_in
->current
->under
->y
= y_in
+ height
;
619 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
620 draw_context_in
->previous
->over
->y
= y_in
;
621 draw_context_in
->previous
->under
->y
= y_in
+ height
;
623 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
624 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
627 if(process_in
->state
->s
== LTTV_STATE_RUN
)
629 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
630 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
631 draw_context_in
->gc
= control_flow_data
->drawing
->gc
;
633 PropertiesBG prop_bg
;
634 prop_bg
.color
= g_new(GdkColor
,1);
638 prop_bg
.color
->red
= 0x1515;
639 prop_bg
.color
->green
= 0x1515;
640 prop_bg
.color
->blue
= 0x8c8c;
643 prop_bg
.color
->red
= 0x4e4e;
644 prop_bg
.color
->green
= 0xa9a9;
645 prop_bg
.color
->blue
= 0xa4a4;
648 prop_bg
.color
->red
= 0x7a7a;
649 prop_bg
.color
->green
= 0x4a4a;
650 prop_bg
.color
->blue
= 0x8b8b;
653 prop_bg
.color
->red
= 0x8080;
654 prop_bg
.color
->green
= 0x7777;
655 prop_bg
.color
->blue
= 0x4747;
658 prop_bg
.color
->red
= 0xe7e7;
659 prop_bg
.color
->green
= 0xe7e7;
660 prop_bg
.color
->blue
= 0xe7e7;
664 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
665 g_free(prop_bg
.color
);
666 //gdk_gc_unref(draw_context_in->gc);
669 draw_context_in
->gc
= widget
->style
->black_gc
;
671 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
672 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
673 PropertiesText prop_text_in
;
674 prop_text_in
.foreground
= &colorfg_in
;
675 prop_text_in
.background
= &colorbg_in
;
676 prop_text_in
.size
= 6;
677 prop_text_in
.position
= OVER
;
679 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
680 /* foreground of text : status of the process */
681 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
683 prop_text_in
.foreground
->red
= 0xffff;
684 prop_text_in
.foreground
->green
= 0xffff;
685 prop_text_in
.foreground
->blue
= 0xffff;
687 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
689 prop_text_in
.foreground
->red
= 0x0fff;
690 prop_text_in
.foreground
->green
= 0xffff;
691 prop_text_in
.foreground
->blue
= 0xfff0;
693 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
695 prop_text_in
.foreground
->red
= 0xffff;
696 prop_text_in
.foreground
->green
= 0xffff;
697 prop_text_in
.foreground
->blue
= 0x0000;
699 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
701 prop_text_in
.foreground
->red
= 0xffff;
702 prop_text_in
.foreground
->green
= 0x0000;
703 prop_text_in
.foreground
->blue
= 0xffff;
705 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
707 prop_text_in
.foreground
->red
= 0xffff;
708 prop_text_in
.foreground
->green
= 0x0000;
709 prop_text_in
.foreground
->blue
= 0x0000;
711 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
713 prop_text_in
.foreground
->red
= 0x0000;
714 prop_text_in
.foreground
->green
= 0xffff;
715 prop_text_in
.foreground
->blue
= 0x0000;
719 prop_text_in
.foreground
->red
= 0xffff;
720 prop_text_in
.foreground
->green
= 0xffff;
721 prop_text_in
.foreground
->blue
= 0xffff;
726 /* Print status of the process : U, WF, WC, E, W, R */
727 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
728 prop_text_in
.text
= "U->";
729 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
730 prop_text_in
.text
= "WF->";
731 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
732 prop_text_in
.text
= "WC->";
733 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
734 prop_text_in
.text
= "E->";
735 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
736 prop_text_in
.text
= "W->";
737 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
738 prop_text_in
.text
= "R->";
740 prop_text_in
.text
= "U";
742 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
743 //gdk_gc_unref(draw_context_in->gc);
745 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
746 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
747 draw_context_in
->gc
= control_flow_data
->drawing
->gc
;
749 PropertiesLine prop_line_in
;
750 prop_line_in
.color
= g_new(GdkColor
,1);
751 prop_line_in
.line_width
= 2;
752 prop_line_in
.style
= GDK_LINE_SOLID
;
753 prop_line_in
.position
= MIDDLE
;
755 /* color of line : status of the process */
756 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
758 prop_line_in
.color
->red
= 0xffff;
759 prop_line_in
.color
->green
= 0xffff;
760 prop_line_in
.color
->blue
= 0xffff;
762 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
764 prop_line_in
.color
->red
= 0x0fff;
765 prop_line_in
.color
->green
= 0xffff;
766 prop_line_in
.color
->blue
= 0xfff0;
768 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
770 prop_line_in
.color
->red
= 0xffff;
771 prop_line_in
.color
->green
= 0xffff;
772 prop_line_in
.color
->blue
= 0x0000;
774 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
776 prop_line_in
.color
->red
= 0xffff;
777 prop_line_in
.color
->green
= 0x0000;
778 prop_line_in
.color
->blue
= 0xffff;
780 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
782 prop_line_in
.color
->red
= 0xffff;
783 prop_line_in
.color
->green
= 0x0000;
784 prop_line_in
.color
->blue
= 0x0000;
786 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
788 prop_line_in
.color
->red
= 0x0000;
789 prop_line_in
.color
->green
= 0xffff;
790 prop_line_in
.color
->blue
= 0x0000;
794 prop_line_in
.color
->red
= 0xffff;
795 prop_line_in
.color
->green
= 0xffff;
796 prop_line_in
.color
->blue
= 0xffff;
799 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
800 g_free(prop_line_in
.color
);
801 //gdk_gc_unref(draw_context_in->gc);
808 GString
*string
= g_string_new("");;
809 gboolean field_names
= TRUE
, state
= TRUE
;
811 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
812 g_string_append_printf(string
,"\n");
815 g_string_append_printf(string
, " %s",
816 g_quark_to_string(tfs
->process
->state
->s
));
819 g_info("%s",string
->str
);
821 g_string_free(string
, TRUE
);
823 /* End of text dump */
829 int draw_after_hook(void *hook_data
, void *call_data
)
831 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
832 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
834 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
836 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
837 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
843 LttTime evtime
= ltt_event_time(e
);
844 TimeWindow time_window
=
845 lttvwindow_get_time_window(control_flow_data
->tab
);
847 LttTime end_time
= ltt_time_add(time_window
.start_time
,
848 time_window
.time_width
);
849 //if(time < time_beg || time > time_end) return;
850 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
851 || ltt_time_compare(evtime
, end_time
) == 1)
855 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
857 g_debug("schedchange!");
859 /* Add process to process list (if not present) and get drawing "y" from
860 * process position */
861 guint pid_out
, pid_in
;
862 LttvProcessState
*process_out
, *process_in
;
864 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
866 ProcessList
*process_list
=
867 guicontrolflow_get_process_list(control_flow_data
);
870 LttField
*f
= ltt_event_field(e
);
872 element
= ltt_field_member(f
,0);
873 pid_out
= ltt_event_get_long_unsigned(e
,element
);
874 element
= ltt_field_member(f
,1);
875 pid_in
= ltt_event_get_long_unsigned(e
,element
);
876 //g_debug("out : %u in : %u", pid_out, pid_in);
879 /* Find process pid_out in the list... */
880 process_out
= lttv_state_find_process(tfs
, pid_out
);
881 if(process_out
== NULL
) return 0;
882 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
884 birth
= process_out
->creation_time
;
885 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
886 HashedProcessData
*hashed_process_data_out
= NULL
;
888 if(processlist_get_process_pixels(process_list
,
891 tfc
->t_context
->index
,
894 &hashed_process_data_out
) == 1)
896 /* Process not present */
897 processlist_add(process_list
,
900 tfc
->t_context
->index
,
903 &hashed_process_data_out
);
904 processlist_get_process_pixels(process_list
,
907 tfc
->t_context
->index
,
910 &hashed_process_data_out
);
911 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
916 /* Find process pid_in in the list... */
917 process_in
= lttv_state_find_process(tfs
, pid_in
);
918 if(process_in
== NULL
) return 0;
919 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
921 birth
= process_in
->creation_time
;
922 name
= strdup(g_quark_to_string(process_in
->name
));
923 HashedProcessData
*hashed_process_data_in
= NULL
;
925 if(processlist_get_process_pixels(process_list
,
928 tfc
->t_context
->index
,
931 &hashed_process_data_in
) == 1)
933 /* Process not present */
934 processlist_add(process_list
,
937 tfc
->t_context
->index
,
940 &hashed_process_data_in
);
941 processlist_get_process_pixels(process_list
,
944 tfc
->t_context
->index
,
947 &hashed_process_data_in
);
949 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
954 /* Find pixels corresponding to time of the event. If the time does
955 * not fit in the window, show a warning, not supposed to happend. */
957 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
959 //LttTime time = ltt_event_time(e);
961 //LttTime window_end = ltt_time_add(time_window->time_width,
962 // time_window->start_time);
965 //convert_time_to_pixels(
966 // time_window->start_time,
972 //assert(x <= width);
974 /* draw what represents the event for outgoing process. */
976 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
977 //draw_context_out->current->modify_over->x = x;
978 draw_context_out
->current
->modify_over
->y
= y_out
;
979 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
980 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
981 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
982 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
983 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
985 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
986 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
988 /*if(process_out->state->s == LTTV_STATE_RUN)
990 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
991 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
992 PropertiesBG prop_bg;
993 prop_bg.color = g_new(GdkColor,1);
995 prop_bg.color->red = 0xffff;
996 prop_bg.color->green = 0xffff;
997 prop_bg.color->blue = 0xffff;
999 draw_bg((void*)&prop_bg, (void*)draw_context_out);
1000 g_free(prop_bg.color);
1001 gdk_gc_unref(draw_context_out->gc);
1004 draw_context_out
->gc
= widget
->style
->black_gc
;
1006 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
1007 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
1008 PropertiesText prop_text_out
;
1009 prop_text_out
.foreground
= &colorfg_out
;
1010 prop_text_out
.background
= &colorbg_out
;
1011 prop_text_out
.size
= 6;
1012 prop_text_out
.position
= OVER
;
1014 /* color of text : status of the process */
1015 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1017 prop_text_out
.foreground
->red
= 0xffff;
1018 prop_text_out
.foreground
->green
= 0xffff;
1019 prop_text_out
.foreground
->blue
= 0xffff;
1021 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1023 prop_text_out
.foreground
->red
= 0x0fff;
1024 prop_text_out
.foreground
->green
= 0xffff;
1025 prop_text_out
.foreground
->blue
= 0xfff0;
1027 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1029 prop_text_out
.foreground
->red
= 0xffff;
1030 prop_text_out
.foreground
->green
= 0xffff;
1031 prop_text_out
.foreground
->blue
= 0x0000;
1033 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1035 prop_text_out
.foreground
->red
= 0xffff;
1036 prop_text_out
.foreground
->green
= 0x0000;
1037 prop_text_out
.foreground
->blue
= 0xffff;
1039 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1041 prop_text_out
.foreground
->red
= 0xffff;
1042 prop_text_out
.foreground
->green
= 0x0000;
1043 prop_text_out
.foreground
->blue
= 0x0000;
1045 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1047 prop_text_out
.foreground
->red
= 0x0000;
1048 prop_text_out
.foreground
->green
= 0xffff;
1049 prop_text_out
.foreground
->blue
= 0x0000;
1053 prop_text_out
.foreground
->red
= 0xffff;
1054 prop_text_out
.foreground
->green
= 0xffff;
1055 prop_text_out
.foreground
->blue
= 0xffff;
1058 /* Print status of the process : U, WF, WC, E, W, R */
1059 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1060 prop_text_out
.text
= "U";
1061 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1062 prop_text_out
.text
= "WF";
1063 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1064 prop_text_out
.text
= "WC";
1065 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1066 prop_text_out
.text
= "E";
1067 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1068 prop_text_out
.text
= "W";
1069 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1070 prop_text_out
.text
= "R";
1072 prop_text_out
.text
= "U";
1074 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
1076 //gdk_gc_unref(draw_context_out->gc);
1078 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
1079 draw_context_out
->current
->over
->y
= y_out
;
1080 draw_context_out
->current
->under
->y
= y_out
+height
;
1081 draw_context_out
->current
->status
= process_out
->state
->s
;
1083 /* for pid_out : remove previous, Prev = current, new current (default) */
1084 g_free(draw_context_out
->previous
->modify_under
);
1085 g_free(draw_context_out
->previous
->modify_middle
);
1086 g_free(draw_context_out
->previous
->modify_over
);
1087 g_free(draw_context_out
->previous
->under
);
1088 g_free(draw_context_out
->previous
->middle
);
1089 g_free(draw_context_out
->previous
->over
);
1090 g_free(draw_context_out
->previous
);
1092 draw_context_out
->previous
= draw_context_out
->current
;
1094 draw_context_out
->current
= g_new(DrawInfo
,1);
1095 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
1096 draw_context_out
->current
->over
->x
= -1;
1097 draw_context_out
->current
->over
->y
= -1;
1098 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1099 draw_context_out
->current
->middle
->x
= -1;
1100 draw_context_out
->current
->middle
->y
= -1;
1101 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1102 draw_context_out
->current
->under
->x
= -1;
1103 draw_context_out
->current
->under
->y
= -1;
1104 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1105 draw_context_out
->current
->modify_over
->x
= -1;
1106 draw_context_out
->current
->modify_over
->y
= -1;
1107 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1108 draw_context_out
->current
->modify_middle
->x
= -1;
1109 draw_context_out
->current
->modify_middle
->y
= -1;
1110 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1111 draw_context_out
->current
->modify_under
->x
= -1;
1112 draw_context_out
->current
->modify_under
->y
= -1;
1113 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1115 /* Finally, update the drawing context of the pid_in. */
1117 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1118 //draw_context_in->current->modify_over->x = x;
1119 draw_context_in
->current
->modify_over
->y
= y_in
;
1120 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1121 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1122 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1123 widget
= control_flow_data
->drawing
->drawing_area
;
1124 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1126 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1127 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1129 /*if(process_in->state->s == LTTV_STATE_RUN)
1131 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1132 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1133 PropertiesBG prop_bg;
1134 prop_bg.color = g_new(GdkColor,1);
1136 prop_bg.color->red = 0xffff;
1137 prop_bg.color->green = 0xffff;
1138 prop_bg.color->blue = 0xffff;
1140 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1141 g_free(prop_bg.color);
1142 gdk_gc_unref(draw_context_in->gc);
1145 draw_context_in
->gc
= widget
->style
->black_gc
;
1147 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1148 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1149 PropertiesText prop_text_in
;
1150 prop_text_in
.foreground
= &colorfg_in
;
1151 prop_text_in
.background
= &colorbg_in
;
1152 prop_text_in
.size
= 6;
1153 prop_text_in
.position
= OVER
;
1155 /* foreground of text : status of the process */
1156 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1158 prop_text_in
.foreground
->red
= 0xffff;
1159 prop_text_in
.foreground
->green
= 0xffff;
1160 prop_text_in
.foreground
->blue
= 0xffff;
1162 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1164 prop_text_in
.foreground
->red
= 0x0fff;
1165 prop_text_in
.foreground
->green
= 0xffff;
1166 prop_text_in
.foreground
->blue
= 0xfff0;
1168 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1170 prop_text_in
.foreground
->red
= 0xffff;
1171 prop_text_in
.foreground
->green
= 0xffff;
1172 prop_text_in
.foreground
->blue
= 0x0000;
1174 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1176 prop_text_in
.foreground
->red
= 0xffff;
1177 prop_text_in
.foreground
->green
= 0x0000;
1178 prop_text_in
.foreground
->blue
= 0xffff;
1180 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1182 prop_text_in
.foreground
->red
= 0xffff;
1183 prop_text_in
.foreground
->green
= 0x0000;
1184 prop_text_in
.foreground
->blue
= 0x0000;
1186 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1188 prop_text_in
.foreground
->red
= 0x0000;
1189 prop_text_in
.foreground
->green
= 0xffff;
1190 prop_text_in
.foreground
->blue
= 0x0000;
1194 prop_text_in
.foreground
->red
= 0xffff;
1195 prop_text_in
.foreground
->green
= 0xffff;
1196 prop_text_in
.foreground
->blue
= 0xffff;
1200 /* Print status of the process : U, WF, WC, E, W, R */
1201 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1202 prop_text_in
.text
= "U";
1203 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1204 prop_text_in
.text
= "WF";
1205 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1206 prop_text_in
.text
= "WC";
1207 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1208 prop_text_in
.text
= "E";
1209 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1210 prop_text_in
.text
= "W";
1211 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1212 prop_text_in
.text
= "R";
1214 prop_text_in
.text
= "U";
1216 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1219 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1222 prop_text_in
.foreground
= &colorfg_in
;
1223 prop_text_in
.background
= &colorbg_in
;
1224 prop_text_in
.foreground
->red
= 0xffff;
1225 prop_text_in
.foreground
->green
= 0xffff;
1226 prop_text_in
.foreground
->blue
= 0xffff;
1227 prop_text_in
.size
= 6;
1228 prop_text_in
.position
= UNDER
;
1230 prop_text_in
.text
= g_new(gchar
, 260);
1231 strcpy(prop_text_in
.text
, "CPU ");
1232 snprintf(tmp
, 255, "%u", tfc
->index
);
1233 strcat(prop_text_in
.text
, tmp
);
1235 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1236 g_free(prop_text_in
.text
);
1240 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1241 draw_context_in
->current
->over
->y
= y_in
;
1242 draw_context_in
->current
->under
->y
= y_in
+height
;
1243 draw_context_in
->current
->status
= process_in
->state
->s
;
1245 /* for pid_in : remove previous, Prev = current, new current (default) */
1246 g_free(draw_context_in
->previous
->modify_under
);
1247 g_free(draw_context_in
->previous
->modify_middle
);
1248 g_free(draw_context_in
->previous
->modify_over
);
1249 g_free(draw_context_in
->previous
->under
);
1250 g_free(draw_context_in
->previous
->middle
);
1251 g_free(draw_context_in
->previous
->over
);
1252 g_free(draw_context_in
->previous
);
1254 draw_context_in
->previous
= draw_context_in
->current
;
1256 draw_context_in
->current
= g_new(DrawInfo
,1);
1257 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1258 draw_context_in
->current
->over
->x
= -1;
1259 draw_context_in
->current
->over
->y
= -1;
1260 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1261 draw_context_in
->current
->middle
->x
= -1;
1262 draw_context_in
->current
->middle
->y
= -1;
1263 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1264 draw_context_in
->current
->under
->x
= -1;
1265 draw_context_in
->current
->under
->y
= -1;
1266 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1267 draw_context_in
->current
->modify_over
->x
= -1;
1268 draw_context_in
->current
->modify_over
->y
= -1;
1269 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1270 draw_context_in
->current
->modify_middle
->x
= -1;
1271 draw_context_in
->current
->modify_middle
->y
= -1;
1272 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1273 draw_context_in
->current
->modify_under
->x
= -1;
1274 draw_context_in
->current
->modify_under
->y
= -1;
1275 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1285 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1287 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1288 Drawing_t
*drawing
= control_flow_data
->drawing
;
1290 const TimeWindowNotifyData
*time_window_nofify_data
=
1291 ((const TimeWindowNotifyData
*)call_data
);
1293 TimeWindow
*old_time_window
=
1294 time_window_nofify_data
->old_time_window
;
1295 TimeWindow
*new_time_window
=
1296 time_window_nofify_data
->new_time_window
;
1298 /* Update the ruler */
1299 drawing_update_ruler(control_flow_data
->drawing
,
1303 /* Two cases : zoom in/out or scrolling */
1305 /* In order to make sure we can reuse the old drawing, the scale must
1306 * be the same and the new time interval being partly located in the
1307 * currently shown time interval. (reuse is only for scrolling)
1310 g_info("Old time window HOOK : %u, %u to %u, %u",
1311 old_time_window
->start_time
.tv_sec
,
1312 old_time_window
->start_time
.tv_nsec
,
1313 old_time_window
->time_width
.tv_sec
,
1314 old_time_window
->time_width
.tv_nsec
);
1316 g_info("New time window HOOK : %u, %u to %u, %u",
1317 new_time_window
->start_time
.tv_sec
,
1318 new_time_window
->start_time
.tv_nsec
,
1319 new_time_window
->time_width
.tv_sec
,
1320 new_time_window
->time_width
.tv_nsec
);
1322 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1323 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1325 /* Same scale (scrolling) */
1326 g_info("scrolling");
1327 LttTime
*ns
= &new_time_window
->start_time
;
1328 LttTime
*os
= &old_time_window
->start_time
;
1329 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1330 old_time_window
->time_width
);
1331 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1332 new_time_window
->time_width
);
1334 //if(ns<os+w && os+w<ns+w)
1335 //if(ns<old_end && os<ns)
1336 if(ltt_time_compare(*ns
, old_end
) == -1
1337 && ltt_time_compare(*os
, *ns
) == -1)
1339 g_info("scrolling near right");
1340 /* Scroll right, keep right part of the screen */
1342 guint width
= control_flow_data
->drawing
->width
;
1343 convert_time_to_pixels(
1350 /* Copy old data to new location */
1351 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1352 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1353 control_flow_data
->drawing
->pixmap
,
1356 control_flow_data
->drawing
->width
-x
+SAFETY
, -1);
1358 if(drawing
->damage_begin
== drawing
->damage_end
)
1359 drawing
->damage_begin
= control_flow_data
->drawing
->width
-x
;
1361 drawing
->damage_begin
= 0;
1363 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1365 /* Clear the data request background, but not SAFETY */
1366 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1367 //control_flow_data->drawing->drawing_area->style->black_gc,
1368 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1370 drawing
->damage_begin
+SAFETY
, 0,
1371 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1372 control_flow_data
->drawing
->height
);
1374 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1376 control_flow_data
->drawing
->width
,
1377 control_flow_data
->drawing
->height
);
1379 /* Get new data for the rest. */
1380 drawing_data_request(control_flow_data
->drawing
,
1381 &control_flow_data
->drawing
->pixmap
,
1382 drawing
->damage_begin
, 0,
1383 drawing
->damage_end
- drawing
->damage_begin
,
1384 control_flow_data
->drawing
->height
);
1387 //if(ns<os && os<ns+w)
1388 //if(ns<os && os<new_end)
1389 if(ltt_time_compare(*ns
,*os
) == -1
1390 && ltt_time_compare(*os
,new_end
) == -1)
1392 g_info("scrolling near left");
1393 /* Scroll left, keep left part of the screen */
1395 guint width
= control_flow_data
->drawing
->width
;
1396 convert_time_to_pixels(
1404 /* Copy old data to new location */
1405 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1406 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1407 control_flow_data
->drawing
->pixmap
,
1412 if(drawing
->damage_begin
== drawing
->damage_end
)
1413 drawing
->damage_end
= x
;
1415 drawing
->damage_end
=
1416 control_flow_data
->drawing
->width
;
1418 drawing
->damage_begin
= 0;
1420 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1421 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1423 drawing
->damage_begin
, 0,
1424 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1425 control_flow_data
->drawing
->height
);
1427 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1429 control_flow_data
->drawing
->width
,
1430 control_flow_data
->drawing
->height
);
1433 /* Get new data for the rest. */
1434 drawing_data_request(control_flow_data
->drawing
,
1435 &control_flow_data
->drawing
->pixmap
,
1436 drawing
->damage_begin
, 0,
1437 drawing
->damage_end
- drawing
->damage_begin
,
1438 control_flow_data
->drawing
->height
);
1441 if(ltt_time_compare(*ns
,*os
) == 0)
1443 g_info("not scrolling");
1445 g_info("scrolling far");
1446 /* Cannot reuse any part of the screen : far jump */
1449 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1450 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1453 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1454 control_flow_data
->drawing
->height
);
1456 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1458 control_flow_data
->drawing
->width
,
1459 control_flow_data
->drawing
->height
);
1461 drawing
->damage_begin
= 0;
1462 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1464 drawing_data_request(control_flow_data
->drawing
,
1465 &control_flow_data
->drawing
->pixmap
,
1467 control_flow_data
->drawing
->width
,
1468 control_flow_data
->drawing
->height
);
1474 /* Different scale (zoom) */
1477 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1478 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1481 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1482 control_flow_data
->drawing
->height
);
1484 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1486 control_flow_data
->drawing
->width
,
1487 control_flow_data
->drawing
->height
);
1489 drawing
->damage_begin
= 0;
1490 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1492 drawing_data_request(control_flow_data
->drawing
,
1493 &control_flow_data
->drawing
->pixmap
,
1495 control_flow_data
->drawing
->width
,
1496 control_flow_data
->drawing
->height
);
1504 gint
traceset_notify(void *hook_data
, void *call_data
)
1506 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1507 Drawing_t
*drawing
= control_flow_data
->drawing
;
1508 GtkWidget
*widget
= drawing
->drawing_area
;
1510 drawing
->damage_begin
= 0;
1511 drawing
->damage_end
= drawing
->width
;
1515 gdk_draw_rectangle (drawing
->pixmap
,
1516 widget
->style
->black_gc
,
1519 drawing
->width
+SAFETY
,
1523 if(drawing
->damage_begin
< drawing
->damage_end
)
1525 drawing_data_request(drawing
,
1527 drawing
->damage_begin
,
1529 drawing
->damage_end
-drawing
->damage_begin
,
1533 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1538 request_background_data(control_flow_data
);
1543 gint
redraw_notify(void *hook_data
, void *call_data
)
1545 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1546 Drawing_t
*drawing
= control_flow_data
->drawing
;
1547 GtkWidget
*widget
= drawing
->drawing_area
;
1549 drawing
->damage_begin
= 0;
1550 drawing
->damage_end
= drawing
->width
;
1554 gdk_draw_rectangle (drawing
->pixmap
,
1555 widget
->style
->black_gc
,
1558 drawing
->width
+SAFETY
,
1562 if(drawing
->damage_begin
< drawing
->damage_end
)
1564 drawing_data_request(drawing
,
1566 drawing
->damage_begin
,
1568 drawing
->damage_end
-drawing
->damage_begin
,
1572 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1582 gint
continue_notify(void *hook_data
, void *call_data
)
1584 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1585 Drawing_t
*drawing
= control_flow_data
->drawing
;
1586 GtkWidget
*widget
= drawing
->drawing_area
;
1588 //g_assert(widget->allocation.width == drawing->damage_end);
1590 if(drawing
->damage_begin
< drawing
->damage_end
)
1592 drawing_data_request(drawing
,
1594 drawing
->damage_begin
,
1596 drawing
->damage_end
-drawing
->damage_begin
,
1604 gint
after_process_traceset_hook(void *hook_data
, void *call_data
)
1606 //ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1607 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1609 ControlFlowData
*control_flow_data
=
1610 (ControlFlowData
*)events_request
->viewer_data
;
1613 drawing_data_request_end(events_request
,
1614 (LttvTracesetState
*)call_data
);
1620 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1622 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1623 Drawing_t
*drawing
= control_flow_data
->drawing
;
1625 LttTime current_time
= *((LttTime
*)call_data
);
1627 TimeWindow time_window
=
1628 lttvwindow_get_time_window(control_flow_data
->tab
);
1630 LttTime time_begin
= time_window
.start_time
;
1631 LttTime width
= time_window
.time_width
;
1632 LttTime half_width
= ltt_time_div(width
,2.0);
1633 LttTime time_end
= ltt_time_add(time_begin
, width
);
1635 LttvTracesetContext
* tsc
=
1636 lttvwindow_get_traceset_context(control_flow_data
->tab
);
1638 LttTime trace_start
= tsc
->time_span
.start_time
;
1639 LttTime trace_end
= tsc
->time_span
.end_time
;
1641 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
1642 current_time
.tv_nsec
);
1646 /* If current time is inside time interval, just move the highlight
1649 /* Else, we have to change the time interval. We have to tell it
1650 * to the main window. */
1651 /* The time interval change will take care of placing the current
1652 * time at the center of the visible area, or nearest possible if we are
1653 * at one end of the trace. */
1656 if(ltt_time_compare(current_time
, time_begin
) == -1)
1658 TimeWindow new_time_window
;
1660 if(ltt_time_compare(current_time
,
1661 ltt_time_add(trace_start
,half_width
)) == -1)
1662 time_begin
= trace_start
;
1664 time_begin
= ltt_time_sub(current_time
,half_width
);
1666 new_time_window
.start_time
= time_begin
;
1667 new_time_window
.time_width
= width
;
1669 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1671 else if(ltt_time_compare(current_time
, time_end
) == 1)
1673 TimeWindow new_time_window
;
1675 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1676 time_begin
= ltt_time_sub(trace_end
,width
);
1678 time_begin
= ltt_time_sub(current_time
,half_width
);
1680 new_time_window
.start_time
= time_begin
;
1681 new_time_window
.time_width
= width
;
1683 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1686 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1687 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1695 typedef struct _ClosureData
{
1696 EventsRequest
*events_request
;
1697 LttvTracesetState
*tss
;
1701 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1703 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1704 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1705 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1707 ControlFlowData
*control_flow_data
=
1708 closure_data
->events_request
->viewer_data
;
1710 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1712 /* Get y position of process */
1715 processlist_get_pixels_from_data( control_flow_data
->process_list
,
1717 hashed_process_data
,
1720 /* Get last state of process */
1721 LttvTraceContext
*tc
=
1722 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
1723 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)closure_data
->tss
;
1725 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
1726 LttvProcessState
*process
;
1728 /* We do not provide a cpu_name argument assuming that this is not the
1729 idle job (pid 0) and thus its pid is unique across all cpus */
1730 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
1732 /* Draw the closing line */
1733 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
1734 if(draw_context
->previous
->middle
->x
== -1)
1736 draw_context
->previous
->over
->x
=
1737 control_flow_data
->drawing
->damage_begin
;
1738 draw_context
->previous
->middle
->x
=
1739 control_flow_data
->drawing
->damage_begin
;
1740 draw_context
->previous
->under
->x
=
1741 control_flow_data
->drawing
->damage_begin
;
1743 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
1746 /* Find pixels corresponding to current time . If the time does
1747 * not fit in the window, show a warning, not supposed to happend. */
1749 guint width
= control_flow_data
->drawing
->width
;
1751 TimeWindow time_window
=
1752 lttvwindow_get_time_window(control_flow_data
->tab
);
1754 LttTime time
= lttv_traceset_context_get_current_tfc(tsc
)->timestamp
;
1756 LttTime window_end
= ltt_time_add(time_window
.time_width
,
1757 time_window
.start_time
);
1759 convert_time_to_pixels(
1760 time_window
.start_time
,
1766 draw_context
->current
->middle
->x
= x
;
1767 draw_context
->current
->over
->x
= x
;
1768 draw_context
->current
->under
->x
= x
;
1769 draw_context
->current
->middle
->y
= y
+ height
/2;
1770 draw_context
->current
->over
->y
= y
;
1771 draw_context
->current
->under
->y
= y
+ height
;
1772 draw_context
->previous
->middle
->y
= y
+ height
/2;
1773 draw_context
->previous
->over
->y
= y
;
1774 draw_context
->previous
->under
->y
= y
+ height
;
1775 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
1776 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1777 //draw_context->gc = widget->style->black_gc;
1778 //draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1779 //gdk_gc_copy(draw_context->gc, widget->style->black_gc);
1780 draw_context
->gc
= control_flow_data
->drawing
->gc
;
1782 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
1784 PropertiesBG prop_bg
;
1785 prop_bg
.color
= g_new(GdkColor
,1);
1787 /*switch(tfc->index) {
1789 prop_bg.color->red = 0x1515;
1790 prop_bg.color->green = 0x1515;
1791 prop_bg.color->blue = 0x8c8c;
1794 prop_bg.color->red = 0x4e4e;
1795 prop_bg.color->green = 0xa9a9;
1796 prop_bg.color->blue = 0xa4a4;
1799 prop_bg.color->red = 0x7a7a;
1800 prop_bg.color->green = 0x4a4a;
1801 prop_bg.color->blue = 0x8b8b;
1804 prop_bg.color->red = 0x8080;
1805 prop_bg.color->green = 0x7777;
1806 prop_bg.color->blue = 0x4747;
1809 prop_bg.color->red = 0xe7e7;
1810 prop_bg.color->green = 0xe7e7;
1811 prop_bg.color->blue = 0xe7e7;
1815 g_debug("calling from closure");
1816 //FIXME : I need the cpu number in process's state to draw this.
1817 //draw_bg((void*)&prop_bg, (void*)draw_context);
1818 g_free(prop_bg
.color
);
1822 PropertiesLine prop_line
;
1823 prop_line
.color
= g_new(GdkColor
,1);
1824 prop_line
.line_width
= 2;
1825 prop_line
.style
= GDK_LINE_SOLID
;
1826 prop_line
.position
= MIDDLE
;
1828 /* color of line : status of the process */
1831 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
1833 prop_line
.color
->red
= 0xffff;
1834 prop_line
.color
->green
= 0xffff;
1835 prop_line
.color
->blue
= 0xffff;
1837 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
1839 prop_line
.color
->red
= 0x0fff;
1840 prop_line
.color
->green
= 0xffff;
1841 prop_line
.color
->blue
= 0xfff0;
1843 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
1845 prop_line
.color
->red
= 0xffff;
1846 prop_line
.color
->green
= 0xffff;
1847 prop_line
.color
->blue
= 0x0000;
1849 else if(process
->state
->s
== LTTV_STATE_EXIT
)
1851 prop_line
.color
->red
= 0xffff;
1852 prop_line
.color
->green
= 0x0000;
1853 prop_line
.color
->blue
= 0xffff;
1855 else if(process
->state
->s
== LTTV_STATE_WAIT
)
1857 prop_line
.color
->red
= 0xffff;
1858 prop_line
.color
->green
= 0x0000;
1859 prop_line
.color
->blue
= 0x0000;
1861 else if(process
->state
->s
== LTTV_STATE_RUN
)
1863 prop_line
.color
->red
= 0x0000;
1864 prop_line
.color
->green
= 0xffff;
1865 prop_line
.color
->blue
= 0x0000;
1869 prop_line
.color
->red
= 0xffff;
1870 prop_line
.color
->green
= 0xffff;
1871 prop_line
.color
->blue
= 0xffff;
1877 prop_line
.color
->red
= 0xffff;
1878 prop_line
.color
->green
= 0xffff;
1879 prop_line
.color
->blue
= 0xffff;
1882 draw_line((void*)&prop_line
, (void*)draw_context
);
1883 g_free(prop_line
.color
);
1884 //gdk_gc_unref(draw_context->gc);
1886 /* Reset draw_context of the process for next request */
1888 hashed_process_data
->draw_context
->drawable
= NULL
;
1889 hashed_process_data
->draw_context
->gc
= NULL
;
1890 hashed_process_data
->draw_context
->pango_layout
= NULL
;
1891 hashed_process_data
->draw_context
->current
->over
->x
= -1;
1892 hashed_process_data
->draw_context
->current
->over
->y
= -1;
1893 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
1894 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
1895 hashed_process_data
->draw_context
->current
->under
->x
= -1;
1896 hashed_process_data
->draw_context
->current
->under
->y
= -1;
1897 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
1898 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
1899 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
1900 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
1901 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
1902 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
1903 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
1904 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
1905 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
1906 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
1907 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
1908 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
1909 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
1910 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
1911 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
1912 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
1913 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
1914 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
1915 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
1916 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
1920 int before_data_request(void *hook_data
, void *call_data
)
1922 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1923 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
1925 drawing_data_request_begin(events_request
, tss
);
1934 * new default prev and current
1935 * then finally remove reading hooks.
1937 int after_data_request(void *hook_data
, void *call_data
)
1939 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1940 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1941 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
1943 ProcessList
*process_list
=
1944 guicontrolflow_get_process_list(control_flow_data
);
1946 ClosureData closure_data
;
1947 closure_data
.events_request
= (EventsRequest
*)hook_data
;
1948 closure_data
.tss
= tss
;
1950 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
1951 (void*)&closure_data
);
1953 /* Request expose */
1954 drawing_data_request_end(events_request
, tss
);