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 <lttvwindow/common.h>
42 #include <lttv/state.h>
43 #include <lttvwindow/viewer.h>
46 #include "eventhooks.h"
48 #include "processlist.h"
50 #include "cfv-private.h"
53 #define MAX_PATH_LEN 256
57 * Event Viewer's constructor hook
59 * This constructor is given as a parameter to the menuitem and toolbar button
60 * registration. It creates the list.
61 * @param mw A pointer to the parent window.
62 * @return The widget created.
65 h_guicontrolflow(MainWindow
*mw
, LttvTracesetSelector
* s
, char * key
)
67 g_info("h_guicontrolflow, %p, %p, %s", mw
, s
, key
);
68 ControlFlowData
*control_flow_data
= guicontrolflow() ;
70 control_flow_data
->mw
= mw
;
72 //g_debug("time width2 : %u",time_window->time_width);
73 // Unreg done in the GuiControlFlow_Destructor
74 lttvwindow_register_time_window_notify(mw
,
75 update_time_window_hook
,
77 lttvwindow_register_current_time_notify(mw
,
78 update_current_time_hook
,
80 return guicontrolflow_get_widget(control_flow_data
) ;
84 int event_selected_hook(void *hook_data
, void *call_data
)
86 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
87 guint
*event_number
= (guint
*) call_data
;
89 g_debug("DEBUG : event selected by main window : %u", *event_number
);
91 // control_flow_data->currently_Selected_Event = *event_number;
92 // control_flow_data->Selected_Event = TRUE ;
94 // tree_v_set_cursor(control_flow_data);
98 /* Hook called before drawing. Gets the initial context at the beginning of the
99 * drawing interval and copy it to the context in event_request.
101 int draw_before_hook(void *hook_data
, void *call_data
)
103 EventRequest
*event_request
= (EventRequest
*)hook_data
;
104 //EventsContext Events_Context = (EventsContext*)call_data;
106 //event_request->Events_Context = Events_Context;
112 * The draw event hook is called by the reading API to have a
113 * particular event drawn on the screen.
114 * @param hook_data ControlFlowData structure of the viewer.
115 * @param call_data Event context.
117 * This function basically draw lines and icons. Two types of lines are drawn :
118 * one small (3 pixels?) representing the state of the process and the second
119 * type is thicker (10 pixels?) representing on which CPU a process is running
120 * (and this only in running state).
122 * Extremums of the lines :
123 * x_min : time of the last event context for this process kept in memory.
124 * x_max : time of the current event.
125 * y : middle of the process in the process list. The process is found in the
126 * list, therefore is it's position in pixels.
128 * The choice of lines'color is defined by the context of the last event for this
131 int draw_event_hook(void *hook_data
, void *call_data
)
133 EventRequest
*event_request
= (EventRequest
*)hook_data
;
134 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
135 MainWindow
*mw
= control_flow_data
->mw
;
137 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
139 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
140 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
145 LttTime evtime
= ltt_event_time(e
);
146 const TimeWindow
*time_window
=
147 lttvwindow_get_time_window(mw
);
149 LttTime end_time
= ltt_time_add(time_window
->start_time
,
150 time_window
->time_width
);
151 //if(time < time_beg || time > time_end) return;
152 if(ltt_time_compare(evtime
, time_window
->start_time
) == -1
153 || ltt_time_compare(evtime
, end_time
) == 1)
156 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
158 g_debug("schedchange!");
160 /* Add process to process list (if not present) and get drawing "y" from
161 * process position */
162 guint pid_out
, pid_in
;
163 LttvProcessState
*process_out
, *process_in
;
165 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
167 ProcessList
*process_list
=
168 guicontrolflow_get_process_list(event_request
->control_flow_data
);
171 LttField
*f
= ltt_event_field(e
);
173 element
= ltt_field_member(f
,0);
174 pid_out
= ltt_event_get_long_unsigned(e
,element
);
175 element
= ltt_field_member(f
,1);
176 pid_in
= ltt_event_get_long_unsigned(e
,element
);
177 g_debug("out : %u in : %u", pid_out
, pid_in
);
180 /* Find process pid_out in the list... */
181 process_out
= lttv_state_find_process(tfs
, pid_out
);
182 if(process_out
== NULL
) return 0;
183 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
185 birth
= process_out
->creation_time
;
186 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
187 HashedProcessData
*hashed_process_data_out
= NULL
;
189 if(processlist_get_process_pixels(process_list
,
192 tfc
->t_context
->index
,
195 &hashed_process_data_out
) == 1)
197 /* Process not present */
198 processlist_add(process_list
,
201 tfc
->t_context
->index
,
204 &hashed_process_data_out
);
205 processlist_get_process_pixels(process_list
,
208 tfc
->t_context
->index
,
211 &hashed_process_data_out
);
212 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_out
, height
);
217 /* Find process pid_in in the list... */
218 process_in
= lttv_state_find_process(tfs
, pid_in
);
219 if(process_in
== NULL
) return 0;
220 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
222 birth
= process_in
->creation_time
;
223 name
= strdup(g_quark_to_string(process_in
->name
));
224 HashedProcessData
*hashed_process_data_in
= NULL
;
226 if(processlist_get_process_pixels(process_list
,
229 tfc
->t_context
->index
,
232 &hashed_process_data_in
) == 1)
234 /* Process not present */
235 processlist_add(process_list
,
238 tfc
->t_context
->index
,
241 &hashed_process_data_in
);
242 processlist_get_process_pixels(process_list
,
245 tfc
->t_context
->index
,
248 &hashed_process_data_in
);
250 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_in
, height
);
255 /* Find pixels corresponding to time of the event. If the time does
256 * not fit in the window, show a warning, not supposed to happend. */
258 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
260 LttTime time
= ltt_event_time(e
);
262 LttTime window_end
= ltt_time_add(time_window
->time_width
,
263 time_window
->start_time
);
266 convert_time_to_pixels(
267 time_window
->start_time
,
272 //assert(x <= width);
274 /* draw what represents the event for outgoing process. */
276 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
277 draw_context_out
->current
->modify_over
->x
= x
;
278 draw_context_out
->current
->modify_under
->x
= x
;
279 draw_context_out
->current
->modify_over
->y
= y_out
;
280 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
281 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
282 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
283 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
284 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
285 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
286 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
287 //draw_context_out->gc = widget->style->black_gc;
289 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
290 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
292 /* Draw the line/background of the out process */
293 if(draw_context_out
->previous
->middle
->x
== -1)
295 draw_context_out
->previous
->over
->x
= event_request
->x_begin
;
296 draw_context_out
->previous
->middle
->x
= event_request
->x_begin
;
297 draw_context_out
->previous
->under
->x
= event_request
->x_begin
;
299 g_debug("out middle x_beg : %u",event_request
->x_begin
);
302 draw_context_out
->current
->middle
->x
= x
;
303 draw_context_out
->current
->over
->x
= x
;
304 draw_context_out
->current
->under
->x
= x
;
305 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
306 draw_context_out
->current
->over
->y
= y_out
;
307 draw_context_out
->current
->under
->y
= y_out
+ height
;
308 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
309 draw_context_out
->previous
->over
->y
= y_out
;
310 draw_context_out
->previous
->under
->y
= y_out
+ height
;
312 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
313 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
315 if(process_out
->state
->s
== LTTV_STATE_RUN
)
317 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
318 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
320 PropertiesBG prop_bg
;
321 prop_bg
.color
= g_new(GdkColor
,1);
325 prop_bg
.color
->red
= 0x1515;
326 prop_bg
.color
->green
= 0x1515;
327 prop_bg
.color
->blue
= 0x8c8c;
330 prop_bg
.color
->red
= 0x4e4e;
331 prop_bg
.color
->green
= 0xa9a9;
332 prop_bg
.color
->blue
= 0xa4a4;
335 prop_bg
.color
->red
= 0x7a7a;
336 prop_bg
.color
->green
= 0x4a4a;
337 prop_bg
.color
->blue
= 0x8b8b;
340 prop_bg
.color
->red
= 0x8080;
341 prop_bg
.color
->green
= 0x7777;
342 prop_bg
.color
->blue
= 0x4747;
345 prop_bg
.color
->red
= 0xe7e7;
346 prop_bg
.color
->green
= 0xe7e7;
347 prop_bg
.color
->blue
= 0xe7e7;
350 g_debug("calling from draw_event");
351 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
352 g_free(prop_bg
.color
);
353 gdk_gc_unref(draw_context_out
->gc
);
356 draw_context_out
->gc
= widget
->style
->black_gc
;
358 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
359 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
360 PropertiesText prop_text_out
;
361 prop_text_out
.foreground
= &colorfg_out
;
362 prop_text_out
.background
= &colorbg_out
;
363 prop_text_out
.size
= 6;
364 prop_text_out
.position
= OVER
;
366 /* color of text : status of the process */
367 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
369 prop_text_out
.foreground
->red
= 0xffff;
370 prop_text_out
.foreground
->green
= 0xffff;
371 prop_text_out
.foreground
->blue
= 0xffff;
373 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
375 prop_text_out
.foreground
->red
= 0x0fff;
376 prop_text_out
.foreground
->green
= 0xffff;
377 prop_text_out
.foreground
->blue
= 0xfff0;
379 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
381 prop_text_out
.foreground
->red
= 0xffff;
382 prop_text_out
.foreground
->green
= 0xffff;
383 prop_text_out
.foreground
->blue
= 0x0000;
385 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
387 prop_text_out
.foreground
->red
= 0xffff;
388 prop_text_out
.foreground
->green
= 0x0000;
389 prop_text_out
.foreground
->blue
= 0xffff;
391 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
393 prop_text_out
.foreground
->red
= 0xffff;
394 prop_text_out
.foreground
->green
= 0x0000;
395 prop_text_out
.foreground
->blue
= 0x0000;
397 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
399 prop_text_out
.foreground
->red
= 0x0000;
400 prop_text_out
.foreground
->green
= 0xffff;
401 prop_text_out
.foreground
->blue
= 0x0000;
405 prop_text_out
.foreground
->red
= 0xffff;
406 prop_text_out
.foreground
->green
= 0xffff;
407 prop_text_out
.foreground
->blue
= 0xffff;
411 /* Print status of the process : U, WF, WC, E, W, R */
412 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
413 prop_text_out
.text
= "U->";
414 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
415 prop_text_out
.text
= "WF->";
416 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
417 prop_text_out
.text
= "WC->";
418 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
419 prop_text_out
.text
= "E->";
420 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
421 prop_text_out
.text
= "W->";
422 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
423 prop_text_out
.text
= "R->";
425 prop_text_out
.text
= "U";
427 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
428 //gdk_gc_unref(draw_context_out->gc);
430 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
431 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
433 PropertiesLine prop_line_out
;
434 prop_line_out
.color
= g_new(GdkColor
,1);
435 prop_line_out
.line_width
= 2;
436 prop_line_out
.style
= GDK_LINE_SOLID
;
437 prop_line_out
.position
= MIDDLE
;
439 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
441 /* color of line : status of the process */
442 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
444 prop_line_out
.color
->red
= 0xffff;
445 prop_line_out
.color
->green
= 0xffff;
446 prop_line_out
.color
->blue
= 0xffff;
448 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
450 prop_line_out
.color
->red
= 0x0fff;
451 prop_line_out
.color
->green
= 0xffff;
452 prop_line_out
.color
->blue
= 0xfff0;
454 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
456 prop_line_out
.color
->red
= 0xffff;
457 prop_line_out
.color
->green
= 0xffff;
458 prop_line_out
.color
->blue
= 0x0000;
460 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
462 prop_line_out
.color
->red
= 0xffff;
463 prop_line_out
.color
->green
= 0x0000;
464 prop_line_out
.color
->blue
= 0xffff;
466 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
468 prop_line_out
.color
->red
= 0xffff;
469 prop_line_out
.color
->green
= 0x0000;
470 prop_line_out
.color
->blue
= 0x0000;
472 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
474 prop_line_out
.color
->red
= 0x0000;
475 prop_line_out
.color
->green
= 0xffff;
476 prop_line_out
.color
->blue
= 0x0000;
480 prop_line_out
.color
->red
= 0xffff;
481 prop_line_out
.color
->green
= 0xffff;
482 prop_line_out
.color
->blue
= 0xffff;
485 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
486 g_free(prop_line_out
.color
);
487 gdk_gc_unref(draw_context_out
->gc
);
488 /* Note : finishing line will have to be added when trace read over. */
490 /* Finally, update the drawing context of the pid_in. */
492 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
493 draw_context_in
->current
->modify_over
->x
= x
;
494 draw_context_in
->current
->modify_under
->x
= x
;
495 draw_context_in
->current
->modify_over
->y
= y_in
;
496 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
497 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
498 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
499 widget
= control_flow_data
->drawing
->drawing_area
;
500 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
501 //draw_context_in->gc = widget->style->black_gc;
502 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
503 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
505 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
506 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
508 /* Draw the line/bg of the in process */
509 if(draw_context_in
->previous
->middle
->x
== -1)
511 draw_context_in
->previous
->middle
->x
= event_request
->x_begin
;
512 draw_context_in
->previous
->over
->x
= event_request
->x_begin
;
513 draw_context_in
->previous
->under
->x
= event_request
->x_begin
;
514 g_debug("in middle x_beg : %u",event_request
->x_begin
);
517 draw_context_in
->current
->middle
->x
= x
;
518 draw_context_in
->current
->over
->x
= x
;
519 draw_context_in
->current
->under
->x
= x
;
520 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
521 draw_context_in
->current
->over
->y
= y_in
;
522 draw_context_in
->current
->under
->y
= y_in
+ height
;
523 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
524 draw_context_in
->previous
->over
->y
= y_in
;
525 draw_context_in
->previous
->under
->y
= y_in
+ height
;
527 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
528 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
531 if(process_in
->state
->s
== LTTV_STATE_RUN
)
533 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
534 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
536 PropertiesBG prop_bg
;
537 prop_bg
.color
= g_new(GdkColor
,1);
541 prop_bg
.color
->red
= 0x1515;
542 prop_bg
.color
->green
= 0x1515;
543 prop_bg
.color
->blue
= 0x8c8c;
546 prop_bg
.color
->red
= 0x4e4e;
547 prop_bg
.color
->green
= 0xa9a9;
548 prop_bg
.color
->blue
= 0xa4a4;
551 prop_bg
.color
->red
= 0x7a7a;
552 prop_bg
.color
->green
= 0x4a4a;
553 prop_bg
.color
->blue
= 0x8b8b;
556 prop_bg
.color
->red
= 0x8080;
557 prop_bg
.color
->green
= 0x7777;
558 prop_bg
.color
->blue
= 0x4747;
561 prop_bg
.color
->red
= 0xe7e7;
562 prop_bg
.color
->green
= 0xe7e7;
563 prop_bg
.color
->blue
= 0xe7e7;
567 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
568 g_free(prop_bg
.color
);
569 gdk_gc_unref(draw_context_in
->gc
);
572 draw_context_in
->gc
= widget
->style
->black_gc
;
574 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
575 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
576 PropertiesText prop_text_in
;
577 prop_text_in
.foreground
= &colorfg_in
;
578 prop_text_in
.background
= &colorbg_in
;
579 prop_text_in
.size
= 6;
580 prop_text_in
.position
= OVER
;
582 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
583 /* foreground of text : status of the process */
584 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
586 prop_text_in
.foreground
->red
= 0xffff;
587 prop_text_in
.foreground
->green
= 0xffff;
588 prop_text_in
.foreground
->blue
= 0xffff;
590 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
592 prop_text_in
.foreground
->red
= 0x0fff;
593 prop_text_in
.foreground
->green
= 0xffff;
594 prop_text_in
.foreground
->blue
= 0xfff0;
596 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
598 prop_text_in
.foreground
->red
= 0xffff;
599 prop_text_in
.foreground
->green
= 0xffff;
600 prop_text_in
.foreground
->blue
= 0x0000;
602 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
604 prop_text_in
.foreground
->red
= 0xffff;
605 prop_text_in
.foreground
->green
= 0x0000;
606 prop_text_in
.foreground
->blue
= 0xffff;
608 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
610 prop_text_in
.foreground
->red
= 0xffff;
611 prop_text_in
.foreground
->green
= 0x0000;
612 prop_text_in
.foreground
->blue
= 0x0000;
614 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
616 prop_text_in
.foreground
->red
= 0x0000;
617 prop_text_in
.foreground
->green
= 0xffff;
618 prop_text_in
.foreground
->blue
= 0x0000;
622 prop_text_in
.foreground
->red
= 0xffff;
623 prop_text_in
.foreground
->green
= 0xffff;
624 prop_text_in
.foreground
->blue
= 0xffff;
629 /* Print status of the process : U, WF, WC, E, W, R */
630 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
631 prop_text_in
.text
= "U->";
632 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
633 prop_text_in
.text
= "WF->";
634 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
635 prop_text_in
.text
= "WC->";
636 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
637 prop_text_in
.text
= "E->";
638 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
639 prop_text_in
.text
= "W->";
640 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
641 prop_text_in
.text
= "R->";
643 prop_text_in
.text
= "U";
645 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
646 //gdk_gc_unref(draw_context_in->gc);
648 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
649 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
651 PropertiesLine prop_line_in
;
652 prop_line_in
.color
= g_new(GdkColor
,1);
653 prop_line_in
.line_width
= 2;
654 prop_line_in
.style
= GDK_LINE_SOLID
;
655 prop_line_in
.position
= MIDDLE
;
657 /* color of line : status of the process */
658 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
660 prop_line_in
.color
->red
= 0xffff;
661 prop_line_in
.color
->green
= 0xffff;
662 prop_line_in
.color
->blue
= 0xffff;
664 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
666 prop_line_in
.color
->red
= 0x0fff;
667 prop_line_in
.color
->green
= 0xffff;
668 prop_line_in
.color
->blue
= 0xfff0;
670 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
672 prop_line_in
.color
->red
= 0xffff;
673 prop_line_in
.color
->green
= 0xffff;
674 prop_line_in
.color
->blue
= 0x0000;
676 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
678 prop_line_in
.color
->red
= 0xffff;
679 prop_line_in
.color
->green
= 0x0000;
680 prop_line_in
.color
->blue
= 0xffff;
682 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
684 prop_line_in
.color
->red
= 0xffff;
685 prop_line_in
.color
->green
= 0x0000;
686 prop_line_in
.color
->blue
= 0x0000;
688 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
690 prop_line_in
.color
->red
= 0x0000;
691 prop_line_in
.color
->green
= 0xffff;
692 prop_line_in
.color
->blue
= 0x0000;
696 prop_line_in
.color
->red
= 0xffff;
697 prop_line_in
.color
->green
= 0xffff;
698 prop_line_in
.color
->blue
= 0xffff;
701 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
702 g_free(prop_line_in
.color
);
703 gdk_gc_unref(draw_context_in
->gc
);
710 GString
*string
= g_string_new("");;
711 gboolean field_names
= TRUE
, state
= TRUE
;
713 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
714 g_string_append_printf(string
,"\n");
717 g_string_append_printf(string
, " %s",
718 g_quark_to_string(tfs
->process
->state
->s
));
721 g_info("%s",string
->str
);
723 g_string_free(string
, TRUE
);
725 /* End of text dump */
731 int draw_after_hook(void *hook_data
, void *call_data
)
733 EventRequest
*event_request
= (EventRequest
*)hook_data
;
734 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
736 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
738 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
739 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
745 LttTime evtime
= ltt_event_time(e
);
746 const TimeWindow
*time_window
=
747 lttvwindow_get_time_window(control_flow_data
->mw
);
749 LttTime end_time
= ltt_time_add(time_window
->start_time
,
750 time_window
->time_width
);
751 //if(time < time_beg || time > time_end) return;
752 if(ltt_time_compare(evtime
, time_window
->start_time
) == -1
753 || ltt_time_compare(evtime
, end_time
) == 1)
757 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
759 g_debug("schedchange!");
761 /* Add process to process list (if not present) and get drawing "y" from
762 * process position */
763 guint pid_out
, pid_in
;
764 LttvProcessState
*process_out
, *process_in
;
766 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
768 ProcessList
*process_list
=
769 guicontrolflow_get_process_list(event_request
->control_flow_data
);
772 LttField
*f
= ltt_event_field(e
);
774 element
= ltt_field_member(f
,0);
775 pid_out
= ltt_event_get_long_unsigned(e
,element
);
776 element
= ltt_field_member(f
,1);
777 pid_in
= ltt_event_get_long_unsigned(e
,element
);
778 //g_debug("out : %u in : %u", pid_out, pid_in);
781 /* Find process pid_out in the list... */
782 process_out
= lttv_state_find_process(tfs
, pid_out
);
783 if(process_out
== NULL
) return 0;
784 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
786 birth
= process_out
->creation_time
;
787 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
788 HashedProcessData
*hashed_process_data_out
= NULL
;
790 if(processlist_get_process_pixels(process_list
,
793 tfc
->t_context
->index
,
796 &hashed_process_data_out
) == 1)
798 /* Process not present */
799 processlist_add(process_list
,
802 tfc
->t_context
->index
,
805 &hashed_process_data_out
);
806 processlist_get_process_pixels(process_list
,
809 tfc
->t_context
->index
,
812 &hashed_process_data_out
);
813 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_out
, height
);
818 /* Find process pid_in in the list... */
819 process_in
= lttv_state_find_process(tfs
, pid_in
);
820 if(process_in
== NULL
) return 0;
821 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
823 birth
= process_in
->creation_time
;
824 name
= strdup(g_quark_to_string(process_in
->name
));
825 HashedProcessData
*hashed_process_data_in
= NULL
;
827 if(processlist_get_process_pixels(process_list
,
830 tfc
->t_context
->index
,
833 &hashed_process_data_in
) == 1)
835 /* Process not present */
836 processlist_add(process_list
,
839 tfc
->t_context
->index
,
842 &hashed_process_data_in
);
843 processlist_get_process_pixels(process_list
,
846 tfc
->t_context
->index
,
849 &hashed_process_data_in
);
851 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_in
, height
);
856 /* Find pixels corresponding to time of the event. If the time does
857 * not fit in the window, show a warning, not supposed to happend. */
859 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
861 //LttTime time = ltt_event_time(e);
863 //LttTime window_end = ltt_time_add(time_window->time_width,
864 // time_window->start_time);
867 //convert_time_to_pixels(
868 // time_window->start_time,
874 //assert(x <= width);
876 /* draw what represents the event for outgoing process. */
878 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
879 //draw_context_out->current->modify_over->x = x;
880 draw_context_out
->current
->modify_over
->y
= y_out
;
881 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
882 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
883 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
884 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
885 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
887 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
888 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
890 /*if(process_out->state->s == LTTV_STATE_RUN)
892 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
893 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
894 PropertiesBG prop_bg;
895 prop_bg.color = g_new(GdkColor,1);
897 prop_bg.color->red = 0xffff;
898 prop_bg.color->green = 0xffff;
899 prop_bg.color->blue = 0xffff;
901 draw_bg((void*)&prop_bg, (void*)draw_context_out);
902 g_free(prop_bg.color);
903 gdk_gc_unref(draw_context_out->gc);
906 draw_context_out
->gc
= widget
->style
->black_gc
;
908 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
909 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
910 PropertiesText prop_text_out
;
911 prop_text_out
.foreground
= &colorfg_out
;
912 prop_text_out
.background
= &colorbg_out
;
913 prop_text_out
.size
= 6;
914 prop_text_out
.position
= OVER
;
916 /* color of text : status of the process */
917 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
919 prop_text_out
.foreground
->red
= 0xffff;
920 prop_text_out
.foreground
->green
= 0xffff;
921 prop_text_out
.foreground
->blue
= 0xffff;
923 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
925 prop_text_out
.foreground
->red
= 0x0fff;
926 prop_text_out
.foreground
->green
= 0xffff;
927 prop_text_out
.foreground
->blue
= 0xfff0;
929 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
931 prop_text_out
.foreground
->red
= 0xffff;
932 prop_text_out
.foreground
->green
= 0xffff;
933 prop_text_out
.foreground
->blue
= 0x0000;
935 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
937 prop_text_out
.foreground
->red
= 0xffff;
938 prop_text_out
.foreground
->green
= 0x0000;
939 prop_text_out
.foreground
->blue
= 0xffff;
941 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
943 prop_text_out
.foreground
->red
= 0xffff;
944 prop_text_out
.foreground
->green
= 0x0000;
945 prop_text_out
.foreground
->blue
= 0x0000;
947 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
949 prop_text_out
.foreground
->red
= 0x0000;
950 prop_text_out
.foreground
->green
= 0xffff;
951 prop_text_out
.foreground
->blue
= 0x0000;
955 prop_text_out
.foreground
->red
= 0xffff;
956 prop_text_out
.foreground
->green
= 0xffff;
957 prop_text_out
.foreground
->blue
= 0xffff;
960 /* Print status of the process : U, WF, WC, E, W, R */
961 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
962 prop_text_out
.text
= "U";
963 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
964 prop_text_out
.text
= "WF";
965 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
966 prop_text_out
.text
= "WC";
967 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
968 prop_text_out
.text
= "E";
969 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
970 prop_text_out
.text
= "W";
971 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
972 prop_text_out
.text
= "R";
974 prop_text_out
.text
= "U";
976 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
978 //gdk_gc_unref(draw_context_out->gc);
980 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
981 draw_context_out
->current
->over
->y
= y_out
;
982 draw_context_out
->current
->under
->y
= y_out
+height
;
983 draw_context_out
->current
->status
= process_out
->state
->s
;
985 /* for pid_out : remove previous, Prev = current, new current (default) */
986 g_free(draw_context_out
->previous
->modify_under
);
987 g_free(draw_context_out
->previous
->modify_middle
);
988 g_free(draw_context_out
->previous
->modify_over
);
989 g_free(draw_context_out
->previous
->under
);
990 g_free(draw_context_out
->previous
->middle
);
991 g_free(draw_context_out
->previous
->over
);
992 g_free(draw_context_out
->previous
);
994 draw_context_out
->previous
= draw_context_out
->current
;
996 draw_context_out
->current
= g_new(DrawInfo
,1);
997 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
998 draw_context_out
->current
->over
->x
= -1;
999 draw_context_out
->current
->over
->y
= -1;
1000 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1001 draw_context_out
->current
->middle
->x
= -1;
1002 draw_context_out
->current
->middle
->y
= -1;
1003 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1004 draw_context_out
->current
->under
->x
= -1;
1005 draw_context_out
->current
->under
->y
= -1;
1006 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1007 draw_context_out
->current
->modify_over
->x
= -1;
1008 draw_context_out
->current
->modify_over
->y
= -1;
1009 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1010 draw_context_out
->current
->modify_middle
->x
= -1;
1011 draw_context_out
->current
->modify_middle
->y
= -1;
1012 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1013 draw_context_out
->current
->modify_under
->x
= -1;
1014 draw_context_out
->current
->modify_under
->y
= -1;
1015 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1017 /* Finally, update the drawing context of the pid_in. */
1019 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1020 //draw_context_in->current->modify_over->x = x;
1021 draw_context_in
->current
->modify_over
->y
= y_in
;
1022 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1023 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1024 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1025 widget
= control_flow_data
->drawing
->drawing_area
;
1026 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1028 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1029 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1031 /*if(process_in->state->s == LTTV_STATE_RUN)
1033 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1034 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1035 PropertiesBG prop_bg;
1036 prop_bg.color = g_new(GdkColor,1);
1038 prop_bg.color->red = 0xffff;
1039 prop_bg.color->green = 0xffff;
1040 prop_bg.color->blue = 0xffff;
1042 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1043 g_free(prop_bg.color);
1044 gdk_gc_unref(draw_context_in->gc);
1047 draw_context_in
->gc
= widget
->style
->black_gc
;
1049 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1050 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1051 PropertiesText prop_text_in
;
1052 prop_text_in
.foreground
= &colorfg_in
;
1053 prop_text_in
.background
= &colorbg_in
;
1054 prop_text_in
.size
= 6;
1055 prop_text_in
.position
= OVER
;
1057 /* foreground of text : status of the process */
1058 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1060 prop_text_in
.foreground
->red
= 0xffff;
1061 prop_text_in
.foreground
->green
= 0xffff;
1062 prop_text_in
.foreground
->blue
= 0xffff;
1064 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1066 prop_text_in
.foreground
->red
= 0x0fff;
1067 prop_text_in
.foreground
->green
= 0xffff;
1068 prop_text_in
.foreground
->blue
= 0xfff0;
1070 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1072 prop_text_in
.foreground
->red
= 0xffff;
1073 prop_text_in
.foreground
->green
= 0xffff;
1074 prop_text_in
.foreground
->blue
= 0x0000;
1076 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1078 prop_text_in
.foreground
->red
= 0xffff;
1079 prop_text_in
.foreground
->green
= 0x0000;
1080 prop_text_in
.foreground
->blue
= 0xffff;
1082 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1084 prop_text_in
.foreground
->red
= 0xffff;
1085 prop_text_in
.foreground
->green
= 0x0000;
1086 prop_text_in
.foreground
->blue
= 0x0000;
1088 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1090 prop_text_in
.foreground
->red
= 0x0000;
1091 prop_text_in
.foreground
->green
= 0xffff;
1092 prop_text_in
.foreground
->blue
= 0x0000;
1096 prop_text_in
.foreground
->red
= 0xffff;
1097 prop_text_in
.foreground
->green
= 0xffff;
1098 prop_text_in
.foreground
->blue
= 0xffff;
1102 /* Print status of the process : U, WF, WC, E, W, R */
1103 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1104 prop_text_in
.text
= "U";
1105 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1106 prop_text_in
.text
= "WF";
1107 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1108 prop_text_in
.text
= "WC";
1109 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1110 prop_text_in
.text
= "E";
1111 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1112 prop_text_in
.text
= "W";
1113 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1114 prop_text_in
.text
= "R";
1116 prop_text_in
.text
= "U";
1118 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1121 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1124 prop_text_in
.foreground
= &colorfg_in
;
1125 prop_text_in
.background
= &colorbg_in
;
1126 prop_text_in
.foreground
->red
= 0xffff;
1127 prop_text_in
.foreground
->green
= 0xffff;
1128 prop_text_in
.foreground
->blue
= 0xffff;
1129 prop_text_in
.size
= 6;
1130 prop_text_in
.position
= UNDER
;
1132 prop_text_in
.text
= g_new(gchar
, 260);
1133 strcpy(prop_text_in
.text
, "CPU ");
1134 snprintf(tmp
, 255, "%u", tfc
->index
);
1135 strcat(prop_text_in
.text
, tmp
);
1137 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1138 g_free(prop_text_in
.text
);
1142 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1143 draw_context_in
->current
->over
->y
= y_in
;
1144 draw_context_in
->current
->under
->y
= y_in
+height
;
1145 draw_context_in
->current
->status
= process_in
->state
->s
;
1147 /* for pid_in : remove previous, Prev = current, new current (default) */
1148 g_free(draw_context_in
->previous
->modify_under
);
1149 g_free(draw_context_in
->previous
->modify_middle
);
1150 g_free(draw_context_in
->previous
->modify_over
);
1151 g_free(draw_context_in
->previous
->under
);
1152 g_free(draw_context_in
->previous
->middle
);
1153 g_free(draw_context_in
->previous
->over
);
1154 g_free(draw_context_in
->previous
);
1156 draw_context_in
->previous
= draw_context_in
->current
;
1158 draw_context_in
->current
= g_new(DrawInfo
,1);
1159 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1160 draw_context_in
->current
->over
->x
= -1;
1161 draw_context_in
->current
->over
->y
= -1;
1162 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1163 draw_context_in
->current
->middle
->x
= -1;
1164 draw_context_in
->current
->middle
->y
= -1;
1165 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1166 draw_context_in
->current
->under
->x
= -1;
1167 draw_context_in
->current
->under
->y
= -1;
1168 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1169 draw_context_in
->current
->modify_over
->x
= -1;
1170 draw_context_in
->current
->modify_over
->y
= -1;
1171 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1172 draw_context_in
->current
->modify_middle
->x
= -1;
1173 draw_context_in
->current
->modify_middle
->y
= -1;
1174 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1175 draw_context_in
->current
->modify_under
->x
= -1;
1176 draw_context_in
->current
->modify_under
->y
= -1;
1177 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1187 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1189 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1190 Drawing_t
*drawing
= control_flow_data
->drawing
;
1192 const TimeWindowNotifyData
*time_window_nofify_data
=
1193 ((const TimeWindowNotifyData
*)call_data
);
1195 TimeWindow
*old_time_window
=
1196 time_window_nofify_data
->old_time_window
;
1197 TimeWindow
*new_time_window
=
1198 time_window_nofify_data
->new_time_window
;
1200 /* Update the ruler */
1201 drawing_update_ruler(control_flow_data
->drawing
,
1205 /* Two cases : zoom in/out or scrolling */
1207 /* In order to make sure we can reuse the old drawing, the scale must
1208 * be the same and the new time interval being partly located in the
1209 * currently shown time interval. (reuse is only for scrolling)
1212 g_info("Old time window HOOK : %u, %u to %u, %u",
1213 old_time_window
->start_time
.tv_sec
,
1214 old_time_window
->start_time
.tv_nsec
,
1215 old_time_window
->time_width
.tv_sec
,
1216 old_time_window
->time_width
.tv_nsec
);
1218 g_info("New time window HOOK : %u, %u to %u, %u",
1219 new_time_window
->start_time
.tv_sec
,
1220 new_time_window
->start_time
.tv_nsec
,
1221 new_time_window
->time_width
.tv_sec
,
1222 new_time_window
->time_width
.tv_nsec
);
1224 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1225 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1227 /* Same scale (scrolling) */
1228 g_info("scrolling");
1229 LttTime
*ns
= &new_time_window
->start_time
;
1230 LttTime
*os
= &old_time_window
->start_time
;
1231 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1232 old_time_window
->time_width
);
1233 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1234 new_time_window
->time_width
);
1236 //if(ns<os+w && os+w<ns+w)
1237 //if(ns<old_end && os<ns)
1238 if(ltt_time_compare(*ns
, old_end
) == -1
1239 && ltt_time_compare(*os
, *ns
) == -1)
1241 g_info("scrolling near right");
1242 /* Scroll right, keep right part of the screen */
1244 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1245 convert_time_to_pixels(
1252 /* Copy old data to new location */
1253 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1254 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1255 control_flow_data
->drawing
->pixmap
,
1260 /* Clear the data request background, but not SAFETY */
1261 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1262 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1265 control_flow_data
->drawing
->width
- x
, // do not overlap
1266 control_flow_data
->drawing
->height
+SAFETY
);
1268 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1270 control_flow_data
->drawing
->width
- x
,
1271 control_flow_data
->drawing
->height
);
1273 /* Get new data for the rest. */
1274 drawing_data_request(control_flow_data
->drawing
,
1275 &control_flow_data
->drawing
->pixmap
,
1277 control_flow_data
->drawing
->width
- x
,
1278 control_flow_data
->drawing
->height
);
1282 //if(ns<os && os<ns+w)
1283 //if(ns<os && os<new_end)
1284 if(ltt_time_compare(*ns
,*os
) == -1
1285 && ltt_time_compare(*os
,new_end
) == -1)
1287 g_info("scrolling near left");
1288 /* Scroll left, keep left part of the screen */
1290 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1291 convert_time_to_pixels(
1298 /* Copy old data to new location */
1299 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1300 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1301 control_flow_data
->drawing
->pixmap
,
1306 *old_time_window
= *new_time_window
;
1308 /* Clean the data request background */
1309 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1310 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1313 x
, // do not overlap
1314 control_flow_data
->drawing
->height
+SAFETY
);
1316 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1318 control_flow_data
->drawing
->width
- x
,
1319 control_flow_data
->drawing
->height
);
1321 /* Get new data for the rest. */
1322 drawing_data_request(control_flow_data
->drawing
,
1323 &control_flow_data
->drawing
->pixmap
,
1326 control_flow_data
->drawing
->height
);
1329 if(ltt_time_compare(*ns
,*os
) == 0)
1331 g_info("not scrolling");
1333 g_info("scrolling far");
1334 /* Cannot reuse any part of the screen : far jump */
1337 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1338 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1341 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1342 control_flow_data
->drawing
->height
+SAFETY
);
1344 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1346 control_flow_data
->drawing
->width
,
1347 control_flow_data
->drawing
->height
);
1349 drawing_data_request(control_flow_data
->drawing
,
1350 &control_flow_data
->drawing
->pixmap
,
1352 control_flow_data
->drawing
->width
,
1353 control_flow_data
->drawing
->height
);
1359 /* Different scale (zoom) */
1362 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1363 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1366 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1367 control_flow_data
->drawing
->height
+SAFETY
);
1369 gtk_widget_queue_draw_area (drawing
->drawing_area
,
1371 control_flow_data
->drawing
->width
,
1372 control_flow_data
->drawing
->height
);
1374 drawing_data_request(control_flow_data
->drawing
,
1375 &control_flow_data
->drawing
->pixmap
,
1377 control_flow_data
->drawing
->width
,
1378 control_flow_data
->drawing
->height
);
1387 gint
after_process_traceset_hook(void *hook_data
, void *call_data
)
1389 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1390 TimeRequest
*time_request
= (TimeRequest
*)call_data
;
1392 drawing_data_request_end(control_flow_data
->drawing
,
1393 time_request
->time_window
);
1399 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1401 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1402 Drawing_t
*drawing
= control_flow_data
->drawing
;
1404 LttTime current_time
= *((LttTime
*)call_data
);
1406 const TimeWindow
*time_window
=
1407 lttvwindow_get_time_window(control_flow_data
->mw
);
1409 LttTime time_begin
= time_window
->start_time
;
1410 LttTime width
= time_window
->time_width
;
1411 LttTime half_width
= ltt_time_div(width
,2.0);
1412 LttTime time_end
= ltt_time_add(time_begin
, width
);
1414 LttvTracesetContext
* tsc
=
1415 lttvwindow_get_traceset_context(control_flow_data
->mw
);
1417 LttTime trace_start
= tsc
->Time_Span
->startTime
;
1418 LttTime trace_end
= tsc
->Time_Span
->endTime
;
1420 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
1421 current_time
.tv_nsec
);
1425 /* If current time is inside time interval, just move the highlight
1428 /* Else, we have to change the time interval. We have to tell it
1429 * to the main window. */
1430 /* The time interval change will take care of placing the current
1431 * time at the center of the visible area, or nearest possible if we are
1432 * at one end of the trace. */
1435 if(ltt_time_compare(current_time
, time_begin
) == -1)
1437 TimeWindow new_time_window
;
1439 if(ltt_time_compare(current_time
,
1440 ltt_time_add(trace_start
,half_width
)) == -1)
1441 time_begin
= trace_start
;
1443 time_begin
= ltt_time_sub(current_time
,half_width
);
1445 new_time_window
.start_time
= time_begin
;
1446 new_time_window
.time_width
= width
;
1448 lttvwindow_report_time_window(control_flow_data
->mw
, &new_time_window
);
1450 else if(ltt_time_compare(current_time
, time_end
) == 1)
1452 TimeWindow new_time_window
;
1454 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1455 time_begin
= ltt_time_sub(trace_end
,width
);
1457 time_begin
= ltt_time_sub(current_time
,half_width
);
1459 new_time_window
.start_time
= time_begin
;
1460 new_time_window
.time_width
= width
;
1462 lttvwindow_report_time_window(control_flow_data
->mw
, &new_time_window
);
1465 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1466 gtk_widget_queue_draw_area(drawing
->drawing_area
,
1474 typedef struct _ClosureData
{
1475 EventRequest
*event_request
;
1476 LttvTracesetState
*tss
;
1480 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1482 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1483 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1484 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1486 ControlFlowData
*control_flow_data
=
1487 closure_data
->event_request
->control_flow_data
;
1489 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1491 /* Get y position of process */
1494 processlist_get_pixels_from_data( control_flow_data
->process_list
,
1496 hashed_process_data
,
1499 /* Get last state of process */
1500 LttvTraceContext
*tc
=
1501 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
1502 //LttvTracefileContext *tfc = (LttvTracefileContext *)closure_data->ts;
1504 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
1505 LttvProcessState
*process
;
1507 /* We do not provide a cpu_name argument assuming that this is not the
1508 idle job (pid 0) and thus its pid is unique across all cpus */
1509 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
1511 /* Draw the closing line */
1512 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
1513 if(draw_context
->previous
->middle
->x
== -1)
1515 draw_context
->previous
->middle
->x
= closure_data
->event_request
->x_begin
;
1516 draw_context
->previous
->over
->x
= closure_data
->event_request
->x_begin
;
1517 draw_context
->previous
->under
->x
= closure_data
->event_request
->x_begin
;
1518 g_debug("out middle x_beg : %u",closure_data
->event_request
->x_begin
);
1521 draw_context
->current
->middle
->x
= closure_data
->event_request
->x_end
;
1522 draw_context
->current
->over
->x
= closure_data
->event_request
->x_end
;
1523 draw_context
->current
->under
->x
= closure_data
->event_request
->x_end
;
1524 draw_context
->current
->middle
->y
= y
+ height
/2;
1525 draw_context
->current
->over
->y
= y
;
1526 draw_context
->current
->under
->y
= y
+ height
;
1527 draw_context
->previous
->middle
->y
= y
+ height
/2;
1528 draw_context
->previous
->over
->y
= y
;
1529 draw_context
->previous
->under
->y
= y
+ height
;
1530 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
1531 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1532 //draw_context->gc = widget->style->black_gc;
1533 draw_context
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
1534 gdk_gc_copy(draw_context
->gc
, widget
->style
->black_gc
);
1536 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
1538 PropertiesBG prop_bg
;
1539 prop_bg
.color
= g_new(GdkColor
,1);
1541 /*switch(tfc->index) {
1543 prop_bg.color->red = 0x1515;
1544 prop_bg.color->green = 0x1515;
1545 prop_bg.color->blue = 0x8c8c;
1548 prop_bg.color->red = 0x4e4e;
1549 prop_bg.color->green = 0xa9a9;
1550 prop_bg.color->blue = 0xa4a4;
1553 prop_bg.color->red = 0x7a7a;
1554 prop_bg.color->green = 0x4a4a;
1555 prop_bg.color->blue = 0x8b8b;
1558 prop_bg.color->red = 0x8080;
1559 prop_bg.color->green = 0x7777;
1560 prop_bg.color->blue = 0x4747;
1563 prop_bg.color->red = 0xe7e7;
1564 prop_bg.color->green = 0xe7e7;
1565 prop_bg.color->blue = 0xe7e7;
1569 g_debug("calling from closure");
1570 //FIXME : I need the cpu number in process's state to draw this.
1571 //draw_bg((void*)&prop_bg, (void*)draw_context);
1572 g_free(prop_bg
.color
);
1576 PropertiesLine prop_line
;
1577 prop_line
.color
= g_new(GdkColor
,1);
1578 prop_line
.line_width
= 2;
1579 prop_line
.style
= GDK_LINE_SOLID
;
1580 prop_line
.position
= MIDDLE
;
1582 /* color of line : status of the process */
1585 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
1587 prop_line
.color
->red
= 0xffff;
1588 prop_line
.color
->green
= 0xffff;
1589 prop_line
.color
->blue
= 0xffff;
1591 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
1593 prop_line
.color
->red
= 0x0fff;
1594 prop_line
.color
->green
= 0xffff;
1595 prop_line
.color
->blue
= 0xfff0;
1597 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
1599 prop_line
.color
->red
= 0xffff;
1600 prop_line
.color
->green
= 0xffff;
1601 prop_line
.color
->blue
= 0x0000;
1603 else if(process
->state
->s
== LTTV_STATE_EXIT
)
1605 prop_line
.color
->red
= 0xffff;
1606 prop_line
.color
->green
= 0x0000;
1607 prop_line
.color
->blue
= 0xffff;
1609 else if(process
->state
->s
== LTTV_STATE_WAIT
)
1611 prop_line
.color
->red
= 0xffff;
1612 prop_line
.color
->green
= 0x0000;
1613 prop_line
.color
->blue
= 0x0000;
1615 else if(process
->state
->s
== LTTV_STATE_RUN
)
1617 prop_line
.color
->red
= 0x0000;
1618 prop_line
.color
->green
= 0xffff;
1619 prop_line
.color
->blue
= 0x0000;
1623 prop_line
.color
->red
= 0xffff;
1624 prop_line
.color
->green
= 0xffff;
1625 prop_line
.color
->blue
= 0xffff;
1631 prop_line
.color
->red
= 0xffff;
1632 prop_line
.color
->green
= 0xffff;
1633 prop_line
.color
->blue
= 0xffff;
1636 draw_line((void*)&prop_line
, (void*)draw_context
);
1637 g_free(prop_line
.color
);
1638 gdk_gc_unref(draw_context
->gc
);
1640 /* Reset draw_context of the process for next request */
1642 hashed_process_data
->draw_context
->drawable
= NULL
;
1643 hashed_process_data
->draw_context
->gc
= NULL
;
1644 hashed_process_data
->draw_context
->pango_layout
= NULL
;
1645 hashed_process_data
->draw_context
->current
->over
->x
= -1;
1646 hashed_process_data
->draw_context
->current
->over
->y
= -1;
1647 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
1648 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
1649 hashed_process_data
->draw_context
->current
->under
->x
= -1;
1650 hashed_process_data
->draw_context
->current
->under
->y
= -1;
1651 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
1652 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
1653 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
1654 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
1655 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
1656 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
1657 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
1658 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
1659 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
1660 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
1661 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
1662 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
1663 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
1664 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
1665 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
1666 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
1667 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
1668 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
1669 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
1670 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
1678 * new default prev and current
1679 * then finally remove reading hooks.
1681 int after_data_request(void *hook_data
, void *call_data
)
1683 EventRequest
*event_request
= (EventRequest
*)hook_data
;
1684 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
1686 ProcessList
*process_list
=
1687 guicontrolflow_get_process_list(event_request
->control_flow_data
);
1689 ClosureData closure_data
;
1690 closure_data
.event_request
= (EventRequest
*)hook_data
;
1691 closure_data
.tss
= (LttvTracesetState
*)call_data
;
1693 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
1694 (void*)&closure_data
);
1696 /* Remove reading hooks */
1697 // Cannot do this here, will break processtrace!
1698 //drawing_data_request_end(control_flow_data->drawing);