5 #include <lttv/processTrace.h>
6 #include <lttv/gtkTraceSet.h>
11 #include "CFV-private.h"
12 #include "Event_Hooks.h"
14 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
15 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
17 /*****************************************************************************
19 *****************************************************************************/
21 //FIXME Colors will need to be dynamic. Graphic context part not done so far.
32 /* Vector of unallocated colors */
33 static GdkColor CF_Colors
[] =
35 { 0, 0xffff, 0x0000, 0x0000 }, // RED
36 { 0, 0x0000, 0xffff, 0x0000 }, // GREEN
37 { 0, 0x0000, 0x0000, 0xffff }, // BLUE
38 { 0, 0xffff, 0xffff, 0xffff }, // WHITE
39 { 0, 0x0000, 0x0000, 0x0000 } // BLACK
43 /* Function responsible for updating the exposed area.
44 * It must call processTrace() to ask for this update.
45 * Note : this function cannot clear the background, because it may
46 * erase drawing already present (SAFETY).
48 void drawing_data_request(Drawing_t
*Drawing
,
54 if(width
< 0) return ;
55 if(height
< 0) return ;
56 ControlFlowData
*control_flow_data
=
57 (ControlFlowData
*)g_object_get_data(
59 Drawing
->Drawing_Area_V
),
63 LttTime window_end
= ltt_time_add(control_flow_data
->Time_Window
.time_width
,
64 control_flow_data
->Time_Window
.start_time
);
66 g_critical("req : window_end : %u, %u", window_end
.tv_sec
,
69 g_critical("req : time width : %u, %u", control_flow_data
->Time_Window
.time_width
.tv_sec
,
70 control_flow_data
->Time_Window
.time_width
.tv_nsec
);
72 g_critical("x is : %i, x+width is : %i", x
, x
+width
);
74 convert_pixels_to_time(Drawing
->Drawing_Area_V
->allocation
.width
, x
,
75 &control_flow_data
->Time_Window
.start_time
,
79 convert_pixels_to_time(Drawing
->Drawing_Area_V
->allocation
.width
, x
+ width
,
80 &control_flow_data
->Time_Window
.start_time
,
84 LttvTracesetContext
* tsc
=
85 get_traceset_context(control_flow_data
->Parent_Window
);
88 //guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
91 //guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
92 //Drawing, *Pixmap, x, y, width, height);
94 // Let's call processTrace() !!
95 EventRequest event_request
; // Variable freed at the end of the function.
96 event_request
.Control_Flow_Data
= control_flow_data
;
97 event_request
.time_begin
= start
;
98 event_request
.time_end
= end
;
99 event_request
.x_begin
= x
;
100 event_request
.x_end
= x
+width
;
102 g_critical("req : start : %u, %u", event_request
.time_begin
.tv_sec
,
103 event_request
.time_begin
.tv_nsec
);
105 g_critical("req : end : %u, %u", event_request
.time_end
.tv_sec
,
106 event_request
.time_end
.tv_nsec
);
108 LttvHooks
*event
= lttv_hooks_new();
109 LttvHooks
*after_event
= lttv_hooks_new();
110 LttvHooks
*after_traceset
= lttv_hooks_new();
111 lttv_hooks_add(after_traceset
, after_data_request
, &event_request
);
112 lttv_hooks_add(event
, draw_event_hook
, &event_request
);
113 state_add_event_hooks_api(control_flow_data
->Parent_Window
);
114 lttv_hooks_add(after_event
, draw_after_hook
, &event_request
);
116 lttv_process_traceset_seek_time(tsc
, start
);
117 // FIXME : would like to place the after_traceset hook after the traceset,
118 // but the traceset context state is not valid anymore.
119 lttv_traceset_context_add_hooks(tsc
,
120 // NULL, after_traceset, NULL, NULL, NULL, NULL,
121 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
122 NULL
, after_traceset
, NULL
, event
, after_event
);
123 lttv_process_traceset(tsc
, end
, G_MAXULONG
);
124 //after_data_request((void*)&event_request,(void*)tsc);
125 lttv_traceset_context_remove_hooks(tsc
,
126 //NULL, after_traceset, NULL, NULL, NULL, NULL,
127 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
128 NULL
, after_traceset
, NULL
, event
, after_event
);
129 state_remove_event_hooks_api(control_flow_data
->Parent_Window
);
131 lttv_hooks_destroy(after_traceset
);
132 lttv_hooks_destroy(event
);
133 lttv_hooks_destroy(after_event
);
141 /* Create a new backing pixmap of the appropriate size */
142 /* As the scaling will always change, it's of no use to copy old
146 configure_event( GtkWidget
*widget
, GdkEventConfigure
*event
,
149 Drawing_t
*Drawing
= (Drawing_t
*)user_data
;
152 /* First, get the new time interval of the main window */
153 /* we assume (see documentation) that the main window
154 * has updated the time interval before this configure gets
157 get_time_window(Drawing
->Control_Flow_Data
->Parent_Window
,
158 &Drawing
->Control_Flow_Data
->Time_Window
);
160 /* New Pixmap, size of the configure event */
161 //GdkPixmap *Pixmap = gdk_pixmap_new(widget->window,
162 // widget->allocation.width + SAFETY,
163 // widget->allocation.height + SAFETY,
166 g_critical("drawing configure event");
167 g_critical("New draw size : %i by %i",widget
->allocation
.width
, widget
->allocation
.height
);
171 gdk_pixmap_unref(Drawing
->Pixmap
);
173 /* If no old Pixmap present */
174 //if(Drawing->Pixmap == NULL)
176 Drawing
->Pixmap
= gdk_pixmap_new(
178 widget
->allocation
.width
+ SAFETY
,
179 widget
->allocation
.height
+ SAFETY
,
180 //ProcessList_get_height
181 // (GuiControlFlow_get_Process_List(Drawing->Control_Flow_Data)),
183 Drawing
->width
= widget
->allocation
.width
;
184 Drawing
->height
= widget
->allocation
.height
;
188 gdk_draw_rectangle (Drawing
->Pixmap
,
189 widget
->style
->white_gc
,
192 widget
->allocation
.width
+SAFETY
,
193 widget
->allocation
.height
+SAFETY
);
195 //g_info("init data request");
198 /* Initial data request */
199 // Do not need to ask for data of 1 pixel : not synchronized with
200 // main window time at this moment.
201 drawing_data_request(Drawing
, &Drawing
->Pixmap
, 0, 0,
202 widget
->allocation
.width
,
203 widget
->allocation
.height
);
205 Drawing
->width
= widget
->allocation
.width
;
206 Drawing
->height
= widget
->allocation
.height
;
214 // /* Draw empty background */
215 // gdk_draw_rectangle (Pixmap,
216 // widget->style->black_gc,
219 // widget->allocation.width,
220 // widget->allocation.height);
222 /* Copy old data to new pixmap */
223 gdk_draw_drawable (Pixmap
,
224 widget
->style
->white_gc
,
231 gdk_pixmap_unref(Drawing
->Pixmap
);
233 Drawing
->Pixmap
= Pixmap
;
235 // Clear the bottom part of the image (SAFETY)
236 gdk_draw_rectangle (Pixmap
,
237 widget
->style
->white_gc
,
239 0, Drawing
->height
+SAFETY
,
240 Drawing
->width
+SAFETY
, // do not overlap
241 (widget
->allocation
.height
) - Drawing
->height
);
243 // Clear the right part of the image (SAFETY)
244 gdk_draw_rectangle (Pixmap
,
245 widget
->style
->white_gc
,
247 Drawing
->width
+SAFETY
, 0,
248 (widget
->allocation
.width
) - Drawing
->width
, // do not overlap
249 Drawing
->height
+SAFETY
);
251 /* Clear the backgound for data request, but not SAFETY */
252 gdk_draw_rectangle (Pixmap
,
253 Drawing
->Drawing_Area_V
->style
->white_gc
,
255 Drawing
->width
+ SAFETY
, 0,
256 widget
->allocation
.width
- Drawing
->width
, // do not overlap
257 widget
->allocation
.height
+SAFETY
);
259 /* Request data for missing space */
260 g_info("missing data request");
261 drawing_data_request(Drawing
, &Pixmap
, Drawing
->width
, 0,
262 widget
->allocation
.width
- Drawing
->width
,
263 widget
->allocation
.height
);
265 Drawing
->width
= widget
->allocation
.width
;
266 Drawing
->height
= widget
->allocation
.height
;
273 /* Redraw the screen from the backing pixmap */
275 expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
277 Drawing_t
*Drawing
= (Drawing_t
*)user_data
;
278 ControlFlowData
*control_flow_data
=
279 (ControlFlowData
*)g_object_get_data(
281 "Control_Flow_Data");
283 g_critical("drawing expose event");
286 LttTime
* Current_Time
=
287 guicontrolflow_get_current_time(control_flow_data
);
289 LttTime window_end
= ltt_time_add(control_flow_data
->Time_Window
.time_width
,
290 control_flow_data
->Time_Window
.start_time
);
292 convert_time_to_pixels(
293 control_flow_data
->Time_Window
.start_time
,
296 widget
->allocation
.width
,
299 gdk_draw_pixmap(widget
->window
,
300 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
302 event
->area
.x
, event
->area
.y
,
303 event
->area
.x
, event
->area
.y
,
304 event
->area
.width
, event
->area
.height
);
306 if(x
>= event
->area
.x
&& x
<= event
->area
.x
+event
->area
.width
)
308 GdkGC
*gc
= gdk_gc_new(control_flow_data
->Drawing
->Pixmap
);
309 gdk_gc_copy(gc
, widget
->style
->black_gc
);
311 drawing_draw_line(NULL
, widget
->window
,
313 x
, event
->area
.y
+event
->area
.height
,
322 button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, gpointer user_data
)
324 ControlFlowData
*control_flow_data
=
325 (ControlFlowData
*)g_object_get_data(
327 "Control_Flow_Data");
328 Drawing_t
*Drawing
= control_flow_data
->Drawing
;
332 if(event
->button
== 1)
336 LttTime window_end
= ltt_time_add(control_flow_data
->Time_Window
.time_width
,
337 control_flow_data
->Time_Window
.start_time
);
340 /* left mouse button click */
341 g_critical("x click is : %f", event
->x
);
343 convert_pixels_to_time(widget
->allocation
.width
, (guint
)event
->x
,
344 &control_flow_data
->Time_Window
.start_time
,
348 set_current_time(control_flow_data
->Parent_Window
, &time
);
358 Drawing_t
*drawing_construct(ControlFlowData
*Control_Flow_Data
)
360 Drawing_t
*Drawing
= g_new(Drawing_t
, 1);
362 Drawing
->Drawing_Area_V
= gtk_drawing_area_new ();
363 Drawing
->Control_Flow_Data
= Control_Flow_Data
;
365 Drawing
->pango_layout
=
366 gtk_widget_create_pango_layout(Drawing
->Drawing_Area_V
, NULL
);
368 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
369 g_object_set_data_full(
370 G_OBJECT(Drawing
->Drawing_Area_V
),
373 (GDestroyNotify
)drawing_destroy
);
375 //gtk_widget_modify_bg( Drawing->Drawing_Area_V,
377 // &CF_Colors[BLACK]);
379 //gdk_window_get_geometry(Drawing->Drawing_Area_V->window,
381 // &(Drawing->width),
382 // &(Drawing->height),
385 //Drawing->Pixmap = gdk_pixmap_new(
386 // Drawing->Drawing_Area_V->window,
391 Drawing
->Pixmap
= NULL
;
393 // Drawing->Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
394 // Drawing->Drawing_Area_V->allocation.width,
395 // Drawing->Drawing_Area_V->allocation.height,
398 gtk_widget_add_events(Drawing
->Drawing_Area_V
, GDK_BUTTON_PRESS_MASK
);
400 g_signal_connect (G_OBJECT(Drawing
->Drawing_Area_V
),
402 G_CALLBACK (configure_event
),
405 g_signal_connect (G_OBJECT(Drawing
->Drawing_Area_V
),
407 G_CALLBACK (expose_event
),
410 g_signal_connect (G_OBJECT(Drawing
->Drawing_Area_V
),
411 "button-press-event",
412 G_CALLBACK (button_press_event
),
419 void drawing_destroy(Drawing_t
*Drawing
)
422 // Do not unref here, Drawing_t destroyed by it's widget.
423 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
425 g_free(Drawing
->pango_layout
);
429 GtkWidget
*drawing_get_widget(Drawing_t
*Drawing
)
431 return Drawing
->Drawing_Area_V
;
434 /* convert_pixels_to_time
436 * Convert from window pixel and time interval to an absolute time.
438 void convert_pixels_to_time(
441 LttTime
*window_time_begin
,
442 LttTime
*window_time_end
,
445 LttTime window_time_interval
;
447 window_time_interval
= ltt_time_sub(*window_time_end
,
449 *time
= ltt_time_mul(window_time_interval
, (x
/(float)width
));
450 *time
= ltt_time_add(*window_time_begin
, *time
);
455 void convert_time_to_pixels(
456 LttTime window_time_begin
,
457 LttTime window_time_end
,
462 LttTime window_time_interval
;
463 float interval_float
, time_float
;
465 window_time_interval
= ltt_time_sub(window_time_end
,window_time_begin
);
467 time
= ltt_time_sub(time
, window_time_begin
);
469 interval_float
= ltt_time_to_double(window_time_interval
);
470 time_float
= ltt_time_to_double(time
);
472 *x
= (guint
)(time_float
/interval_float
* width
);
476 void drawing_refresh ( Drawing_t
*Drawing
,
478 guint width
, guint height
)
480 g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x
, y
, width
, height
);
481 GdkRectangle update_rect
;
484 Drawing
->Drawing_Area_V
->window
,
485 Drawing
->Drawing_Area_V
->
486 style
->fg_gc
[GTK_WIDGET_STATE (Drawing
->Drawing_Area_V
)],
487 GDK_DRAWABLE(Drawing
->Pixmap
),
494 update_rect
.width
= Drawing
->width
;
495 update_rect
.height
= Drawing
->height
;
496 gtk_widget_draw( Drawing
->Drawing_Area_V
, &update_rect
);
501 void drawing_draw_line( Drawing_t
*Drawing
,
507 gdk_draw_line (Pixmap
,
515 void drawing_resize(Drawing_t
*Drawing
, guint h
, guint w
)
517 Drawing
->height
= h
;
520 gtk_widget_set_size_request ( Drawing
->Drawing_Area_V
,
528 /* Insert a square corresponding to a new process in the list */
529 /* Applies to whole Drawing->width */
530 void drawing_insert_square(Drawing_t
*Drawing
,
534 //GdkRectangle update_rect;
536 /* Allocate a new pixmap with new height */
537 GdkPixmap
*Pixmap
= gdk_pixmap_new(Drawing
->Drawing_Area_V
->window
,
538 Drawing
->width
+ SAFETY
,
539 Drawing
->height
+ height
+ SAFETY
,
542 /* Copy the high region */
543 gdk_draw_drawable (Pixmap
,
544 Drawing
->Drawing_Area_V
->style
->black_gc
,
548 Drawing
->width
+ SAFETY
, y
);
553 /* add an empty square */
554 gdk_draw_rectangle (Pixmap
,
555 Drawing
->Drawing_Area_V
->style
->white_gc
,
558 Drawing
->width
+ SAFETY
, // do not overlap
563 /* copy the bottom of the region */
564 gdk_draw_drawable (Pixmap
,
565 Drawing
->Drawing_Area_V
->style
->black_gc
,
569 Drawing
->width
+SAFETY
, Drawing
->height
- y
+ SAFETY
);
575 gdk_pixmap_unref(Drawing
->Pixmap
);
577 Drawing
->Pixmap
= Pixmap
;
579 Drawing
->height
+=height
;
581 /* Rectangle to update, from new Drawing dimensions */
582 //update_rect.x = 0 ;
583 //update_rect.y = y ;
584 //update_rect.width = Drawing->width;
585 //update_rect.height = Drawing->height - y ;
586 //gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
590 /* Remove a square corresponding to a removed process in the list */
591 void drawing_remove_square(Drawing_t
*Drawing
,
595 //GdkRectangle update_rect;
597 /* Allocate a new pixmap with new height */
598 GdkPixmap
*Pixmap
= gdk_pixmap_new(
599 Drawing
->Drawing_Area_V
->window
,
600 Drawing
->width
+ SAFETY
,
601 Drawing
->height
- height
+ SAFETY
,
604 /* Copy the high region */
605 gdk_draw_drawable (Pixmap
,
606 Drawing
->Drawing_Area_V
->style
->black_gc
,
610 Drawing
->width
+ SAFETY
, y
);
614 /* Copy up the bottom of the region */
615 gdk_draw_drawable (Pixmap
,
616 Drawing
->Drawing_Area_V
->style
->black_gc
,
620 Drawing
->width
, Drawing
->height
- y
- height
+ SAFETY
);
624 gdk_pixmap_unref(Drawing
->Pixmap
);
626 Drawing
->Pixmap
= Pixmap
;
628 Drawing
->height
-=height
;
630 /* Rectangle to update, from new Drawing dimensions */
631 //update_rect.x = 0 ;
632 //update_rect.y = y ;
633 //update_rect.width = Drawing->width;
634 //update_rect.height = Drawing->height - y ;
635 //gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);