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 /* Event hooks are the drawing hooks called during traceset read. They draw the
26 * icons, text, lines and background color corresponding to the events read.
28 * Two hooks are used for drawing : draw_before and draw_after hooks. The
29 * draw_before is called before the state update that occurs with an event and
30 * the draw_after hook is called after this state update.
32 * The draw_before hooks fulfill the task of drawing the visible objects that
33 * corresponds to the data accumulated by the draw_after hook.
35 * The draw_after hook accumulates the data that need to be shown on the screen
36 * (items) into a queue. Then, the next draw_before hook will draw what that
37 * queue contains. That's the Right Way (TM) of drawing items on the screen,
38 * because we need to draw the background first (and then add icons, text, ...
39 * over it), but we only know the length of a background region once the state
40 * corresponding to it is over, which happens to be at the next draw_before
43 * We also have a hook called at the end of a chunk to draw the information left
44 * undrawn in each process queue. We use the current time as end of
49 //#define PANGO_ENABLE_BACKEND
57 //#include <pango/pango.h>
59 #include <ltt/event.h>
63 #include <lttv/lttv.h>
64 #include <lttv/hook.h>
65 #include <lttv/state.h>
66 #include <lttvwindow/lttvwindow.h>
67 #include <lttvwindow/lttvwindowtraces.h>
70 #include "eventhooks.h"
72 #include "processlist.h"
74 #include "cfv-private.h"
77 #define MAX_PATH_LEN 256
81 typedef struct _ProcessAddClosure
{
86 static void process_add(gpointer key
,
90 LttvProcessState
*process
= (LttvProcessState
*)value
;
91 ProcessAddClosure
*closure
= (ProcessAddClosure
*)user_data
;
92 ControlFlowData
*control_flow_data
= closure
->cfd
;
93 guint trace_num
= closure
->trace_num
;
95 /* Add process to process list (if not present) */
98 guint y
= 0, height
= 0, pl_height
= 0;
100 ProcessList
*process_list
=
101 guicontrolflow_get_process_list(control_flow_data
);
104 birth
= process
->creation_time
;
105 const gchar
*name
= g_quark_to_string(process
->name
);
106 HashedProcessData
*hashed_process_data
= NULL
;
108 if(processlist_get_process_pixels(process_list
,
114 &hashed_process_data
) == 1)
116 /* Process not present */
117 processlist_add(process_list
,
123 &hashed_process_data
);
124 processlist_get_process_pixels(process_list
,
130 &hashed_process_data
);
131 drawing_insert_square( control_flow_data
->drawing
, y
, height
);
137 /* Action to do when background computation completed.
139 * Eventually, will have to check that every requested traces are finished
140 * before doing the redraw. It will save unnecessary processor usage.
143 gint
background_ready(void *hook_data
, void *call_data
)
145 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
146 LttvTrace
*trace
= (LttvTrace
*)call_data
;
147 LttvTracesetContext
*tsc
=
148 lttvwindow_get_traceset_context(control_flow_data
->tab
);
150 g_debug("control flow viewer : background computation data ready.");
152 drawing_clear(control_flow_data
->drawing
);
153 processlist_clear(control_flow_data
->process_list
);
156 gint num_traces
= lttv_traceset_number(tsc
->ts
);
159 ProcessAddClosure closure
;
160 closure
.cfd
= control_flow_data
;
162 for(i
=0;i
<num_traces
;i
++) {
163 ts
= (LttvTraceState
*)tsc
->traces
[i
];
165 closure
.trace_num
= i
;
167 /* add all the processes to the list */
168 lttv_state_for_each_process(ts
, (GHFunc
)process_add
, &closure
);
172 redraw_notify(control_flow_data
, NULL
);
178 /* Request background computation. Verify if it is in progress or ready first.
180 * Right now, for all loaded traces.
182 * Later : must be only for each trace in the tab's traceset.
184 void request_background_data(ControlFlowData
*control_flow_data
)
186 gint num_traces
= lttvwindowtraces_get_number();
190 LttvHooks
*background_ready_hook
=
192 lttv_hooks_add(background_ready_hook
, background_ready
, control_flow_data
,
195 for(i
=0;i
<num_traces
;i
++) {
196 trace
= lttvwindowtraces_get_trace(i
);
198 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace
)==FALSE
) {
200 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
202 /* We first remove requests that could have been done for the same
203 * information. Happens when two viewers ask for it before servicing
206 lttvwindowtraces_background_request_remove(trace
, "state");
207 lttvwindowtraces_background_request_queue(trace
,
209 lttvwindowtraces_background_notify_queue(control_flow_data
,
213 background_ready_hook
);
214 } else { /* in progress */
216 lttvwindowtraces_background_notify_current(control_flow_data
,
220 background_ready_hook
);
226 lttv_hooks_destroy(background_ready_hook
);
233 * Event Viewer's constructor hook
235 * This constructor is given as a parameter to the menuitem and toolbar button
236 * registration. It creates the list.
237 * @param tab A pointer to the parent tab.
238 * @return The widget created.
241 h_guicontrolflow(Tab
*tab
, LttvTracesetSelector
* s
, char * key
)
243 g_info("h_guicontrolflow, %p, %p, %s", tab
, s
, key
);
244 ControlFlowData
*control_flow_data
= guicontrolflow() ;
246 control_flow_data
->tab
= tab
;
248 //g_debug("time width2 : %u",time_window->time_width);
249 // Unreg done in the GuiControlFlow_Destructor
250 lttvwindow_register_traceset_notify(tab
,
254 lttvwindow_register_time_window_notify(tab
,
255 update_time_window_hook
,
257 lttvwindow_register_current_time_notify(tab
,
258 update_current_time_hook
,
260 lttvwindow_register_redraw_notify(tab
,
263 lttvwindow_register_continue_notify(tab
,
266 request_background_data(control_flow_data
);
269 return guicontrolflow_get_widget(control_flow_data
) ;
273 int event_selected_hook(void *hook_data
, void *call_data
)
275 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
276 guint
*event_number
= (guint
*) call_data
;
278 g_debug("DEBUG : event selected by main window : %u", *event_number
);
284 * This function basically draw lines and icons. Two types of lines are drawn :
285 * one small (3 pixels?) representing the state of the process and the second
286 * type is thicker (10 pixels?) representing on which CPU a process is running
287 * (and this only in running state).
289 * Extremums of the lines :
290 * x_min : time of the last event context for this process kept in memory.
291 * x_max : time of the current event.
292 * y : middle of the process in the process list. The process is found in the
293 * list, therefore is it's position in pixels.
295 * The choice of lines'color is defined by the context of the last event for this
300 int draw_before_hook(void *hook_data
, void *call_data
)
302 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
303 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
305 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
307 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
308 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
313 LttTime evtime
= ltt_event_time(e
);
314 TimeWindow time_window
=
315 lttvwindow_get_time_window(control_flow_data
->tab
);
317 LttTime end_time
= ltt_time_add(time_window
.start_time
,
318 time_window
.time_width
);
320 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
321 || ltt_time_compare(evtime
, end_time
) == 1)
324 guint width
= control_flow_data
->drawing
->width
;
326 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0) {
328 /* we are in a schedchange, before the state update. We must draw the
329 * items corresponding to the state before it changes : now is the right
336 LttField
*f
= ltt_event_field(e
);
338 element
= ltt_field_member(f
,0);
339 pid_out
= ltt_event_get_long_unsigned(e
,element
);
340 element
= ltt_field_member(f
,1);
341 pid_in
= ltt_event_get_long_unsigned(e
,element
);
342 g_debug("out : %u in : %u", pid_out
, pid_in
);
345 /* First, check if the current process is in the state computation process
346 * list. If it is there, that means we must add it right now and draw items
347 * from the beginning of the read for it. If it is not present, it's a new
348 * process and it was not present : it will be added after the state update.
350 LttvProcessState
*process
;
351 process
= lttv_state_find_process(tfs
, pid_out
);
353 if(process
!= NULL
) {
354 /* Well, the process_out existed : we must get it in the process hash
355 * or add it, and draw its items.
357 /* Add process to process list (if not present) */
358 guint y_out
= 0, height
= 0, pl_height
= 0;
359 HashedProcessData
*hashed_process_data
= NULL
;
360 ProcessList
*process_list
=
361 guicontrolflow_get_process_list(control_flow_data
);
362 LttTime birth
= process
->creation_time
;
363 const gchar
*name
= g_quark_to_string(process
->name
);
365 if(processlist_get_process_pixels(process_list
,
368 tfc
->t_context
->index
,
371 &hashed_process_data
) == 1)
373 /* Process not present */
374 processlist_add(process_list
,
377 tfc
->t_context
->index
,
380 &hashed_process_data
);
381 processlist_get_process_pixels(process_list
,
384 tfc
->t_context
->index
,
387 &hashed_process_data
);
388 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
391 /* Now, the process is in the state hash and our own process hash.
392 * We definitely can draw the items related to the ending state.
395 /* Check if the x position is unset. In can have been left unset by
396 * a draw closure from a after chunk hook. This should never happen,
397 * because it must be set by before chunk hook to the damage_begin
400 g_assert(hashed_process_data
->x
!= -1);
412 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
413 ControlFlowData
*control_flow_data
=
414 (ControlFlowData
*)events_request
->viewer_data
;
415 Tab
*tab
= control_flow_data
->tab
;
417 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
419 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
420 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
425 LttTime evtime
= ltt_event_time(e
);
426 TimeWindow time_window
=
427 lttvwindow_get_time_window(tab
);
429 LttTime end_time
= ltt_time_add(time_window
.start_time
,
430 time_window
.time_width
);
431 //if(time < time_beg || time > time_end) return;
432 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
433 || ltt_time_compare(evtime
, end_time
) == 1)
436 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
438 g_debug("schedchange!");
440 /* Add process to process list (if not present) and get drawing "y" from
441 * process position */
442 guint pid_out
, pid_in
;
443 LttvProcessState
*process_out
, *process_in
;
445 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
447 ProcessList
*process_list
=
448 guicontrolflow_get_process_list(control_flow_data
);
451 LttField
*f
= ltt_event_field(e
);
453 element
= ltt_field_member(f
,0);
454 pid_out
= ltt_event_get_long_unsigned(e
,element
);
455 element
= ltt_field_member(f
,1);
456 pid_in
= ltt_event_get_long_unsigned(e
,element
);
457 g_debug("out : %u in : %u", pid_out
, pid_in
);
460 /* Find process pid_out in the list... */
461 process_out
= lttv_state_find_process(tfs
, pid_out
);
462 if(process_out
== NULL
) return 0;
463 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
465 birth
= process_out
->creation_time
;
466 const gchar
*name
= g_quark_to_string(process_out
->name
);
467 HashedProcessData
*hashed_process_data_out
= NULL
;
469 if(processlist_get_process_pixels(process_list
,
472 tfc
->t_context
->index
,
475 &hashed_process_data_out
) == 1)
477 /* Process not present */
478 processlist_add(process_list
,
481 tfc
->t_context
->index
,
484 &hashed_process_data_out
);
485 g_assert(processlist_get_process_pixels(process_list
,
488 tfc
->t_context
->index
,
491 &hashed_process_data_out
)==0);
492 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
496 /* Find process pid_in in the list... */
497 process_in
= lttv_state_find_process(tfs
, pid_in
);
498 if(process_in
== NULL
) return 0;
499 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
501 birth
= process_in
->creation_time
;
502 name
= g_quark_to_string(process_in
->name
);
503 HashedProcessData
*hashed_process_data_in
= NULL
;
505 if(processlist_get_process_pixels(process_list
,
508 tfc
->t_context
->index
,
511 &hashed_process_data_in
) == 1)
513 /* Process not present */
514 processlist_add(process_list
,
517 tfc
->t_context
->index
,
520 &hashed_process_data_in
);
521 processlist_get_process_pixels(process_list
,
524 tfc
->t_context
->index
,
527 &hashed_process_data_in
);
529 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
534 /* Find pixels corresponding to time of the event. If the time does
535 * not fit in the window, show a warning, not supposed to happend. */
537 guint width
= control_flow_data
->drawing
->width
;
539 LttTime time
= ltt_event_time(e
);
541 LttTime window_end
= ltt_time_add(time_window
.time_width
,
542 time_window
.start_time
);
545 convert_time_to_pixels(
546 time_window
.start_time
,
551 //assert(x <= width);
553 /* draw what represents the event for outgoing process. */
555 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
556 draw_context_out
->current
->modify_over
->x
= x
;
557 draw_context_out
->current
->modify_under
->x
= x
;
558 draw_context_out
->current
->modify_over
->y
= y_out
;
559 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
560 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
561 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
562 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
563 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
564 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
565 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
566 //draw_context_out->gc = widget->style->black_gc;
568 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
569 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
571 /* Draw the line/background of the out process */
572 if(draw_context_out
->previous
->middle
->x
== -1)
574 draw_context_out
->previous
->over
->x
=
575 control_flow_data
->drawing
->damage_begin
;
576 draw_context_out
->previous
->middle
->x
=
577 control_flow_data
->drawing
->damage_begin
;
578 draw_context_out
->previous
->under
->x
=
579 control_flow_data
->drawing
->damage_begin
;
581 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
584 draw_context_out
->current
->middle
->x
= x
;
585 draw_context_out
->current
->over
->x
= x
;
586 draw_context_out
->current
->under
->x
= x
;
587 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
588 draw_context_out
->current
->over
->y
= y_out
;
589 draw_context_out
->current
->under
->y
= y_out
+ height
;
590 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
591 draw_context_out
->previous
->over
->y
= y_out
;
592 draw_context_out
->previous
->under
->y
= y_out
+ height
;
594 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
595 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
597 if(process_out
->state
->s
== LTTV_STATE_RUN
)
599 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
600 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
601 draw_context_out
->gc
= control_flow_data
->drawing
->gc
;
603 PropertiesBG prop_bg
;
604 prop_bg
.color
= g_new(GdkColor
,1);
608 prop_bg
.color
->red
= 0x1515;
609 prop_bg
.color
->green
= 0x1515;
610 prop_bg
.color
->blue
= 0x8c8c;
613 prop_bg
.color
->red
= 0x4e4e;
614 prop_bg
.color
->green
= 0xa9a9;
615 prop_bg
.color
->blue
= 0xa4a4;
618 prop_bg
.color
->red
= 0x7a7a;
619 prop_bg
.color
->green
= 0x4a4a;
620 prop_bg
.color
->blue
= 0x8b8b;
623 prop_bg
.color
->red
= 0x8080;
624 prop_bg
.color
->green
= 0x7777;
625 prop_bg
.color
->blue
= 0x4747;
628 prop_bg
.color
->red
= 0xe7e7;
629 prop_bg
.color
->green
= 0xe7e7;
630 prop_bg
.color
->blue
= 0xe7e7;
633 g_debug("calling from draw_event");
634 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
635 g_free(prop_bg
.color
);
636 //gdk_gc_unref(draw_context_out->gc);
639 draw_context_out
->gc
= widget
->style
->black_gc
;
641 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
642 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
643 PropertiesText prop_text_out
;
644 prop_text_out
.foreground
= &colorfg_out
;
645 prop_text_out
.background
= &colorbg_out
;
646 prop_text_out
.size
= 6;
647 prop_text_out
.position
= OVER
;
649 /* color of text : status of the process */
650 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
652 prop_text_out
.foreground
->red
= 0xffff;
653 prop_text_out
.foreground
->green
= 0xffff;
654 prop_text_out
.foreground
->blue
= 0xffff;
656 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
658 prop_text_out
.foreground
->red
= 0x0fff;
659 prop_text_out
.foreground
->green
= 0xffff;
660 prop_text_out
.foreground
->blue
= 0xfff0;
662 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
664 prop_text_out
.foreground
->red
= 0xffff;
665 prop_text_out
.foreground
->green
= 0xffff;
666 prop_text_out
.foreground
->blue
= 0x0000;
668 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
670 prop_text_out
.foreground
->red
= 0xffff;
671 prop_text_out
.foreground
->green
= 0x0000;
672 prop_text_out
.foreground
->blue
= 0xffff;
674 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
676 prop_text_out
.foreground
->red
= 0xffff;
677 prop_text_out
.foreground
->green
= 0x0000;
678 prop_text_out
.foreground
->blue
= 0x0000;
680 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
682 prop_text_out
.foreground
->red
= 0x0000;
683 prop_text_out
.foreground
->green
= 0xffff;
684 prop_text_out
.foreground
->blue
= 0x0000;
688 prop_text_out
.foreground
->red
= 0xffff;
689 prop_text_out
.foreground
->green
= 0xffff;
690 prop_text_out
.foreground
->blue
= 0xffff;
694 /* Print status of the process : U, WF, WC, E, W, R */
695 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
696 prop_text_out
.text
= "U->";
697 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
698 prop_text_out
.text
= "WF->";
699 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
700 prop_text_out
.text
= "WC->";
701 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
702 prop_text_out
.text
= "E->";
703 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
704 prop_text_out
.text
= "W->";
705 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
706 prop_text_out
.text
= "R->";
708 prop_text_out
.text
= "U";
710 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
711 //gdk_gc_unref(draw_context_out->gc);
713 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
714 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
715 draw_context_out
->gc
= control_flow_data
->drawing
->gc
;
717 PropertiesLine prop_line_out
;
718 prop_line_out
.color
= g_new(GdkColor
,1);
719 prop_line_out
.line_width
= 2;
720 prop_line_out
.style
= GDK_LINE_SOLID
;
721 prop_line_out
.position
= MIDDLE
;
723 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
725 /* color of line : status of the process */
726 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
728 prop_line_out
.color
->red
= 0xffff;
729 prop_line_out
.color
->green
= 0xffff;
730 prop_line_out
.color
->blue
= 0xffff;
732 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
734 prop_line_out
.color
->red
= 0x0fff;
735 prop_line_out
.color
->green
= 0xffff;
736 prop_line_out
.color
->blue
= 0xfff0;
738 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
740 prop_line_out
.color
->red
= 0xffff;
741 prop_line_out
.color
->green
= 0xffff;
742 prop_line_out
.color
->blue
= 0x0000;
744 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
746 prop_line_out
.color
->red
= 0xffff;
747 prop_line_out
.color
->green
= 0x0000;
748 prop_line_out
.color
->blue
= 0xffff;
750 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
752 prop_line_out
.color
->red
= 0xffff;
753 prop_line_out
.color
->green
= 0x0000;
754 prop_line_out
.color
->blue
= 0x0000;
756 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
758 prop_line_out
.color
->red
= 0x0000;
759 prop_line_out
.color
->green
= 0xffff;
760 prop_line_out
.color
->blue
= 0x0000;
764 prop_line_out
.color
->red
= 0xffff;
765 prop_line_out
.color
->green
= 0xffff;
766 prop_line_out
.color
->blue
= 0xffff;
769 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
770 g_free(prop_line_out
.color
);
771 //gdk_gc_unref(draw_context_out->gc);
772 /* Note : finishing line will have to be added when trace read over. */
774 /* Finally, update the drawing context of the pid_in. */
776 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
777 draw_context_in
->current
->modify_over
->x
= x
;
778 draw_context_in
->current
->modify_under
->x
= x
;
779 draw_context_in
->current
->modify_over
->y
= y_in
;
780 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
781 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
782 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
783 widget
= control_flow_data
->drawing
->drawing_area
;
784 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
785 //draw_context_in->gc = widget->style->black_gc;
786 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
787 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
789 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
790 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
792 /* Draw the line/bg of the in process */
793 if(draw_context_in
->previous
->middle
->x
== -1)
795 draw_context_in
->previous
->over
->x
=
796 control_flow_data
->drawing
->damage_begin
;
797 draw_context_in
->previous
->middle
->x
=
798 control_flow_data
->drawing
->damage_begin
;
799 draw_context_in
->previous
->under
->x
=
800 control_flow_data
->drawing
->damage_begin
;
802 g_debug("in middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
806 draw_context_in
->current
->middle
->x
= x
;
807 draw_context_in
->current
->over
->x
= x
;
808 draw_context_in
->current
->under
->x
= x
;
809 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
810 draw_context_in
->current
->over
->y
= y_in
;
811 draw_context_in
->current
->under
->y
= y_in
+ height
;
812 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
813 draw_context_in
->previous
->over
->y
= y_in
;
814 draw_context_in
->previous
->under
->y
= y_in
+ height
;
816 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
817 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
820 if(process_in
->state
->s
== LTTV_STATE_RUN
)
822 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
823 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
824 draw_context_in
->gc
= control_flow_data
->drawing
->gc
;
826 PropertiesBG prop_bg
;
827 prop_bg
.color
= g_new(GdkColor
,1);
831 prop_bg
.color
->red
= 0x1515;
832 prop_bg
.color
->green
= 0x1515;
833 prop_bg
.color
->blue
= 0x8c8c;
836 prop_bg
.color
->red
= 0x4e4e;
837 prop_bg
.color
->green
= 0xa9a9;
838 prop_bg
.color
->blue
= 0xa4a4;
841 prop_bg
.color
->red
= 0x7a7a;
842 prop_bg
.color
->green
= 0x4a4a;
843 prop_bg
.color
->blue
= 0x8b8b;
846 prop_bg
.color
->red
= 0x8080;
847 prop_bg
.color
->green
= 0x7777;
848 prop_bg
.color
->blue
= 0x4747;
851 prop_bg
.color
->red
= 0xe7e7;
852 prop_bg
.color
->green
= 0xe7e7;
853 prop_bg
.color
->blue
= 0xe7e7;
857 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
858 g_free(prop_bg
.color
);
859 //gdk_gc_unref(draw_context_in->gc);
862 draw_context_in
->gc
= widget
->style
->black_gc
;
864 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
865 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
866 PropertiesText prop_text_in
;
867 prop_text_in
.foreground
= &colorfg_in
;
868 prop_text_in
.background
= &colorbg_in
;
869 prop_text_in
.size
= 6;
870 prop_text_in
.position
= OVER
;
872 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
873 /* foreground of text : status of the process */
874 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
876 prop_text_in
.foreground
->red
= 0xffff;
877 prop_text_in
.foreground
->green
= 0xffff;
878 prop_text_in
.foreground
->blue
= 0xffff;
880 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
882 prop_text_in
.foreground
->red
= 0x0fff;
883 prop_text_in
.foreground
->green
= 0xffff;
884 prop_text_in
.foreground
->blue
= 0xfff0;
886 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
888 prop_text_in
.foreground
->red
= 0xffff;
889 prop_text_in
.foreground
->green
= 0xffff;
890 prop_text_in
.foreground
->blue
= 0x0000;
892 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
894 prop_text_in
.foreground
->red
= 0xffff;
895 prop_text_in
.foreground
->green
= 0x0000;
896 prop_text_in
.foreground
->blue
= 0xffff;
898 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
900 prop_text_in
.foreground
->red
= 0xffff;
901 prop_text_in
.foreground
->green
= 0x0000;
902 prop_text_in
.foreground
->blue
= 0x0000;
904 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
906 prop_text_in
.foreground
->red
= 0x0000;
907 prop_text_in
.foreground
->green
= 0xffff;
908 prop_text_in
.foreground
->blue
= 0x0000;
912 prop_text_in
.foreground
->red
= 0xffff;
913 prop_text_in
.foreground
->green
= 0xffff;
914 prop_text_in
.foreground
->blue
= 0xffff;
919 /* Print status of the process : U, WF, WC, E, W, R */
920 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
921 prop_text_in
.text
= "U->";
922 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
923 prop_text_in
.text
= "WF->";
924 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
925 prop_text_in
.text
= "WC->";
926 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
927 prop_text_in
.text
= "E->";
928 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
929 prop_text_in
.text
= "W->";
930 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
931 prop_text_in
.text
= "R->";
933 prop_text_in
.text
= "U";
935 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
936 //gdk_gc_unref(draw_context_in->gc);
938 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
939 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
940 draw_context_in
->gc
= control_flow_data
->drawing
->gc
;
942 PropertiesLine prop_line_in
;
943 prop_line_in
.color
= g_new(GdkColor
,1);
944 prop_line_in
.line_width
= 2;
945 prop_line_in
.style
= GDK_LINE_SOLID
;
946 prop_line_in
.position
= MIDDLE
;
948 /* color of line : status of the process */
949 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
951 prop_line_in
.color
->red
= 0xffff;
952 prop_line_in
.color
->green
= 0xffff;
953 prop_line_in
.color
->blue
= 0xffff;
955 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
957 prop_line_in
.color
->red
= 0x0fff;
958 prop_line_in
.color
->green
= 0xffff;
959 prop_line_in
.color
->blue
= 0xfff0;
961 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
963 prop_line_in
.color
->red
= 0xffff;
964 prop_line_in
.color
->green
= 0xffff;
965 prop_line_in
.color
->blue
= 0x0000;
967 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
969 prop_line_in
.color
->red
= 0xffff;
970 prop_line_in
.color
->green
= 0x0000;
971 prop_line_in
.color
->blue
= 0xffff;
973 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
975 prop_line_in
.color
->red
= 0xffff;
976 prop_line_in
.color
->green
= 0x0000;
977 prop_line_in
.color
->blue
= 0x0000;
979 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
981 prop_line_in
.color
->red
= 0x0000;
982 prop_line_in
.color
->green
= 0xffff;
983 prop_line_in
.color
->blue
= 0x0000;
987 prop_line_in
.color
->red
= 0xffff;
988 prop_line_in
.color
->green
= 0xffff;
989 prop_line_in
.color
->blue
= 0xffff;
992 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
993 g_free(prop_line_in
.color
);
994 //gdk_gc_unref(draw_context_in->gc);
1004 GString
*string
= g_string_new("");;
1005 gboolean field_names
= TRUE
, state
= TRUE
;
1007 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
1008 g_string_append_printf(string
,"\n");
1011 g_string_append_printf(string
, " %s",
1012 g_quark_to_string(tfs
->process
->state
->s
));
1015 g_info("%s",string
->str
);
1017 g_string_free(string
, TRUE
);
1019 /* End of text dump */
1026 * The draw after hook is called by the reading API to have a
1027 * particular event drawn on the screen.
1028 * @param hook_data ControlFlowData structure of the viewer.
1029 * @param call_data Event context.
1031 * This function adds items to be drawn in a queue for each process.
1034 int draw_after_hook(void *hook_data
, void *call_data
)
1036 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1037 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1039 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
1041 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
1042 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
1047 LttTime evtime
= ltt_event_time(e
);
1048 TimeWindow time_window
=
1049 lttvwindow_get_time_window(control_flow_data
->tab
);
1051 LttTime end_time
= ltt_time_add(time_window
.start_time
,
1052 time_window
.time_width
);
1054 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
1055 || ltt_time_compare(evtime
, end_time
) == 1)
1058 guint width
= control_flow_data
->drawing
->width
;
1060 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0) {
1062 g_debug("schedchange!");
1065 /* Add process to process list (if not present) */
1066 LttvProcessState
*process_out
, *process_in
;
1068 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
1069 HashedProcessData
*hashed_process_data_in
= NULL
;
1071 ProcessList
*process_list
=
1072 guicontrolflow_get_process_list(control_flow_data
);
1077 LttField
*f
= ltt_event_field(e
);
1079 element
= ltt_field_member(f
,0);
1080 pid_out
= ltt_event_get_long_unsigned(e
,element
);
1081 element
= ltt_field_member(f
,1);
1082 pid_in
= ltt_event_get_long_unsigned(e
,element
);
1083 g_debug("out : %u in : %u", pid_out
, pid_in
);
1087 /* Find process pid_in in the list... */
1088 process_in
= lttv_state_find_process(tfs
, pid_in
);
1089 /* It should exist, because we are after the state update. */
1090 g_assert(process_in
!= NULL
);
1092 birth
= process_in
->creation_time
;
1093 const gchar
*name
= g_quark_to_string(process_in
->name
);
1095 if(processlist_get_process_pixels(process_list
,
1098 tfc
->t_context
->index
,
1101 &hashed_process_data_in
) == 1)
1103 /* Process not present */
1104 processlist_add(process_list
,
1107 tfc
->t_context
->index
,
1110 &hashed_process_data_in
);
1111 processlist_get_process_pixels(process_list
,
1114 tfc
->t_context
->index
,
1117 &hashed_process_data_in
);
1118 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
1121 convert_time_to_pixels(
1122 time_window
.start_time
,
1126 &hashed_process_data_in
->x
);
1134 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
1135 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
1137 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
1139 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
1140 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
1146 LttTime evtime
= ltt_event_time(e
);
1147 TimeWindow time_window
=
1148 lttvwindow_get_time_window(control_flow_data
->tab
);
1150 LttTime end_time
= ltt_time_add(time_window
.start_time
,
1151 time_window
.time_width
);
1152 //if(time < time_beg || time > time_end) return;
1153 if(ltt_time_compare(evtime
, time_window
.start_time
) == -1
1154 || ltt_time_compare(evtime
, end_time
) == 1)
1158 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
1160 g_debug("schedchange!");
1162 /* Add process to process list (if not present) and get drawing "y" from
1163 * process position */
1164 guint pid_out
, pid_in
;
1165 LttvProcessState
*process_out
, *process_in
;
1167 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
1169 ProcessList
*process_list
=
1170 guicontrolflow_get_process_list(control_flow_data
);
1173 LttField
*f
= ltt_event_field(e
);
1175 element
= ltt_field_member(f
,0);
1176 pid_out
= ltt_event_get_long_unsigned(e
,element
);
1177 element
= ltt_field_member(f
,1);
1178 pid_in
= ltt_event_get_long_unsigned(e
,element
);
1179 //g_debug("out : %u in : %u", pid_out, pid_in);
1182 /* Find process pid_out in the list... */
1183 process_out
= lttv_state_find_process(tfs
, pid_out
);
1184 if(process_out
== NULL
) return 0;
1185 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
1187 birth
= process_out
->creation_time
;
1188 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
1189 HashedProcessData
*hashed_process_data_out
= NULL
;
1191 if(processlist_get_process_pixels(process_list
,
1194 tfc
->t_context
->index
,
1197 &hashed_process_data_out
) == 1)
1199 /* Process not present */
1200 processlist_add(process_list
,
1203 tfc
->t_context
->index
,
1206 &hashed_process_data_out
);
1207 processlist_get_process_pixels(process_list
,
1210 tfc
->t_context
->index
,
1213 &hashed_process_data_out
);
1214 drawing_insert_square( control_flow_data
->drawing
, y_out
, height
);
1219 /* Find process pid_in in the list... */
1220 process_in
= lttv_state_find_process(tfs
, pid_in
);
1221 if(process_in
== NULL
) return 0;
1222 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
1224 birth
= process_in
->creation_time
;
1225 name
= strdup(g_quark_to_string(process_in
->name
));
1226 HashedProcessData
*hashed_process_data_in
= NULL
;
1228 if(processlist_get_process_pixels(process_list
,
1231 tfc
->t_context
->index
,
1234 &hashed_process_data_in
) == 1)
1236 /* Process not present */
1237 processlist_add(process_list
,
1240 tfc
->t_context
->index
,
1243 &hashed_process_data_in
);
1244 processlist_get_process_pixels(process_list
,
1247 tfc
->t_context
->index
,
1250 &hashed_process_data_in
);
1252 drawing_insert_square( control_flow_data
->drawing
, y_in
, height
);
1257 /* Find pixels corresponding to time of the event. If the time does
1258 * not fit in the window, show a warning, not supposed to happend. */
1260 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
1262 //LttTime time = ltt_event_time(e);
1264 //LttTime window_end = ltt_time_add(time_window->time_width,
1265 // time_window->start_time);
1268 //convert_time_to_pixels(
1269 // time_window->start_time,
1275 //assert(x <= width);
1277 /* draw what represents the event for outgoing process. */
1279 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
1280 //draw_context_out->current->modify_over->x = x;
1281 draw_context_out
->current
->modify_over
->y
= y_out
;
1282 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
1283 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
1284 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1285 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1286 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1288 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
1289 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1291 /*if(process_out->state->s == LTTV_STATE_RUN)
1293 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1294 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1295 PropertiesBG prop_bg;
1296 prop_bg.color = g_new(GdkColor,1);
1298 prop_bg.color->red = 0xffff;
1299 prop_bg.color->green = 0xffff;
1300 prop_bg.color->blue = 0xffff;
1302 draw_bg((void*)&prop_bg, (void*)draw_context_out);
1303 g_free(prop_bg.color);
1304 gdk_gc_unref(draw_context_out->gc);
1307 draw_context_out
->gc
= widget
->style
->black_gc
;
1309 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
1310 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
1311 PropertiesText prop_text_out
;
1312 prop_text_out
.foreground
= &colorfg_out
;
1313 prop_text_out
.background
= &colorbg_out
;
1314 prop_text_out
.size
= 6;
1315 prop_text_out
.position
= OVER
;
1317 /* color of text : status of the process */
1318 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1320 prop_text_out
.foreground
->red
= 0xffff;
1321 prop_text_out
.foreground
->green
= 0xffff;
1322 prop_text_out
.foreground
->blue
= 0xffff;
1324 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1326 prop_text_out
.foreground
->red
= 0x0fff;
1327 prop_text_out
.foreground
->green
= 0xffff;
1328 prop_text_out
.foreground
->blue
= 0xfff0;
1330 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1332 prop_text_out
.foreground
->red
= 0xffff;
1333 prop_text_out
.foreground
->green
= 0xffff;
1334 prop_text_out
.foreground
->blue
= 0x0000;
1336 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1338 prop_text_out
.foreground
->red
= 0xffff;
1339 prop_text_out
.foreground
->green
= 0x0000;
1340 prop_text_out
.foreground
->blue
= 0xffff;
1342 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1344 prop_text_out
.foreground
->red
= 0xffff;
1345 prop_text_out
.foreground
->green
= 0x0000;
1346 prop_text_out
.foreground
->blue
= 0x0000;
1348 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1350 prop_text_out
.foreground
->red
= 0x0000;
1351 prop_text_out
.foreground
->green
= 0xffff;
1352 prop_text_out
.foreground
->blue
= 0x0000;
1356 prop_text_out
.foreground
->red
= 0xffff;
1357 prop_text_out
.foreground
->green
= 0xffff;
1358 prop_text_out
.foreground
->blue
= 0xffff;
1361 /* Print status of the process : U, WF, WC, E, W, R */
1362 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
1363 prop_text_out
.text
= "U";
1364 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
1365 prop_text_out
.text
= "WF";
1366 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
1367 prop_text_out
.text
= "WC";
1368 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
1369 prop_text_out
.text
= "E";
1370 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
1371 prop_text_out
.text
= "W";
1372 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
1373 prop_text_out
.text
= "R";
1375 prop_text_out
.text
= "U";
1377 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
1379 //gdk_gc_unref(draw_context_out->gc);
1381 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
1382 draw_context_out
->current
->over
->y
= y_out
;
1383 draw_context_out
->current
->under
->y
= y_out
+height
;
1384 draw_context_out
->current
->status
= process_out
->state
->s
;
1386 /* for pid_out : remove previous, Prev = current, new current (default) */
1387 g_free(draw_context_out
->previous
->modify_under
);
1388 g_free(draw_context_out
->previous
->modify_middle
);
1389 g_free(draw_context_out
->previous
->modify_over
);
1390 g_free(draw_context_out
->previous
->under
);
1391 g_free(draw_context_out
->previous
->middle
);
1392 g_free(draw_context_out
->previous
->over
);
1393 g_free(draw_context_out
->previous
);
1395 draw_context_out
->previous
= draw_context_out
->current
;
1397 draw_context_out
->current
= g_new(DrawInfo
,1);
1398 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
1399 draw_context_out
->current
->over
->x
= -1;
1400 draw_context_out
->current
->over
->y
= -1;
1401 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1402 draw_context_out
->current
->middle
->x
= -1;
1403 draw_context_out
->current
->middle
->y
= -1;
1404 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1405 draw_context_out
->current
->under
->x
= -1;
1406 draw_context_out
->current
->under
->y
= -1;
1407 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1408 draw_context_out
->current
->modify_over
->x
= -1;
1409 draw_context_out
->current
->modify_over
->y
= -1;
1410 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1411 draw_context_out
->current
->modify_middle
->x
= -1;
1412 draw_context_out
->current
->modify_middle
->y
= -1;
1413 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1414 draw_context_out
->current
->modify_under
->x
= -1;
1415 draw_context_out
->current
->modify_under
->y
= -1;
1416 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1418 /* Finally, update the drawing context of the pid_in. */
1420 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1421 //draw_context_in->current->modify_over->x = x;
1422 draw_context_in
->current
->modify_over
->y
= y_in
;
1423 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1424 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1425 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1426 widget
= control_flow_data
->drawing
->drawing_area
;
1427 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1429 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1430 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1432 /*if(process_in->state->s == LTTV_STATE_RUN)
1434 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1435 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1436 PropertiesBG prop_bg;
1437 prop_bg.color = g_new(GdkColor,1);
1439 prop_bg.color->red = 0xffff;
1440 prop_bg.color->green = 0xffff;
1441 prop_bg.color->blue = 0xffff;
1443 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1444 g_free(prop_bg.color);
1445 gdk_gc_unref(draw_context_in->gc);
1448 draw_context_in
->gc
= widget
->style
->black_gc
;
1450 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1451 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1452 PropertiesText prop_text_in
;
1453 prop_text_in
.foreground
= &colorfg_in
;
1454 prop_text_in
.background
= &colorbg_in
;
1455 prop_text_in
.size
= 6;
1456 prop_text_in
.position
= OVER
;
1458 /* foreground of text : status of the process */
1459 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1461 prop_text_in
.foreground
->red
= 0xffff;
1462 prop_text_in
.foreground
->green
= 0xffff;
1463 prop_text_in
.foreground
->blue
= 0xffff;
1465 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1467 prop_text_in
.foreground
->red
= 0x0fff;
1468 prop_text_in
.foreground
->green
= 0xffff;
1469 prop_text_in
.foreground
->blue
= 0xfff0;
1471 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1473 prop_text_in
.foreground
->red
= 0xffff;
1474 prop_text_in
.foreground
->green
= 0xffff;
1475 prop_text_in
.foreground
->blue
= 0x0000;
1477 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1479 prop_text_in
.foreground
->red
= 0xffff;
1480 prop_text_in
.foreground
->green
= 0x0000;
1481 prop_text_in
.foreground
->blue
= 0xffff;
1483 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1485 prop_text_in
.foreground
->red
= 0xffff;
1486 prop_text_in
.foreground
->green
= 0x0000;
1487 prop_text_in
.foreground
->blue
= 0x0000;
1489 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1491 prop_text_in
.foreground
->red
= 0x0000;
1492 prop_text_in
.foreground
->green
= 0xffff;
1493 prop_text_in
.foreground
->blue
= 0x0000;
1497 prop_text_in
.foreground
->red
= 0xffff;
1498 prop_text_in
.foreground
->green
= 0xffff;
1499 prop_text_in
.foreground
->blue
= 0xffff;
1503 /* Print status of the process : U, WF, WC, E, W, R */
1504 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1505 prop_text_in
.text
= "U";
1506 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1507 prop_text_in
.text
= "WF";
1508 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1509 prop_text_in
.text
= "WC";
1510 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1511 prop_text_in
.text
= "E";
1512 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1513 prop_text_in
.text
= "W";
1514 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1515 prop_text_in
.text
= "R";
1517 prop_text_in
.text
= "U";
1519 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1522 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1525 prop_text_in
.foreground
= &colorfg_in
;
1526 prop_text_in
.background
= &colorbg_in
;
1527 prop_text_in
.foreground
->red
= 0xffff;
1528 prop_text_in
.foreground
->green
= 0xffff;
1529 prop_text_in
.foreground
->blue
= 0xffff;
1530 prop_text_in
.size
= 6;
1531 prop_text_in
.position
= UNDER
;
1533 prop_text_in
.text
= g_new(gchar
, 260);
1534 strcpy(prop_text_in
.text
, "CPU ");
1535 snprintf(tmp
, 255, "%u", tfc
->index
);
1536 strcat(prop_text_in
.text
, tmp
);
1538 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1539 g_free(prop_text_in
.text
);
1543 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1544 draw_context_in
->current
->over
->y
= y_in
;
1545 draw_context_in
->current
->under
->y
= y_in
+height
;
1546 draw_context_in
->current
->status
= process_in
->state
->s
;
1548 /* for pid_in : remove previous, Prev = current, new current (default) */
1549 g_free(draw_context_in
->previous
->modify_under
);
1550 g_free(draw_context_in
->previous
->modify_middle
);
1551 g_free(draw_context_in
->previous
->modify_over
);
1552 g_free(draw_context_in
->previous
->under
);
1553 g_free(draw_context_in
->previous
->middle
);
1554 g_free(draw_context_in
->previous
->over
);
1555 g_free(draw_context_in
->previous
);
1557 draw_context_in
->previous
= draw_context_in
->current
;
1559 draw_context_in
->current
= g_new(DrawInfo
,1);
1560 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1561 draw_context_in
->current
->over
->x
= -1;
1562 draw_context_in
->current
->over
->y
= -1;
1563 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1564 draw_context_in
->current
->middle
->x
= -1;
1565 draw_context_in
->current
->middle
->y
= -1;
1566 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1567 draw_context_in
->current
->under
->x
= -1;
1568 draw_context_in
->current
->under
->y
= -1;
1569 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1570 draw_context_in
->current
->modify_over
->x
= -1;
1571 draw_context_in
->current
->modify_over
->y
= -1;
1572 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1573 draw_context_in
->current
->modify_middle
->x
= -1;
1574 draw_context_in
->current
->modify_middle
->y
= -1;
1575 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1576 draw_context_in
->current
->modify_under
->x
= -1;
1577 draw_context_in
->current
->modify_under
->y
= -1;
1578 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1589 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1591 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1592 Drawing_t
*drawing
= control_flow_data
->drawing
;
1594 const TimeWindowNotifyData
*time_window_nofify_data
=
1595 ((const TimeWindowNotifyData
*)call_data
);
1597 TimeWindow
*old_time_window
=
1598 time_window_nofify_data
->old_time_window
;
1599 TimeWindow
*new_time_window
=
1600 time_window_nofify_data
->new_time_window
;
1602 /* Update the ruler */
1603 drawing_update_ruler(control_flow_data
->drawing
,
1607 /* Two cases : zoom in/out or scrolling */
1609 /* In order to make sure we can reuse the old drawing, the scale must
1610 * be the same and the new time interval being partly located in the
1611 * currently shown time interval. (reuse is only for scrolling)
1614 g_info("Old time window HOOK : %u, %u to %u, %u",
1615 old_time_window
->start_time
.tv_sec
,
1616 old_time_window
->start_time
.tv_nsec
,
1617 old_time_window
->time_width
.tv_sec
,
1618 old_time_window
->time_width
.tv_nsec
);
1620 g_info("New time window HOOK : %u, %u to %u, %u",
1621 new_time_window
->start_time
.tv_sec
,
1622 new_time_window
->start_time
.tv_nsec
,
1623 new_time_window
->time_width
.tv_sec
,
1624 new_time_window
->time_width
.tv_nsec
);
1626 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1627 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1629 /* Same scale (scrolling) */
1630 g_info("scrolling");
1631 LttTime
*ns
= &new_time_window
->start_time
;
1632 LttTime
*os
= &old_time_window
->start_time
;
1633 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1634 old_time_window
->time_width
);
1635 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1636 new_time_window
->time_width
);
1638 //if(ns<os+w && os+w<ns+w)
1639 //if(ns<old_end && os<ns)
1640 if(ltt_time_compare(*ns
, old_end
) == -1
1641 && ltt_time_compare(*os
, *ns
) == -1)
1643 g_info("scrolling near right");
1644 /* Scroll right, keep right part of the screen */
1646 guint width
= control_flow_data
->drawing
->width
;
1647 convert_time_to_pixels(
1654 /* Copy old data to new location */
1655 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1656 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1657 control_flow_data
->drawing
->pixmap
,
1660 control_flow_data
->drawing
->width
-x
+SAFETY
, -1);
1662 if(drawing
->damage_begin
== drawing
->damage_end
)
1663 drawing
->damage_begin
= control_flow_data
->drawing
->width
-x
;
1665 drawing
->damage_begin
= 0;
1667 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1669 /* Clear the data request background, but not SAFETY */
1670 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1671 //control_flow_data->drawing->drawing_area->style->black_gc,
1672 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1674 drawing
->damage_begin
+SAFETY
, 0,
1675 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1676 control_flow_data
->drawing
->height
);
1678 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1680 control_flow_data
->drawing
->width
,
1681 control_flow_data
->drawing
->height
);
1683 /* Get new data for the rest. */
1684 drawing_data_request(control_flow_data
->drawing
,
1685 &control_flow_data
->drawing
->pixmap
,
1686 drawing
->damage_begin
, 0,
1687 drawing
->damage_end
- drawing
->damage_begin
,
1688 control_flow_data
->drawing
->height
);
1691 //if(ns<os && os<ns+w)
1692 //if(ns<os && os<new_end)
1693 if(ltt_time_compare(*ns
,*os
) == -1
1694 && ltt_time_compare(*os
,new_end
) == -1)
1696 g_info("scrolling near left");
1697 /* Scroll left, keep left part of the screen */
1699 guint width
= control_flow_data
->drawing
->width
;
1700 convert_time_to_pixels(
1708 /* Copy old data to new location */
1709 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1710 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1711 control_flow_data
->drawing
->pixmap
,
1716 if(drawing
->damage_begin
== drawing
->damage_end
)
1717 drawing
->damage_end
= x
;
1719 drawing
->damage_end
=
1720 control_flow_data
->drawing
->width
;
1722 drawing
->damage_begin
= 0;
1724 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1725 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1727 drawing
->damage_begin
, 0,
1728 drawing
->damage_end
- drawing
->damage_begin
, // do not overlap
1729 control_flow_data
->drawing
->height
);
1731 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1733 control_flow_data
->drawing
->width
,
1734 control_flow_data
->drawing
->height
);
1737 /* Get new data for the rest. */
1738 drawing_data_request(control_flow_data
->drawing
,
1739 &control_flow_data
->drawing
->pixmap
,
1740 drawing
->damage_begin
, 0,
1741 drawing
->damage_end
- drawing
->damage_begin
,
1742 control_flow_data
->drawing
->height
);
1745 if(ltt_time_compare(*ns
,*os
) == 0)
1747 g_info("not scrolling");
1749 g_info("scrolling far");
1750 /* Cannot reuse any part of the screen : far jump */
1753 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1754 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1757 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1758 control_flow_data
->drawing
->height
);
1760 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1762 control_flow_data
->drawing
->width
,
1763 control_flow_data
->drawing
->height
);
1765 drawing
->damage_begin
= 0;
1766 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1768 drawing_data_request(control_flow_data
->drawing
,
1769 &control_flow_data
->drawing
->pixmap
,
1771 control_flow_data
->drawing
->width
,
1772 control_flow_data
->drawing
->height
);
1778 /* Different scale (zoom) */
1781 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1782 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1785 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1786 control_flow_data
->drawing
->height
);
1788 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1790 control_flow_data
->drawing
->width
,
1791 control_flow_data
->drawing
->height
);
1793 drawing
->damage_begin
= 0;
1794 drawing
->damage_end
= control_flow_data
->drawing
->width
;
1796 drawing_data_request(control_flow_data
->drawing
,
1797 &control_flow_data
->drawing
->pixmap
,
1799 control_flow_data
->drawing
->width
,
1800 control_flow_data
->drawing
->height
);
1808 gint
traceset_notify(void *hook_data
, void *call_data
)
1810 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1811 Drawing_t
*drawing
= control_flow_data
->drawing
;
1812 GtkWidget
*widget
= drawing
->drawing_area
;
1814 drawing
->damage_begin
= 0;
1815 drawing
->damage_end
= drawing
->width
;
1817 drawing_clear(control_flow_data
->drawing
);
1818 processlist_clear(control_flow_data
->process_list
);
1820 if(drawing
->damage_begin
< drawing
->damage_end
)
1822 drawing_data_request(drawing
,
1824 drawing
->damage_begin
,
1826 drawing
->damage_end
-drawing
->damage_begin
,
1830 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1835 request_background_data(control_flow_data
);
1840 gint
redraw_notify(void *hook_data
, void *call_data
)
1842 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1843 Drawing_t
*drawing
= control_flow_data
->drawing
;
1844 GtkWidget
*widget
= drawing
->drawing_area
;
1846 drawing
->damage_begin
= 0;
1847 drawing
->damage_end
= drawing
->width
;
1851 gdk_draw_rectangle (drawing
->pixmap
,
1852 widget
->style
->black_gc
,
1855 drawing
->width
+SAFETY
,
1859 if(drawing
->damage_begin
< drawing
->damage_end
)
1861 drawing_data_request(drawing
,
1863 drawing
->damage_begin
,
1865 drawing
->damage_end
-drawing
->damage_begin
,
1869 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1879 gint
continue_notify(void *hook_data
, void *call_data
)
1881 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1882 Drawing_t
*drawing
= control_flow_data
->drawing
;
1883 GtkWidget
*widget
= drawing
->drawing_area
;
1885 //g_assert(widget->allocation.width == drawing->damage_end);
1887 if(drawing
->damage_begin
< drawing
->damage_end
)
1889 drawing_data_request(drawing
,
1891 drawing
->damage_begin
,
1893 drawing
->damage_end
-drawing
->damage_begin
,
1901 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1903 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1904 Drawing_t
*drawing
= control_flow_data
->drawing
;
1906 LttTime current_time
= *((LttTime
*)call_data
);
1908 TimeWindow time_window
=
1909 lttvwindow_get_time_window(control_flow_data
->tab
);
1911 LttTime time_begin
= time_window
.start_time
;
1912 LttTime width
= time_window
.time_width
;
1913 LttTime half_width
= ltt_time_div(width
,2.0);
1914 LttTime time_end
= ltt_time_add(time_begin
, width
);
1916 LttvTracesetContext
* tsc
=
1917 lttvwindow_get_traceset_context(control_flow_data
->tab
);
1919 LttTime trace_start
= tsc
->time_span
.start_time
;
1920 LttTime trace_end
= tsc
->time_span
.end_time
;
1922 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
1923 current_time
.tv_nsec
);
1927 /* If current time is inside time interval, just move the highlight
1930 /* Else, we have to change the time interval. We have to tell it
1931 * to the main window. */
1932 /* The time interval change will take care of placing the current
1933 * time at the center of the visible area, or nearest possible if we are
1934 * at one end of the trace. */
1937 if(ltt_time_compare(current_time
, time_begin
) == -1)
1939 TimeWindow new_time_window
;
1941 if(ltt_time_compare(current_time
,
1942 ltt_time_add(trace_start
,half_width
)) == -1)
1943 time_begin
= trace_start
;
1945 time_begin
= ltt_time_sub(current_time
,half_width
);
1947 new_time_window
.start_time
= time_begin
;
1948 new_time_window
.time_width
= width
;
1950 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1952 else if(ltt_time_compare(current_time
, time_end
) == 1)
1954 TimeWindow new_time_window
;
1956 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1957 time_begin
= ltt_time_sub(trace_end
,width
);
1959 time_begin
= ltt_time_sub(current_time
,half_width
);
1961 new_time_window
.start_time
= time_begin
;
1962 new_time_window
.time_width
= width
;
1964 lttvwindow_report_time_window(control_flow_data
->tab
, &new_time_window
);
1967 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1968 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1976 typedef struct _ClosureData
{
1977 EventsRequest
*events_request
;
1978 LttvTracesetState
*tss
;
1983 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1990 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1991 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1992 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1994 ControlFlowData
*control_flow_data
=
1995 closure_data
->events_request
->viewer_data
;
1997 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1999 /* Get y position of process */
2002 processlist_get_pixels_from_data( control_flow_data
->process_list
,
2004 hashed_process_data
,
2007 /* Get last state of process */
2008 LttvTraceContext
*tc
=
2009 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
2010 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)closure_data
->tss
;
2012 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
2013 LttvProcessState
*process
;
2015 /* We do not provide a cpu_name argument assuming that this is not the
2016 idle job (pid 0) and thus its pid is unique across all cpus */
2017 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
2019 /* Draw the closing line */
2020 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
2021 if(draw_context
->previous
->middle
->x
== -1)
2023 draw_context
->previous
->over
->x
=
2024 control_flow_data
->drawing
->damage_begin
;
2025 draw_context
->previous
->middle
->x
=
2026 control_flow_data
->drawing
->damage_begin
;
2027 draw_context
->previous
->under
->x
=
2028 control_flow_data
->drawing
->damage_begin
;
2030 g_debug("out middle x_beg : %u",control_flow_data
->drawing
->damage_begin
);
2033 /* Find pixels corresponding to current time . If the time does
2034 * not fit in the window, show a warning, not supposed to happend. */
2036 guint width
= control_flow_data
->drawing
->width
;
2038 TimeWindow time_window
=
2039 lttvwindow_get_time_window(control_flow_data
->tab
);
2041 LttTime time
= lttv_traceset_context_get_current_tfc(tsc
)->timestamp
;
2043 LttTime window_end
= ltt_time_add(time_window
.time_width
,
2044 time_window
.start_time
);
2046 convert_time_to_pixels(
2047 time_window
.start_time
,
2053 draw_context
->current
->middle
->x
= x
;
2054 draw_context
->current
->over
->x
= x
;
2055 draw_context
->current
->under
->x
= x
;
2056 draw_context
->current
->middle
->y
= y
+ height
/2;
2057 draw_context
->current
->over
->y
= y
;
2058 draw_context
->current
->under
->y
= y
+ height
;
2059 draw_context
->previous
->middle
->y
= y
+ height
/2;
2060 draw_context
->previous
->over
->y
= y
;
2061 draw_context
->previous
->under
->y
= y
+ height
;
2062 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
2063 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
2064 //draw_context->gc = widget->style->black_gc;
2065 //draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
2066 //gdk_gc_copy(draw_context->gc, widget->style->black_gc);
2067 draw_context
->gc
= control_flow_data
->drawing
->gc
;
2069 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
2071 PropertiesBG prop_bg
;
2072 prop_bg
.color
= g_new(GdkColor
,1);
2074 /*switch(tfc->index) {
2076 prop_bg.color->red = 0x1515;
2077 prop_bg.color->green = 0x1515;
2078 prop_bg.color->blue = 0x8c8c;
2081 prop_bg.color->red = 0x4e4e;
2082 prop_bg.color->green = 0xa9a9;
2083 prop_bg.color->blue = 0xa4a4;
2086 prop_bg.color->red = 0x7a7a;
2087 prop_bg.color->green = 0x4a4a;
2088 prop_bg.color->blue = 0x8b8b;
2091 prop_bg.color->red = 0x8080;
2092 prop_bg.color->green = 0x7777;
2093 prop_bg.color->blue = 0x4747;
2096 prop_bg.color->red = 0xe7e7;
2097 prop_bg.color->green = 0xe7e7;
2098 prop_bg.color->blue = 0xe7e7;
2102 g_debug("calling from closure");
2103 //FIXME : I need the cpu number in process's state to draw this.
2104 //draw_bg((void*)&prop_bg, (void*)draw_context);
2105 g_free(prop_bg
.color
);
2109 PropertiesLine prop_line
;
2110 prop_line
.color
= g_new(GdkColor
,1);
2111 prop_line
.line_width
= 2;
2112 prop_line
.style
= GDK_LINE_SOLID
;
2113 prop_line
.position
= MIDDLE
;
2115 /* color of line : status of the process */
2118 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
2120 prop_line
.color
->red
= 0xffff;
2121 prop_line
.color
->green
= 0xffff;
2122 prop_line
.color
->blue
= 0xffff;
2124 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
2126 prop_line
.color
->red
= 0x0fff;
2127 prop_line
.color
->green
= 0xffff;
2128 prop_line
.color
->blue
= 0xfff0;
2130 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
2132 prop_line
.color
->red
= 0xffff;
2133 prop_line
.color
->green
= 0xffff;
2134 prop_line
.color
->blue
= 0x0000;
2136 else if(process
->state
->s
== LTTV_STATE_EXIT
)
2138 prop_line
.color
->red
= 0xffff;
2139 prop_line
.color
->green
= 0x0000;
2140 prop_line
.color
->blue
= 0xffff;
2142 else if(process
->state
->s
== LTTV_STATE_WAIT
)
2144 prop_line
.color
->red
= 0xffff;
2145 prop_line
.color
->green
= 0x0000;
2146 prop_line
.color
->blue
= 0x0000;
2148 else if(process
->state
->s
== LTTV_STATE_RUN
)
2150 prop_line
.color
->red
= 0x0000;
2151 prop_line
.color
->green
= 0xffff;
2152 prop_line
.color
->blue
= 0x0000;
2156 prop_line
.color
->red
= 0xffff;
2157 prop_line
.color
->green
= 0xffff;
2158 prop_line
.color
->blue
= 0xffff;
2164 prop_line
.color
->red
= 0xffff;
2165 prop_line
.color
->green
= 0xffff;
2166 prop_line
.color
->blue
= 0xffff;
2169 draw_line((void*)&prop_line
, (void*)draw_context
);
2170 g_free(prop_line
.color
);
2171 //gdk_gc_unref(draw_context->gc);
2173 /* Reset draw_context of the process for next request */
2175 hashed_process_data
->draw_context
->drawable
= NULL
;
2176 hashed_process_data
->draw_context
->gc
= NULL
;
2177 hashed_process_data
->draw_context
->pango_layout
= NULL
;
2178 hashed_process_data
->draw_context
->current
->over
->x
= -1;
2179 hashed_process_data
->draw_context
->current
->over
->y
= -1;
2180 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
2181 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
2182 hashed_process_data
->draw_context
->current
->under
->x
= -1;
2183 hashed_process_data
->draw_context
->current
->under
->y
= -1;
2184 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
2185 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
2186 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
2187 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
2188 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
2189 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
2190 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
2191 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
2192 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
2193 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
2194 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
2195 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
2196 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
2197 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
2198 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
2199 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
2200 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
2201 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
2202 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
2203 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
2208 int before_chunk(void *hook_data
, void *call_data
)
2210 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2211 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2213 drawing_chunk_begin(events_request
, tss
);
2218 int before_request(void *hook_data
, void *call_data
)
2220 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2221 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2223 drawing_data_request_begin(events_request
, tss
);
2230 * after request is necessary in addition of after chunk in order to draw
2231 * lines until the end of the screen. after chunk just draws lines until
2238 int after_request(void *hook_data
, void *call_data
)
2240 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2241 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
2242 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2243 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(call_data
);
2245 ProcessList
*process_list
=
2246 guicontrolflow_get_process_list(control_flow_data
);
2247 LttTime end_time
= events_request
->end_time
;
2249 ClosureData closure_data
;
2250 closure_data
.events_request
= (EventsRequest
*)hook_data
;
2251 closure_data
.tss
= tss
;
2252 closure_data
.end_time
= end_time
;
2254 /* Draw last items */
2255 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
2256 (void*)&closure_data
);
2258 /* Request expose */
2259 drawing_request_expose(events_request
, tss
, end_time
);
2268 int after_chunk(void *hook_data
, void *call_data
)
2270 EventsRequest
*events_request
= (EventsRequest
*)hook_data
;
2271 ControlFlowData
*control_flow_data
= events_request
->viewer_data
;
2272 LttvTracesetState
*tss
= LTTV_TRACESET_STATE(call_data
);
2273 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(call_data
);
2274 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
2277 ProcessList
*process_list
=
2278 guicontrolflow_get_process_list(control_flow_data
);
2281 && ltt_time_compare(tfc
->timestamp
, events_request
->end_time
) <= 0)
2282 end_time
= tfc
->timestamp
;
2283 else /* end of traceset, or position now out of request : end */
2284 end_time
= events_request
->end_time
;
2286 ClosureData closure_data
;
2287 closure_data
.events_request
= (EventsRequest
*)hook_data
;
2288 closure_data
.tss
= tss
;
2289 closure_data
.end_time
= end_time
;
2291 /* Draw last items */
2292 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
2293 (void*)&closure_data
);
2295 /* Request expose */
2296 drawing_request_expose(events_request
, tss
, end_time
);