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
;
136 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
138 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
139 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
144 LttTime evtime
= ltt_event_time(e
);
145 const TimeWindow
*time_window
=
146 lttvwindow_get_time_window(control_flow_data
->mw
);
148 LttTime end_time
= ltt_time_add(time_window
->start_time
,
149 time_window
->time_width
);
150 //if(time < time_beg || time > time_end) return;
151 if(ltt_time_compare(evtime
, time_window
->start_time
) == -1
152 || ltt_time_compare(evtime
, end_time
) == 1)
155 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
157 g_debug("schedchange!");
159 /* Add process to process list (if not present) and get drawing "y" from
160 * process position */
161 guint pid_out
, pid_in
;
162 LttvProcessState
*process_out
, *process_in
;
164 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
166 ProcessList
*process_list
=
167 guicontrolflow_get_process_list(event_request
->control_flow_data
);
170 LttField
*f
= ltt_event_field(e
);
172 element
= ltt_field_member(f
,0);
173 pid_out
= ltt_event_get_long_unsigned(e
,element
);
174 element
= ltt_field_member(f
,1);
175 pid_in
= ltt_event_get_long_unsigned(e
,element
);
176 g_debug("out : %u in : %u", pid_out
, pid_in
);
179 /* Find process pid_out in the list... */
180 process_out
= lttv_state_find_process(tfs
, pid_out
);
181 if(process_out
== NULL
) return 0;
182 g_debug("out : %s",g_quark_to_string(process_out
->state
->s
));
184 birth
= process_out
->creation_time
;
185 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
186 HashedProcessData
*hashed_process_data_out
= NULL
;
188 if(processlist_get_process_pixels(process_list
,
191 tfc
->t_context
->index
,
194 &hashed_process_data_out
) == 1)
196 /* Process not present */
197 processlist_add(process_list
,
200 tfc
->t_context
->index
,
203 &hashed_process_data_out
);
204 processlist_get_process_pixels(process_list
,
207 tfc
->t_context
->index
,
210 &hashed_process_data_out
);
211 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_out
, height
);
216 /* Find process pid_in in the list... */
217 process_in
= lttv_state_find_process(tfs
, pid_in
);
218 if(process_in
== NULL
) return 0;
219 g_debug("in : %s",g_quark_to_string(process_in
->state
->s
));
221 birth
= process_in
->creation_time
;
222 name
= strdup(g_quark_to_string(process_in
->name
));
223 HashedProcessData
*hashed_process_data_in
= NULL
;
225 if(processlist_get_process_pixels(process_list
,
228 tfc
->t_context
->index
,
231 &hashed_process_data_in
) == 1)
233 /* Process not present */
234 processlist_add(process_list
,
237 tfc
->t_context
->index
,
240 &hashed_process_data_in
);
241 processlist_get_process_pixels(process_list
,
244 tfc
->t_context
->index
,
247 &hashed_process_data_in
);
249 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_in
, height
);
254 /* Find pixels corresponding to time of the event. If the time does
255 * not fit in the window, show a warning, not supposed to happend. */
257 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
259 LttTime time
= ltt_event_time(e
);
261 LttTime window_end
= ltt_time_add(time_window
->time_width
,
262 time_window
->start_time
);
265 convert_time_to_pixels(
266 time_window
->start_time
,
271 //assert(x <= width);
273 /* draw what represents the event for outgoing process. */
275 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
276 draw_context_out
->current
->modify_over
->x
= x
;
277 draw_context_out
->current
->modify_under
->x
= x
;
278 draw_context_out
->current
->modify_over
->y
= y_out
;
279 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
280 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
281 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
282 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
283 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
284 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
285 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
286 //draw_context_out->gc = widget->style->black_gc;
288 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
289 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
291 /* Draw the line/background of the out process */
292 if(draw_context_out
->previous
->middle
->x
== -1)
294 draw_context_out
->previous
->over
->x
= event_request
->x_begin
;
295 draw_context_out
->previous
->middle
->x
= event_request
->x_begin
;
296 draw_context_out
->previous
->under
->x
= event_request
->x_begin
;
298 g_debug("out middle x_beg : %u",event_request
->x_begin
);
301 draw_context_out
->current
->middle
->x
= x
;
302 draw_context_out
->current
->over
->x
= x
;
303 draw_context_out
->current
->under
->x
= x
;
304 draw_context_out
->current
->middle
->y
= y_out
+ height
/2;
305 draw_context_out
->current
->over
->y
= y_out
;
306 draw_context_out
->current
->under
->y
= y_out
+ height
;
307 draw_context_out
->previous
->middle
->y
= y_out
+ height
/2;
308 draw_context_out
->previous
->over
->y
= y_out
;
309 draw_context_out
->previous
->under
->y
= y_out
+ height
;
311 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
312 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
314 if(process_out
->state
->s
== LTTV_STATE_RUN
)
316 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
317 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
319 PropertiesBG prop_bg
;
320 prop_bg
.color
= g_new(GdkColor
,1);
324 prop_bg
.color
->red
= 0x1515;
325 prop_bg
.color
->green
= 0x1515;
326 prop_bg
.color
->blue
= 0x8c8c;
329 prop_bg
.color
->red
= 0x4e4e;
330 prop_bg
.color
->green
= 0xa9a9;
331 prop_bg
.color
->blue
= 0xa4a4;
334 prop_bg
.color
->red
= 0x7a7a;
335 prop_bg
.color
->green
= 0x4a4a;
336 prop_bg
.color
->blue
= 0x8b8b;
339 prop_bg
.color
->red
= 0x8080;
340 prop_bg
.color
->green
= 0x7777;
341 prop_bg
.color
->blue
= 0x4747;
344 prop_bg
.color
->red
= 0xe7e7;
345 prop_bg
.color
->green
= 0xe7e7;
346 prop_bg
.color
->blue
= 0xe7e7;
349 g_debug("calling from draw_event");
350 draw_bg((void*)&prop_bg
, (void*)draw_context_out
);
351 g_free(prop_bg
.color
);
352 gdk_gc_unref(draw_context_out
->gc
);
355 draw_context_out
->gc
= widget
->style
->black_gc
;
357 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
358 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
359 PropertiesText prop_text_out
;
360 prop_text_out
.foreground
= &colorfg_out
;
361 prop_text_out
.background
= &colorbg_out
;
362 prop_text_out
.size
= 6;
363 prop_text_out
.position
= OVER
;
365 /* color of text : status of the process */
366 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
368 prop_text_out
.foreground
->red
= 0xffff;
369 prop_text_out
.foreground
->green
= 0xffff;
370 prop_text_out
.foreground
->blue
= 0xffff;
372 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
374 prop_text_out
.foreground
->red
= 0x0fff;
375 prop_text_out
.foreground
->green
= 0xffff;
376 prop_text_out
.foreground
->blue
= 0xfff0;
378 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
380 prop_text_out
.foreground
->red
= 0xffff;
381 prop_text_out
.foreground
->green
= 0xffff;
382 prop_text_out
.foreground
->blue
= 0x0000;
384 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
386 prop_text_out
.foreground
->red
= 0xffff;
387 prop_text_out
.foreground
->green
= 0x0000;
388 prop_text_out
.foreground
->blue
= 0xffff;
390 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
392 prop_text_out
.foreground
->red
= 0xffff;
393 prop_text_out
.foreground
->green
= 0x0000;
394 prop_text_out
.foreground
->blue
= 0x0000;
396 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
398 prop_text_out
.foreground
->red
= 0x0000;
399 prop_text_out
.foreground
->green
= 0xffff;
400 prop_text_out
.foreground
->blue
= 0x0000;
404 prop_text_out
.foreground
->red
= 0xffff;
405 prop_text_out
.foreground
->green
= 0xffff;
406 prop_text_out
.foreground
->blue
= 0xffff;
410 /* Print status of the process : U, WF, WC, E, W, R */
411 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
412 prop_text_out
.text
= "U->";
413 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
414 prop_text_out
.text
= "WF->";
415 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
416 prop_text_out
.text
= "WC->";
417 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
418 prop_text_out
.text
= "E->";
419 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
420 prop_text_out
.text
= "W->";
421 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
422 prop_text_out
.text
= "R->";
424 prop_text_out
.text
= "U";
426 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
427 //gdk_gc_unref(draw_context_out->gc);
429 draw_context_out
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
430 gdk_gc_copy(draw_context_out
->gc
, widget
->style
->black_gc
);
432 PropertiesLine prop_line_out
;
433 prop_line_out
.color
= g_new(GdkColor
,1);
434 prop_line_out
.line_width
= 2;
435 prop_line_out
.style
= GDK_LINE_SOLID
;
436 prop_line_out
.position
= MIDDLE
;
438 g_debug("out state : %s", g_quark_to_string(process_out
->state
->s
));
440 /* color of line : status of the process */
441 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
443 prop_line_out
.color
->red
= 0xffff;
444 prop_line_out
.color
->green
= 0xffff;
445 prop_line_out
.color
->blue
= 0xffff;
447 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
449 prop_line_out
.color
->red
= 0x0fff;
450 prop_line_out
.color
->green
= 0xffff;
451 prop_line_out
.color
->blue
= 0xfff0;
453 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
455 prop_line_out
.color
->red
= 0xffff;
456 prop_line_out
.color
->green
= 0xffff;
457 prop_line_out
.color
->blue
= 0x0000;
459 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
461 prop_line_out
.color
->red
= 0xffff;
462 prop_line_out
.color
->green
= 0x0000;
463 prop_line_out
.color
->blue
= 0xffff;
465 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
467 prop_line_out
.color
->red
= 0xffff;
468 prop_line_out
.color
->green
= 0x0000;
469 prop_line_out
.color
->blue
= 0x0000;
471 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
473 prop_line_out
.color
->red
= 0x0000;
474 prop_line_out
.color
->green
= 0xffff;
475 prop_line_out
.color
->blue
= 0x0000;
479 prop_line_out
.color
->red
= 0xffff;
480 prop_line_out
.color
->green
= 0xffff;
481 prop_line_out
.color
->blue
= 0xffff;
484 draw_line((void*)&prop_line_out
, (void*)draw_context_out
);
485 g_free(prop_line_out
.color
);
486 gdk_gc_unref(draw_context_out
->gc
);
487 /* Note : finishing line will have to be added when trace read over. */
489 /* Finally, update the drawing context of the pid_in. */
491 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
492 draw_context_in
->current
->modify_over
->x
= x
;
493 draw_context_in
->current
->modify_under
->x
= x
;
494 draw_context_in
->current
->modify_over
->y
= y_in
;
495 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
496 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
497 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
498 widget
= control_flow_data
->drawing
->drawing_area
;
499 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
500 //draw_context_in->gc = widget->style->black_gc;
501 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
502 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
504 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
505 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
507 /* Draw the line/bg of the in process */
508 if(draw_context_in
->previous
->middle
->x
== -1)
510 draw_context_in
->previous
->middle
->x
= event_request
->x_begin
;
511 draw_context_in
->previous
->over
->x
= event_request
->x_begin
;
512 draw_context_in
->previous
->under
->x
= event_request
->x_begin
;
513 g_debug("in middle x_beg : %u",event_request
->x_begin
);
516 draw_context_in
->current
->middle
->x
= x
;
517 draw_context_in
->current
->over
->x
= x
;
518 draw_context_in
->current
->under
->x
= x
;
519 draw_context_in
->current
->middle
->y
= y_in
+ height
/2;
520 draw_context_in
->current
->over
->y
= y_in
;
521 draw_context_in
->current
->under
->y
= y_in
+ height
;
522 draw_context_in
->previous
->middle
->y
= y_in
+ height
/2;
523 draw_context_in
->previous
->over
->y
= y_in
;
524 draw_context_in
->previous
->under
->y
= y_in
+ height
;
526 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
527 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
530 if(process_in
->state
->s
== LTTV_STATE_RUN
)
532 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
533 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
535 PropertiesBG prop_bg
;
536 prop_bg
.color
= g_new(GdkColor
,1);
540 prop_bg
.color
->red
= 0x1515;
541 prop_bg
.color
->green
= 0x1515;
542 prop_bg
.color
->blue
= 0x8c8c;
545 prop_bg
.color
->red
= 0x4e4e;
546 prop_bg
.color
->green
= 0xa9a9;
547 prop_bg
.color
->blue
= 0xa4a4;
550 prop_bg
.color
->red
= 0x7a7a;
551 prop_bg
.color
->green
= 0x4a4a;
552 prop_bg
.color
->blue
= 0x8b8b;
555 prop_bg
.color
->red
= 0x8080;
556 prop_bg
.color
->green
= 0x7777;
557 prop_bg
.color
->blue
= 0x4747;
560 prop_bg
.color
->red
= 0xe7e7;
561 prop_bg
.color
->green
= 0xe7e7;
562 prop_bg
.color
->blue
= 0xe7e7;
566 draw_bg((void*)&prop_bg
, (void*)draw_context_in
);
567 g_free(prop_bg
.color
);
568 gdk_gc_unref(draw_context_in
->gc
);
571 draw_context_in
->gc
= widget
->style
->black_gc
;
573 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
574 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
575 PropertiesText prop_text_in
;
576 prop_text_in
.foreground
= &colorfg_in
;
577 prop_text_in
.background
= &colorbg_in
;
578 prop_text_in
.size
= 6;
579 prop_text_in
.position
= OVER
;
581 g_debug("in state : %s", g_quark_to_string(process_in
->state
->s
));
582 /* foreground of text : status of the process */
583 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
585 prop_text_in
.foreground
->red
= 0xffff;
586 prop_text_in
.foreground
->green
= 0xffff;
587 prop_text_in
.foreground
->blue
= 0xffff;
589 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
591 prop_text_in
.foreground
->red
= 0x0fff;
592 prop_text_in
.foreground
->green
= 0xffff;
593 prop_text_in
.foreground
->blue
= 0xfff0;
595 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
597 prop_text_in
.foreground
->red
= 0xffff;
598 prop_text_in
.foreground
->green
= 0xffff;
599 prop_text_in
.foreground
->blue
= 0x0000;
601 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
603 prop_text_in
.foreground
->red
= 0xffff;
604 prop_text_in
.foreground
->green
= 0x0000;
605 prop_text_in
.foreground
->blue
= 0xffff;
607 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
609 prop_text_in
.foreground
->red
= 0xffff;
610 prop_text_in
.foreground
->green
= 0x0000;
611 prop_text_in
.foreground
->blue
= 0x0000;
613 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
615 prop_text_in
.foreground
->red
= 0x0000;
616 prop_text_in
.foreground
->green
= 0xffff;
617 prop_text_in
.foreground
->blue
= 0x0000;
621 prop_text_in
.foreground
->red
= 0xffff;
622 prop_text_in
.foreground
->green
= 0xffff;
623 prop_text_in
.foreground
->blue
= 0xffff;
628 /* Print status of the process : U, WF, WC, E, W, R */
629 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
630 prop_text_in
.text
= "U->";
631 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
632 prop_text_in
.text
= "WF->";
633 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
634 prop_text_in
.text
= "WC->";
635 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
636 prop_text_in
.text
= "E->";
637 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
638 prop_text_in
.text
= "W->";
639 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
640 prop_text_in
.text
= "R->";
642 prop_text_in
.text
= "U";
644 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
645 //gdk_gc_unref(draw_context_in->gc);
647 draw_context_in
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
648 gdk_gc_copy(draw_context_in
->gc
, widget
->style
->black_gc
);
650 PropertiesLine prop_line_in
;
651 prop_line_in
.color
= g_new(GdkColor
,1);
652 prop_line_in
.line_width
= 2;
653 prop_line_in
.style
= GDK_LINE_SOLID
;
654 prop_line_in
.position
= MIDDLE
;
656 /* color of line : status of the process */
657 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
659 prop_line_in
.color
->red
= 0xffff;
660 prop_line_in
.color
->green
= 0xffff;
661 prop_line_in
.color
->blue
= 0xffff;
663 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
665 prop_line_in
.color
->red
= 0x0fff;
666 prop_line_in
.color
->green
= 0xffff;
667 prop_line_in
.color
->blue
= 0xfff0;
669 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
671 prop_line_in
.color
->red
= 0xffff;
672 prop_line_in
.color
->green
= 0xffff;
673 prop_line_in
.color
->blue
= 0x0000;
675 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
677 prop_line_in
.color
->red
= 0xffff;
678 prop_line_in
.color
->green
= 0x0000;
679 prop_line_in
.color
->blue
= 0xffff;
681 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
683 prop_line_in
.color
->red
= 0xffff;
684 prop_line_in
.color
->green
= 0x0000;
685 prop_line_in
.color
->blue
= 0x0000;
687 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
689 prop_line_in
.color
->red
= 0x0000;
690 prop_line_in
.color
->green
= 0xffff;
691 prop_line_in
.color
->blue
= 0x0000;
695 prop_line_in
.color
->red
= 0xffff;
696 prop_line_in
.color
->green
= 0xffff;
697 prop_line_in
.color
->blue
= 0xffff;
700 draw_line((void*)&prop_line_in
, (void*)draw_context_in
);
701 g_free(prop_line_in
.color
);
702 gdk_gc_unref(draw_context_in
->gc
);
709 GString
*string
= g_string_new("");;
710 gboolean field_names
= TRUE
, state
= TRUE
;
712 lttv_event_to_string(e
, tfc
->tf
, string
, TRUE
, field_names
, tfs
);
713 g_string_append_printf(string
,"\n");
716 g_string_append_printf(string
, " %s",
717 g_quark_to_string(tfs
->process
->state
->s
));
720 g_info("%s",string
->str
);
722 g_string_free(string
, TRUE
);
724 /* End of text dump */
730 int draw_after_hook(void *hook_data
, void *call_data
)
732 EventRequest
*event_request
= (EventRequest
*)hook_data
;
733 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
735 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
737 LttvTracefileState
*tfs
= (LttvTracefileState
*)call_data
;
738 LttvTraceState
*ts
=(LttvTraceState
*)LTTV_TRACEFILE_CONTEXT(tfs
)->t_context
;
744 LttTime evtime
= ltt_event_time(e
);
745 const TimeWindow
*time_window
=
746 lttvwindow_get_time_window(control_flow_data
->mw
);
748 LttTime end_time
= ltt_time_add(time_window
->start_time
,
749 time_window
->time_width
);
750 //if(time < time_beg || time > time_end) return;
751 if(ltt_time_compare(evtime
, time_window
->start_time
) == -1
752 || ltt_time_compare(evtime
, end_time
) == 1)
756 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e
)),"schedchange") == 0)
758 g_debug("schedchange!");
760 /* Add process to process list (if not present) and get drawing "y" from
761 * process position */
762 guint pid_out
, pid_in
;
763 LttvProcessState
*process_out
, *process_in
;
765 guint y_in
= 0, y_out
= 0, height
= 0, pl_height
= 0;
767 ProcessList
*process_list
=
768 guicontrolflow_get_process_list(event_request
->control_flow_data
);
771 LttField
*f
= ltt_event_field(e
);
773 element
= ltt_field_member(f
,0);
774 pid_out
= ltt_event_get_long_unsigned(e
,element
);
775 element
= ltt_field_member(f
,1);
776 pid_in
= ltt_event_get_long_unsigned(e
,element
);
777 //g_debug("out : %u in : %u", pid_out, pid_in);
780 /* Find process pid_out in the list... */
781 process_out
= lttv_state_find_process(tfs
, pid_out
);
782 if(process_out
== NULL
) return 0;
783 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
785 birth
= process_out
->creation_time
;
786 gchar
*name
= strdup(g_quark_to_string(process_out
->name
));
787 HashedProcessData
*hashed_process_data_out
= NULL
;
789 if(processlist_get_process_pixels(process_list
,
792 tfc
->t_context
->index
,
795 &hashed_process_data_out
) == 1)
797 /* Process not present */
798 processlist_add(process_list
,
801 tfc
->t_context
->index
,
804 &hashed_process_data_out
);
805 processlist_get_process_pixels(process_list
,
808 tfc
->t_context
->index
,
811 &hashed_process_data_out
);
812 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_out
, height
);
817 /* Find process pid_in in the list... */
818 process_in
= lttv_state_find_process(tfs
, pid_in
);
819 if(process_in
== NULL
) return 0;
820 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
822 birth
= process_in
->creation_time
;
823 name
= strdup(g_quark_to_string(process_in
->name
));
824 HashedProcessData
*hashed_process_data_in
= NULL
;
826 if(processlist_get_process_pixels(process_list
,
829 tfc
->t_context
->index
,
832 &hashed_process_data_in
) == 1)
834 /* Process not present */
835 processlist_add(process_list
,
838 tfc
->t_context
->index
,
841 &hashed_process_data_in
);
842 processlist_get_process_pixels(process_list
,
845 tfc
->t_context
->index
,
848 &hashed_process_data_in
);
850 drawing_insert_square( event_request
->control_flow_data
->drawing
, y_in
, height
);
855 /* Find pixels corresponding to time of the event. If the time does
856 * not fit in the window, show a warning, not supposed to happend. */
858 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
860 //LttTime time = ltt_event_time(e);
862 //LttTime window_end = ltt_time_add(time_window->time_width,
863 // time_window->start_time);
866 //convert_time_to_pixels(
867 // time_window->start_time,
873 //assert(x <= width);
875 /* draw what represents the event for outgoing process. */
877 DrawContext
*draw_context_out
= hashed_process_data_out
->draw_context
;
878 //draw_context_out->current->modify_over->x = x;
879 draw_context_out
->current
->modify_over
->y
= y_out
;
880 draw_context_out
->current
->modify_under
->y
= y_out
+(height
/2)+2;
881 draw_context_out
->drawable
= control_flow_data
->drawing
->pixmap
;
882 draw_context_out
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
883 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
884 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
886 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
887 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
889 /*if(process_out->state->s == LTTV_STATE_RUN)
891 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
892 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
893 PropertiesBG prop_bg;
894 prop_bg.color = g_new(GdkColor,1);
896 prop_bg.color->red = 0xffff;
897 prop_bg.color->green = 0xffff;
898 prop_bg.color->blue = 0xffff;
900 draw_bg((void*)&prop_bg, (void*)draw_context_out);
901 g_free(prop_bg.color);
902 gdk_gc_unref(draw_context_out->gc);
905 draw_context_out
->gc
= widget
->style
->black_gc
;
907 GdkColor colorfg_out
= { 0, 0xffff, 0x0000, 0x0000 };
908 GdkColor colorbg_out
= { 0, 0x0000, 0x0000, 0x0000 };
909 PropertiesText prop_text_out
;
910 prop_text_out
.foreground
= &colorfg_out
;
911 prop_text_out
.background
= &colorbg_out
;
912 prop_text_out
.size
= 6;
913 prop_text_out
.position
= OVER
;
915 /* color of text : status of the process */
916 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
918 prop_text_out
.foreground
->red
= 0xffff;
919 prop_text_out
.foreground
->green
= 0xffff;
920 prop_text_out
.foreground
->blue
= 0xffff;
922 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
924 prop_text_out
.foreground
->red
= 0x0fff;
925 prop_text_out
.foreground
->green
= 0xffff;
926 prop_text_out
.foreground
->blue
= 0xfff0;
928 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
930 prop_text_out
.foreground
->red
= 0xffff;
931 prop_text_out
.foreground
->green
= 0xffff;
932 prop_text_out
.foreground
->blue
= 0x0000;
934 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
936 prop_text_out
.foreground
->red
= 0xffff;
937 prop_text_out
.foreground
->green
= 0x0000;
938 prop_text_out
.foreground
->blue
= 0xffff;
940 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
942 prop_text_out
.foreground
->red
= 0xffff;
943 prop_text_out
.foreground
->green
= 0x0000;
944 prop_text_out
.foreground
->blue
= 0x0000;
946 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
948 prop_text_out
.foreground
->red
= 0x0000;
949 prop_text_out
.foreground
->green
= 0xffff;
950 prop_text_out
.foreground
->blue
= 0x0000;
954 prop_text_out
.foreground
->red
= 0xffff;
955 prop_text_out
.foreground
->green
= 0xffff;
956 prop_text_out
.foreground
->blue
= 0xffff;
959 /* Print status of the process : U, WF, WC, E, W, R */
960 if(process_out
->state
->s
== LTTV_STATE_UNNAMED
)
961 prop_text_out
.text
= "U";
962 else if(process_out
->state
->s
== LTTV_STATE_WAIT_FORK
)
963 prop_text_out
.text
= "WF";
964 else if(process_out
->state
->s
== LTTV_STATE_WAIT_CPU
)
965 prop_text_out
.text
= "WC";
966 else if(process_out
->state
->s
== LTTV_STATE_EXIT
)
967 prop_text_out
.text
= "E";
968 else if(process_out
->state
->s
== LTTV_STATE_WAIT
)
969 prop_text_out
.text
= "W";
970 else if(process_out
->state
->s
== LTTV_STATE_RUN
)
971 prop_text_out
.text
= "R";
973 prop_text_out
.text
= "U";
975 draw_text((void*)&prop_text_out
, (void*)draw_context_out
);
977 //gdk_gc_unref(draw_context_out->gc);
979 draw_context_out
->current
->middle
->y
= y_out
+height
/2;
980 draw_context_out
->current
->over
->y
= y_out
;
981 draw_context_out
->current
->under
->y
= y_out
+height
;
982 draw_context_out
->current
->status
= process_out
->state
->s
;
984 /* for pid_out : remove previous, Prev = current, new current (default) */
985 g_free(draw_context_out
->previous
->modify_under
);
986 g_free(draw_context_out
->previous
->modify_middle
);
987 g_free(draw_context_out
->previous
->modify_over
);
988 g_free(draw_context_out
->previous
->under
);
989 g_free(draw_context_out
->previous
->middle
);
990 g_free(draw_context_out
->previous
->over
);
991 g_free(draw_context_out
->previous
);
993 draw_context_out
->previous
= draw_context_out
->current
;
995 draw_context_out
->current
= g_new(DrawInfo
,1);
996 draw_context_out
->current
->over
= g_new(ItemInfo
,1);
997 draw_context_out
->current
->over
->x
= -1;
998 draw_context_out
->current
->over
->y
= -1;
999 draw_context_out
->current
->middle
= g_new(ItemInfo
,1);
1000 draw_context_out
->current
->middle
->x
= -1;
1001 draw_context_out
->current
->middle
->y
= -1;
1002 draw_context_out
->current
->under
= g_new(ItemInfo
,1);
1003 draw_context_out
->current
->under
->x
= -1;
1004 draw_context_out
->current
->under
->y
= -1;
1005 draw_context_out
->current
->modify_over
= g_new(ItemInfo
,1);
1006 draw_context_out
->current
->modify_over
->x
= -1;
1007 draw_context_out
->current
->modify_over
->y
= -1;
1008 draw_context_out
->current
->modify_middle
= g_new(ItemInfo
,1);
1009 draw_context_out
->current
->modify_middle
->x
= -1;
1010 draw_context_out
->current
->modify_middle
->y
= -1;
1011 draw_context_out
->current
->modify_under
= g_new(ItemInfo
,1);
1012 draw_context_out
->current
->modify_under
->x
= -1;
1013 draw_context_out
->current
->modify_under
->y
= -1;
1014 draw_context_out
->current
->status
= LTTV_STATE_UNNAMED
;
1016 /* Finally, update the drawing context of the pid_in. */
1018 DrawContext
*draw_context_in
= hashed_process_data_in
->draw_context
;
1019 //draw_context_in->current->modify_over->x = x;
1020 draw_context_in
->current
->modify_over
->y
= y_in
;
1021 draw_context_in
->current
->modify_under
->y
= y_in
+(height
/2)+2;
1022 draw_context_in
->drawable
= control_flow_data
->drawing
->pixmap
;
1023 draw_context_in
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1024 widget
= control_flow_data
->drawing
->drawing_area
;
1025 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1027 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1028 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1030 /*if(process_in->state->s == LTTV_STATE_RUN)
1032 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1033 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1034 PropertiesBG prop_bg;
1035 prop_bg.color = g_new(GdkColor,1);
1037 prop_bg.color->red = 0xffff;
1038 prop_bg.color->green = 0xffff;
1039 prop_bg.color->blue = 0xffff;
1041 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1042 g_free(prop_bg.color);
1043 gdk_gc_unref(draw_context_in->gc);
1046 draw_context_in
->gc
= widget
->style
->black_gc
;
1048 GdkColor colorfg_in
= { 0, 0x0000, 0xffff, 0x0000 };
1049 GdkColor colorbg_in
= { 0, 0x0000, 0x0000, 0x0000 };
1050 PropertiesText prop_text_in
;
1051 prop_text_in
.foreground
= &colorfg_in
;
1052 prop_text_in
.background
= &colorbg_in
;
1053 prop_text_in
.size
= 6;
1054 prop_text_in
.position
= OVER
;
1056 /* foreground of text : status of the process */
1057 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1059 prop_text_in
.foreground
->red
= 0xffff;
1060 prop_text_in
.foreground
->green
= 0xffff;
1061 prop_text_in
.foreground
->blue
= 0xffff;
1063 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1065 prop_text_in
.foreground
->red
= 0x0fff;
1066 prop_text_in
.foreground
->green
= 0xffff;
1067 prop_text_in
.foreground
->blue
= 0xfff0;
1069 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1071 prop_text_in
.foreground
->red
= 0xffff;
1072 prop_text_in
.foreground
->green
= 0xffff;
1073 prop_text_in
.foreground
->blue
= 0x0000;
1075 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1077 prop_text_in
.foreground
->red
= 0xffff;
1078 prop_text_in
.foreground
->green
= 0x0000;
1079 prop_text_in
.foreground
->blue
= 0xffff;
1081 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1083 prop_text_in
.foreground
->red
= 0xffff;
1084 prop_text_in
.foreground
->green
= 0x0000;
1085 prop_text_in
.foreground
->blue
= 0x0000;
1087 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1089 prop_text_in
.foreground
->red
= 0x0000;
1090 prop_text_in
.foreground
->green
= 0xffff;
1091 prop_text_in
.foreground
->blue
= 0x0000;
1095 prop_text_in
.foreground
->red
= 0xffff;
1096 prop_text_in
.foreground
->green
= 0xffff;
1097 prop_text_in
.foreground
->blue
= 0xffff;
1101 /* Print status of the process : U, WF, WC, E, W, R */
1102 if(process_in
->state
->s
== LTTV_STATE_UNNAMED
)
1103 prop_text_in
.text
= "U";
1104 else if(process_in
->state
->s
== LTTV_STATE_WAIT_FORK
)
1105 prop_text_in
.text
= "WF";
1106 else if(process_in
->state
->s
== LTTV_STATE_WAIT_CPU
)
1107 prop_text_in
.text
= "WC";
1108 else if(process_in
->state
->s
== LTTV_STATE_EXIT
)
1109 prop_text_in
.text
= "E";
1110 else if(process_in
->state
->s
== LTTV_STATE_WAIT
)
1111 prop_text_in
.text
= "W";
1112 else if(process_in
->state
->s
== LTTV_STATE_RUN
)
1113 prop_text_in
.text
= "R";
1115 prop_text_in
.text
= "U";
1117 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1120 if(process_in
->state
->s
== LTTV_STATE_RUN
)
1123 prop_text_in
.foreground
= &colorfg_in
;
1124 prop_text_in
.background
= &colorbg_in
;
1125 prop_text_in
.foreground
->red
= 0xffff;
1126 prop_text_in
.foreground
->green
= 0xffff;
1127 prop_text_in
.foreground
->blue
= 0xffff;
1128 prop_text_in
.size
= 6;
1129 prop_text_in
.position
= UNDER
;
1131 prop_text_in
.text
= g_new(gchar
, 260);
1132 strcpy(prop_text_in
.text
, "CPU ");
1133 snprintf(tmp
, 255, "%u", tfc
->index
);
1134 strcat(prop_text_in
.text
, tmp
);
1136 draw_text((void*)&prop_text_in
, (void*)draw_context_in
);
1137 g_free(prop_text_in
.text
);
1141 draw_context_in
->current
->middle
->y
= y_in
+height
/2;
1142 draw_context_in
->current
->over
->y
= y_in
;
1143 draw_context_in
->current
->under
->y
= y_in
+height
;
1144 draw_context_in
->current
->status
= process_in
->state
->s
;
1146 /* for pid_in : remove previous, Prev = current, new current (default) */
1147 g_free(draw_context_in
->previous
->modify_under
);
1148 g_free(draw_context_in
->previous
->modify_middle
);
1149 g_free(draw_context_in
->previous
->modify_over
);
1150 g_free(draw_context_in
->previous
->under
);
1151 g_free(draw_context_in
->previous
->middle
);
1152 g_free(draw_context_in
->previous
->over
);
1153 g_free(draw_context_in
->previous
);
1155 draw_context_in
->previous
= draw_context_in
->current
;
1157 draw_context_in
->current
= g_new(DrawInfo
,1);
1158 draw_context_in
->current
->over
= g_new(ItemInfo
,1);
1159 draw_context_in
->current
->over
->x
= -1;
1160 draw_context_in
->current
->over
->y
= -1;
1161 draw_context_in
->current
->middle
= g_new(ItemInfo
,1);
1162 draw_context_in
->current
->middle
->x
= -1;
1163 draw_context_in
->current
->middle
->y
= -1;
1164 draw_context_in
->current
->under
= g_new(ItemInfo
,1);
1165 draw_context_in
->current
->under
->x
= -1;
1166 draw_context_in
->current
->under
->y
= -1;
1167 draw_context_in
->current
->modify_over
= g_new(ItemInfo
,1);
1168 draw_context_in
->current
->modify_over
->x
= -1;
1169 draw_context_in
->current
->modify_over
->y
= -1;
1170 draw_context_in
->current
->modify_middle
= g_new(ItemInfo
,1);
1171 draw_context_in
->current
->modify_middle
->x
= -1;
1172 draw_context_in
->current
->modify_middle
->y
= -1;
1173 draw_context_in
->current
->modify_under
= g_new(ItemInfo
,1);
1174 draw_context_in
->current
->modify_under
->x
= -1;
1175 draw_context_in
->current
->modify_under
->y
= -1;
1176 draw_context_in
->current
->status
= LTTV_STATE_UNNAMED
;
1186 gint
update_time_window_hook(void *hook_data
, void *call_data
)
1188 ControlFlowData
*control_flow_data
= (ControlFlowData
*) hook_data
;
1189 const TimeWindowNotifyData
*time_window_nofify_data
=
1190 ((const TimeWindowNotifyData
*)call_data
);
1192 TimeWindow
*old_time_window
=
1193 time_window_nofify_data
->old_time_window
;
1194 TimeWindow
*new_time_window
=
1195 time_window_nofify_data
->new_time_window
;
1197 /* Update the ruler */
1198 drawing_update_ruler(control_flow_data
->drawing
,
1202 /* Two cases : zoom in/out or scrolling */
1204 /* In order to make sure we can reuse the old drawing, the scale must
1205 * be the same and the new time interval being partly located in the
1206 * currently shown time interval. (reuse is only for scrolling)
1209 g_info("Old time window HOOK : %u, %u to %u, %u",
1210 old_time_window
->start_time
.tv_sec
,
1211 old_time_window
->start_time
.tv_nsec
,
1212 old_time_window
->time_width
.tv_sec
,
1213 old_time_window
->time_width
.tv_nsec
);
1215 g_info("New time window HOOK : %u, %u to %u, %u",
1216 new_time_window
->start_time
.tv_sec
,
1217 new_time_window
->start_time
.tv_nsec
,
1218 new_time_window
->time_width
.tv_sec
,
1219 new_time_window
->time_width
.tv_nsec
);
1221 if( new_time_window
->time_width
.tv_sec
== old_time_window
->time_width
.tv_sec
1222 && new_time_window
->time_width
.tv_nsec
== old_time_window
->time_width
.tv_nsec
)
1224 /* Same scale (scrolling) */
1225 g_info("scrolling");
1226 LttTime
*ns
= &new_time_window
->start_time
;
1227 LttTime
*os
= &old_time_window
->start_time
;
1228 LttTime old_end
= ltt_time_add(old_time_window
->start_time
,
1229 old_time_window
->time_width
);
1230 LttTime new_end
= ltt_time_add(new_time_window
->start_time
,
1231 new_time_window
->time_width
);
1233 //if(ns<os+w && os+w<ns+w)
1234 //if(ns<old_end && os<ns)
1235 if(ltt_time_compare(*ns
, old_end
) == -1
1236 && ltt_time_compare(*os
, *ns
) == -1)
1238 g_info("scrolling near right");
1239 /* Scroll right, keep right part of the screen */
1241 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1242 convert_time_to_pixels(
1249 /* Copy old data to new location */
1250 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1251 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1252 control_flow_data
->drawing
->pixmap
,
1257 convert_time_to_pixels(
1264 *old_time_window
= *new_time_window
;
1265 /* Clear the data request background, but not SAFETY */
1266 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1267 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1270 control_flow_data
->drawing
->width
- x
, // do not overlap
1271 control_flow_data
->drawing
->height
+SAFETY
);
1272 /* Get new data for the rest. */
1273 drawing_data_request(control_flow_data
->drawing
,
1274 &control_flow_data
->drawing
->pixmap
,
1276 control_flow_data
->drawing
->width
- x
,
1277 control_flow_data
->drawing
->height
);
1279 drawing_refresh(control_flow_data
->drawing
,
1281 control_flow_data
->drawing
->width
,
1282 control_flow_data
->drawing
->height
);
1287 //if(ns<os && os<ns+w)
1288 //if(ns<os && os<new_end)
1289 if(ltt_time_compare(*ns
,*os
) == -1
1290 && ltt_time_compare(*os
,new_end
) == -1)
1292 g_info("scrolling near left");
1293 /* Scroll left, keep left part of the screen */
1295 guint width
= control_flow_data
->drawing
->drawing_area
->allocation
.width
;
1296 convert_time_to_pixels(
1303 /* Copy old data to new location */
1304 gdk_draw_drawable (control_flow_data
->drawing
->pixmap
,
1305 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1306 control_flow_data
->drawing
->pixmap
,
1311 //*old_time_window = *new_time_window;
1313 /* Clean the data request background */
1314 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1315 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1318 x
, // do not overlap
1319 control_flow_data
->drawing
->height
+SAFETY
);
1320 /* Get new data for the rest. */
1321 drawing_data_request(control_flow_data
->drawing
,
1322 &control_flow_data
->drawing
->pixmap
,
1325 control_flow_data
->drawing
->height
);
1327 drawing_refresh(control_flow_data
->drawing
,
1329 control_flow_data
->drawing
->width
,
1330 control_flow_data
->drawing
->height
);
1333 g_info("scrolling far");
1334 /* Cannot reuse any part of the screen : far jump */
1335 //*old_time_window = *new_time_window;
1338 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1339 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1342 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1343 control_flow_data
->drawing
->height
+SAFETY
);
1345 drawing_data_request(control_flow_data
->drawing
,
1346 &control_flow_data
->drawing
->pixmap
,
1348 control_flow_data
->drawing
->width
,
1349 control_flow_data
->drawing
->height
);
1351 drawing_refresh(control_flow_data
->drawing
,
1353 control_flow_data
->drawing
->width
,
1354 control_flow_data
->drawing
->height
);
1358 /* Different scale (zoom) */
1361 //*old_time_window = *new_time_window;
1363 gdk_draw_rectangle (control_flow_data
->drawing
->pixmap
,
1364 control_flow_data
->drawing
->drawing_area
->style
->black_gc
,
1367 control_flow_data
->drawing
->width
+SAFETY
, // do not overlap
1368 control_flow_data
->drawing
->height
+SAFETY
);
1371 drawing_data_request(control_flow_data
->drawing
,
1372 &control_flow_data
->drawing
->pixmap
,
1374 control_flow_data
->drawing
->width
,
1375 control_flow_data
->drawing
->height
);
1377 drawing_refresh(control_flow_data
->drawing
,
1379 control_flow_data
->drawing
->width
,
1380 control_flow_data
->drawing
->height
);
1388 gint
update_current_time_hook(void *hook_data
, void *call_data
)
1390 ControlFlowData
*control_flow_data
= (ControlFlowData
*)hook_data
;
1392 LttTime current_time
= *((LttTime
*)call_data
);
1394 const TimeWindow
*time_window
=
1395 lttvwindow_get_time_window(control_flow_data
->mw
);
1397 LttTime time_begin
= time_window
->start_time
;
1398 LttTime width
= time_window
->time_width
;
1399 LttTime half_width
= ltt_time_div(width
,2.0);
1400 LttTime time_end
= ltt_time_add(time_begin
, width
);
1402 LttvTracesetContext
* tsc
=
1403 lttvwindow_get_traceset_context(control_flow_data
->mw
);
1405 LttTime trace_start
= tsc
->Time_Span
->startTime
;
1406 LttTime trace_end
= tsc
->Time_Span
->endTime
;
1408 g_info("New current time HOOK : %u, %u", current_time
.tv_sec
,
1409 current_time
.tv_nsec
);
1413 /* If current time is inside time interval, just move the highlight
1416 /* Else, we have to change the time interval. We have to tell it
1417 * to the main window. */
1418 /* The time interval change will take care of placing the current
1419 * time at the center of the visible area, or nearest possible if we are
1420 * at one end of the trace. */
1423 if(ltt_time_compare(current_time
, time_begin
) == -1)
1425 TimeWindow new_time_window
;
1427 if(ltt_time_compare(current_time
,
1428 ltt_time_add(trace_start
,half_width
)) == -1)
1429 time_begin
= trace_start
;
1431 time_begin
= ltt_time_sub(current_time
,half_width
);
1433 new_time_window
.start_time
= time_begin
;
1434 new_time_window
.time_width
= width
;
1436 lttvwindow_report_time_window(control_flow_data
->mw
, &new_time_window
);
1438 else if(ltt_time_compare(current_time
, time_end
) == 1)
1440 TimeWindow new_time_window
;
1442 if(ltt_time_compare(current_time
, ltt_time_sub(trace_end
, half_width
)) == 1)
1443 time_begin
= ltt_time_sub(trace_end
,width
);
1445 time_begin
= ltt_time_sub(current_time
,half_width
);
1447 new_time_window
.start_time
= time_begin
;
1448 new_time_window
.time_width
= width
;
1450 lttvwindow_report_time_window(control_flow_data
->mw
, &new_time_window
);
1453 gtk_widget_queue_draw(control_flow_data
->drawing
->drawing_area
);
1458 typedef struct _ClosureData
{
1459 EventRequest
*event_request
;
1460 LttvTracesetState
*tss
;
1464 void draw_closure(gpointer key
, gpointer value
, gpointer user_data
)
1466 ProcessInfo
*process_info
= (ProcessInfo
*)key
;
1467 HashedProcessData
*hashed_process_data
= (HashedProcessData
*)value
;
1468 ClosureData
*closure_data
= (ClosureData
*)user_data
;
1470 ControlFlowData
*control_flow_data
=
1471 closure_data
->event_request
->control_flow_data
;
1473 GtkWidget
*widget
= control_flow_data
->drawing
->drawing_area
;
1475 /* Get y position of process */
1478 processlist_get_pixels_from_data( control_flow_data
->process_list
,
1480 hashed_process_data
,
1483 /* Get last state of process */
1484 LttvTraceContext
*tc
=
1485 ((LttvTracesetContext
*)closure_data
->tss
)->traces
[process_info
->trace_num
];
1486 //LttvTracefileContext *tfc = (LttvTracefileContext *)closure_data->ts;
1488 LttvTraceState
*ts
= (LttvTraceState
*)tc
;
1489 LttvProcessState
*process
;
1491 /* We do not provide a cpu_name argument assuming that this is not the
1492 idle job (pid 0) and thus its pid is unique across all cpus */
1493 process
= lttv_state_find_process_from_trace(ts
, 0, process_info
->pid
);
1495 /* Draw the closing line */
1496 DrawContext
*draw_context
= hashed_process_data
->draw_context
;
1497 if(draw_context
->previous
->middle
->x
== -1)
1499 draw_context
->previous
->middle
->x
= closure_data
->event_request
->x_begin
;
1500 draw_context
->previous
->over
->x
= closure_data
->event_request
->x_begin
;
1501 draw_context
->previous
->under
->x
= closure_data
->event_request
->x_begin
;
1502 g_debug("out middle x_beg : %u",closure_data
->event_request
->x_begin
);
1505 draw_context
->current
->middle
->x
= closure_data
->event_request
->x_end
;
1506 draw_context
->current
->over
->x
= closure_data
->event_request
->x_end
;
1507 draw_context
->current
->under
->x
= closure_data
->event_request
->x_end
;
1508 draw_context
->current
->middle
->y
= y
+ height
/2;
1509 draw_context
->current
->over
->y
= y
;
1510 draw_context
->current
->under
->y
= y
+ height
;
1511 draw_context
->previous
->middle
->y
= y
+ height
/2;
1512 draw_context
->previous
->over
->y
= y
;
1513 draw_context
->previous
->under
->y
= y
+ height
;
1514 draw_context
->drawable
= control_flow_data
->drawing
->pixmap
;
1515 draw_context
->pango_layout
= control_flow_data
->drawing
->pango_layout
;
1516 //draw_context->gc = widget->style->black_gc;
1517 draw_context
->gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
1518 gdk_gc_copy(draw_context
->gc
, widget
->style
->black_gc
);
1520 if(process
!= NULL
&& process
->state
->s
== LTTV_STATE_RUN
)
1522 PropertiesBG prop_bg
;
1523 prop_bg
.color
= g_new(GdkColor
,1);
1525 /*switch(tfc->index) {
1527 prop_bg.color->red = 0x1515;
1528 prop_bg.color->green = 0x1515;
1529 prop_bg.color->blue = 0x8c8c;
1532 prop_bg.color->red = 0x4e4e;
1533 prop_bg.color->green = 0xa9a9;
1534 prop_bg.color->blue = 0xa4a4;
1537 prop_bg.color->red = 0x7a7a;
1538 prop_bg.color->green = 0x4a4a;
1539 prop_bg.color->blue = 0x8b8b;
1542 prop_bg.color->red = 0x8080;
1543 prop_bg.color->green = 0x7777;
1544 prop_bg.color->blue = 0x4747;
1547 prop_bg.color->red = 0xe7e7;
1548 prop_bg.color->green = 0xe7e7;
1549 prop_bg.color->blue = 0xe7e7;
1553 g_debug("calling from closure");
1554 //FIXME : I need the cpu number in process's state to draw this.
1555 //draw_bg((void*)&prop_bg, (void*)draw_context);
1556 g_free(prop_bg
.color
);
1560 PropertiesLine prop_line
;
1561 prop_line
.color
= g_new(GdkColor
,1);
1562 prop_line
.line_width
= 2;
1563 prop_line
.style
= GDK_LINE_SOLID
;
1564 prop_line
.position
= MIDDLE
;
1566 /* color of line : status of the process */
1569 if(process
->state
->s
== LTTV_STATE_UNNAMED
)
1571 prop_line
.color
->red
= 0xffff;
1572 prop_line
.color
->green
= 0xffff;
1573 prop_line
.color
->blue
= 0xffff;
1575 else if(process
->state
->s
== LTTV_STATE_WAIT_FORK
)
1577 prop_line
.color
->red
= 0x0fff;
1578 prop_line
.color
->green
= 0xffff;
1579 prop_line
.color
->blue
= 0xfff0;
1581 else if(process
->state
->s
== LTTV_STATE_WAIT_CPU
)
1583 prop_line
.color
->red
= 0xffff;
1584 prop_line
.color
->green
= 0xffff;
1585 prop_line
.color
->blue
= 0x0000;
1587 else if(process
->state
->s
== LTTV_STATE_EXIT
)
1589 prop_line
.color
->red
= 0xffff;
1590 prop_line
.color
->green
= 0x0000;
1591 prop_line
.color
->blue
= 0xffff;
1593 else if(process
->state
->s
== LTTV_STATE_WAIT
)
1595 prop_line
.color
->red
= 0xffff;
1596 prop_line
.color
->green
= 0x0000;
1597 prop_line
.color
->blue
= 0x0000;
1599 else if(process
->state
->s
== LTTV_STATE_RUN
)
1601 prop_line
.color
->red
= 0x0000;
1602 prop_line
.color
->green
= 0xffff;
1603 prop_line
.color
->blue
= 0x0000;
1607 prop_line
.color
->red
= 0xffff;
1608 prop_line
.color
->green
= 0xffff;
1609 prop_line
.color
->blue
= 0xffff;
1615 prop_line
.color
->red
= 0xffff;
1616 prop_line
.color
->green
= 0xffff;
1617 prop_line
.color
->blue
= 0xffff;
1620 draw_line((void*)&prop_line
, (void*)draw_context
);
1621 g_free(prop_line
.color
);
1622 gdk_gc_unref(draw_context
->gc
);
1624 /* Reset draw_context of the process for next request */
1626 hashed_process_data
->draw_context
->drawable
= NULL
;
1627 hashed_process_data
->draw_context
->gc
= NULL
;
1628 hashed_process_data
->draw_context
->pango_layout
= NULL
;
1629 hashed_process_data
->draw_context
->current
->over
->x
= -1;
1630 hashed_process_data
->draw_context
->current
->over
->y
= -1;
1631 hashed_process_data
->draw_context
->current
->middle
->x
= -1;
1632 hashed_process_data
->draw_context
->current
->middle
->y
= -1;
1633 hashed_process_data
->draw_context
->current
->under
->x
= -1;
1634 hashed_process_data
->draw_context
->current
->under
->y
= -1;
1635 hashed_process_data
->draw_context
->current
->modify_over
->x
= -1;
1636 hashed_process_data
->draw_context
->current
->modify_over
->y
= -1;
1637 hashed_process_data
->draw_context
->current
->modify_middle
->x
= -1;
1638 hashed_process_data
->draw_context
->current
->modify_middle
->y
= -1;
1639 hashed_process_data
->draw_context
->current
->modify_under
->x
= -1;
1640 hashed_process_data
->draw_context
->current
->modify_under
->y
= -1;
1641 hashed_process_data
->draw_context
->current
->status
= LTTV_STATE_UNNAMED
;
1642 hashed_process_data
->draw_context
->previous
->over
->x
= -1;
1643 hashed_process_data
->draw_context
->previous
->over
->y
= -1;
1644 hashed_process_data
->draw_context
->previous
->middle
->x
= -1;
1645 hashed_process_data
->draw_context
->previous
->middle
->y
= -1;
1646 hashed_process_data
->draw_context
->previous
->under
->x
= -1;
1647 hashed_process_data
->draw_context
->previous
->under
->y
= -1;
1648 hashed_process_data
->draw_context
->previous
->modify_over
->x
= -1;
1649 hashed_process_data
->draw_context
->previous
->modify_over
->y
= -1;
1650 hashed_process_data
->draw_context
->previous
->modify_middle
->x
= -1;
1651 hashed_process_data
->draw_context
->previous
->modify_middle
->y
= -1;
1652 hashed_process_data
->draw_context
->previous
->modify_under
->x
= -1;
1653 hashed_process_data
->draw_context
->previous
->modify_under
->y
= -1;
1654 hashed_process_data
->draw_context
->previous
->status
= LTTV_STATE_UNNAMED
;
1662 * new default prev and current
1664 int after_data_request(void *hook_data
, void *call_data
)
1666 EventRequest
*event_request
= (EventRequest
*)hook_data
;
1667 ControlFlowData
*control_flow_data
= event_request
->control_flow_data
;
1669 ProcessList
*process_list
=
1670 guicontrolflow_get_process_list(event_request
->control_flow_data
);
1672 ClosureData closure_data
;
1673 closure_data
.event_request
= (EventRequest
*)hook_data
;
1674 closure_data
.tss
= (LttvTracesetState
*)call_data
;
1676 g_hash_table_foreach(process_list
->process_hash
, draw_closure
,
1677 (void*)&closure_data
);