5 #include <lttv/processTrace.h>
6 #include <lttv/gtkTraceSet.h>
11 #include "cfv-private.h"
12 #include "eventhooks.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
),
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
->allocation
.width
, x
,
75 &control_flow_data
->time_window
.start_time
,
79 convert_pixels_to_time(drawing
->drawing_area
->allocation
.width
, x
+ width
,
80 &control_flow_data
->time_window
.start_time
,
84 LttvTracesetContext
* tsc
=
85 get_traceset_context(control_flow_data
->mw
);
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 //Modified by xiangxiu: state update hooks are added by the main window
114 //state_add_event_hooks_api(control_flow_data->mw);
115 lttv_hooks_add(after_event
, draw_after_hook
, &event_request
);
117 lttv_process_traceset_seek_time(tsc
, start
);
118 // FIXME : would like to place the after_traceset hook after the traceset,
119 // but the traceset context state is not valid anymore.
120 lttv_traceset_context_add_hooks(tsc
,
121 // NULL, after_traceset, NULL, NULL, NULL, NULL,
122 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
123 NULL
, after_traceset
, NULL
, event
, after_event
);
124 lttv_process_traceset(tsc
, end
, G_MAXULONG
);
125 //after_data_request((void*)&event_request,(void*)tsc);
126 lttv_traceset_context_remove_hooks(tsc
,
127 //NULL, after_traceset, NULL, NULL, NULL, NULL,
128 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
129 NULL
, after_traceset
, NULL
, event
, after_event
);
130 //Modified by xiangxiu: state update hooks are removed by the main window
131 //state_remove_event_hooks_api(control_flow_data->mw);
133 lttv_hooks_destroy(after_traceset
);
134 lttv_hooks_destroy(event
);
135 lttv_hooks_destroy(after_event
);
143 /* Create a new backing pixmap of the appropriate size */
144 /* As the scaling will always change, it's of no use to copy old
148 configure_event( GtkWidget
*widget
, GdkEventConfigure
*event
,
151 Drawing_t
*drawing
= (Drawing_t
*)user_data
;
154 /* First, get the new time interval of the main window */
155 /* we assume (see documentation) that the main window
156 * has updated the time interval before this configure gets
159 get_time_window(drawing
->control_flow_data
->mw
,
160 &drawing
->control_flow_data
->time_window
);
162 /* New pixmap, size of the configure event */
163 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
164 // widget->allocation.width + SAFETY,
165 // widget->allocation.height + SAFETY,
168 g_critical("drawing configure event");
169 g_critical("New draw size : %i by %i",widget
->allocation
.width
, widget
->allocation
.height
);
173 gdk_pixmap_unref(drawing
->pixmap
);
175 /* If no old pixmap present */
176 //if(drawing->pixmap == NULL)
178 drawing
->pixmap
= gdk_pixmap_new(
180 widget
->allocation
.width
+ SAFETY
,
181 widget
->allocation
.height
+ SAFETY
,
182 //ProcessList_get_height
183 // (GuiControlFlow_get_process_list(drawing->control_flow_data)),
185 drawing
->width
= widget
->allocation
.width
;
186 drawing
->height
= widget
->allocation
.height
;
190 gdk_draw_rectangle (drawing
->pixmap
,
191 widget
->style
->white_gc
,
194 widget
->allocation
.width
+SAFETY
,
195 widget
->allocation
.height
+SAFETY
);
197 //g_info("init data request");
200 /* Initial data request */
201 // Do not need to ask for data of 1 pixel : not synchronized with
202 // main window time at this moment.
203 drawing_data_request(drawing
, &drawing
->pixmap
, 0, 0,
204 widget
->allocation
.width
,
205 widget
->allocation
.height
);
207 drawing
->width
= widget
->allocation
.width
;
208 drawing
->height
= widget
->allocation
.height
;
216 // /* Draw empty background */
217 // gdk_draw_rectangle (pixmap,
218 // widget->style->black_gc,
221 // widget->allocation.width,
222 // widget->allocation.height);
224 /* Copy old data to new pixmap */
225 gdk_draw_drawable (pixmap
,
226 widget
->style
->white_gc
,
233 gdk_pixmap_unref(drawing
->pixmap
);
235 drawing
->pixmap
= pixmap
;
237 // Clear the bottom part of the image (SAFETY)
238 gdk_draw_rectangle (pixmap
,
239 widget
->style
->white_gc
,
241 0, drawing
->height
+SAFETY
,
242 drawing
->width
+SAFETY
, // do not overlap
243 (widget
->allocation
.height
) - drawing
->height
);
245 // Clear the right part of the image (SAFETY)
246 gdk_draw_rectangle (pixmap
,
247 widget
->style
->white_gc
,
249 drawing
->width
+SAFETY
, 0,
250 (widget
->allocation
.width
) - drawing
->width
, // do not overlap
251 drawing
->height
+SAFETY
);
253 /* Clear the backgound for data request, but not SAFETY */
254 gdk_draw_rectangle (pixmap
,
255 drawing
->drawing_area
->style
->white_gc
,
257 drawing
->width
+ SAFETY
, 0,
258 widget
->allocation
.width
- drawing
->width
, // do not overlap
259 widget
->allocation
.height
+SAFETY
);
261 /* Request data for missing space */
262 g_info("missing data request");
263 drawing_data_request(drawing
, &pixmap
, drawing
->width
, 0,
264 widget
->allocation
.width
- drawing
->width
,
265 widget
->allocation
.height
);
267 drawing
->width
= widget
->allocation
.width
;
268 drawing
->height
= widget
->allocation
.height
;
275 /* Redraw the screen from the backing pixmap */
277 expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
279 Drawing_t
*drawing
= (Drawing_t
*)user_data
;
280 ControlFlowData
*control_flow_data
=
281 (ControlFlowData
*)g_object_get_data(
283 "control_flow_data");
285 g_critical("drawing expose event");
288 LttTime
* current_time
=
289 guicontrolflow_get_current_time(control_flow_data
);
291 LttTime window_end
= ltt_time_add(control_flow_data
->time_window
.time_width
,
292 control_flow_data
->time_window
.start_time
);
294 convert_time_to_pixels(
295 control_flow_data
->time_window
.start_time
,
298 widget
->allocation
.width
,
301 gdk_draw_pixmap(widget
->window
,
302 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
304 event
->area
.x
, event
->area
.y
,
305 event
->area
.x
, event
->area
.y
,
306 event
->area
.width
, event
->area
.height
);
308 if(x
>= event
->area
.x
&& x
<= event
->area
.x
+event
->area
.width
)
310 GdkGC
*gc
= gdk_gc_new(control_flow_data
->drawing
->pixmap
);
311 gdk_gc_copy(gc
, widget
->style
->black_gc
);
313 drawing_draw_line(NULL
, widget
->window
,
315 x
, event
->area
.y
+event
->area
.height
,
324 button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, gpointer user_data
)
326 ControlFlowData
*control_flow_data
=
327 (ControlFlowData
*)g_object_get_data(
329 "control_flow_data");
330 Drawing_t
*drawing
= control_flow_data
->drawing
;
334 if(event
->button
== 1)
338 LttTime window_end
= ltt_time_add(control_flow_data
->time_window
.time_width
,
339 control_flow_data
->time_window
.start_time
);
342 /* left mouse button click */
343 g_critical("x click is : %f", event
->x
);
345 convert_pixels_to_time(widget
->allocation
.width
, (guint
)event
->x
,
346 &control_flow_data
->time_window
.start_time
,
350 set_current_time(control_flow_data
->mw
, &time
);
360 Drawing_t
*drawing_construct(ControlFlowData
*control_flow_data
)
362 Drawing_t
*drawing
= g_new(Drawing_t
, 1);
364 drawing
->drawing_area
= gtk_drawing_area_new ();
365 drawing
->control_flow_data
= control_flow_data
;
367 drawing
->pango_layout
=
368 gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
370 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
371 g_object_set_data_full(
372 G_OBJECT(drawing
->drawing_area
),
375 (GDestroyNotify
)drawing_destroy
);
377 //gtk_widget_modify_bg( drawing->drawing_area,
379 // &CF_Colors[BLACK]);
381 //gdk_window_get_geometry(drawing->drawing_area->window,
383 // &(drawing->width),
384 // &(drawing->height),
387 //drawing->pixmap = gdk_pixmap_new(
388 // drawing->drawing_area->window,
393 drawing
->pixmap
= NULL
;
395 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
396 // drawing->drawing_area->allocation.width,
397 // drawing->drawing_area->allocation.height,
400 gtk_widget_add_events(drawing
->drawing_area
, GDK_BUTTON_PRESS_MASK
);
402 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
404 G_CALLBACK (configure_event
),
407 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
409 G_CALLBACK (expose_event
),
412 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
413 "button-press-event",
414 G_CALLBACK (button_press_event
),
421 void drawing_destroy(Drawing_t
*drawing
)
424 // Do not unref here, Drawing_t destroyed by it's widget.
425 //g_object_unref( G_OBJECT(drawing->drawing_area));
427 g_free(drawing
->pango_layout
);
431 GtkWidget
*drawing_get_widget(Drawing_t
*drawing
)
433 return drawing
->drawing_area
;
436 /* convert_pixels_to_time
438 * Convert from window pixel and time interval to an absolute time.
440 void convert_pixels_to_time(
443 LttTime
*window_time_begin
,
444 LttTime
*window_time_end
,
447 LttTime window_time_interval
;
449 window_time_interval
= ltt_time_sub(*window_time_end
,
451 *time
= ltt_time_mul(window_time_interval
, (x
/(float)width
));
452 *time
= ltt_time_add(*window_time_begin
, *time
);
457 void convert_time_to_pixels(
458 LttTime window_time_begin
,
459 LttTime window_time_end
,
464 LttTime window_time_interval
;
465 float interval_float
, time_float
;
467 window_time_interval
= ltt_time_sub(window_time_end
,window_time_begin
);
469 time
= ltt_time_sub(time
, window_time_begin
);
471 interval_float
= ltt_time_to_double(window_time_interval
);
472 time_float
= ltt_time_to_double(time
);
474 *x
= (guint
)(time_float
/interval_float
* width
);
478 void drawing_refresh ( Drawing_t
*drawing
,
480 guint width
, guint height
)
482 g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x
, y
, width
, height
);
483 GdkRectangle update_rect
;
486 drawing
->drawing_area
->window
,
487 drawing
->drawing_area
->
488 style
->fg_gc
[GTK_WIDGET_STATE (drawing
->drawing_area
)],
489 GDK_DRAWABLE(drawing
->pixmap
),
496 update_rect
.width
= drawing
->width
;
497 update_rect
.height
= drawing
->height
;
498 gtk_widget_draw( drawing
->drawing_area
, &update_rect
);
503 void drawing_draw_line( Drawing_t
*drawing
,
509 gdk_draw_line (pixmap
,
517 void drawing_resize(Drawing_t
*drawing
, guint h
, guint w
)
519 drawing
->height
= h
;
522 gtk_widget_set_size_request ( drawing
->drawing_area
,
530 /* Insert a square corresponding to a new process in the list */
531 /* Applies to whole drawing->width */
532 void drawing_insert_square(Drawing_t
*drawing
,
536 //GdkRectangle update_rect;
538 /* Allocate a new pixmap with new height */
539 GdkPixmap
*pixmap
= gdk_pixmap_new(drawing
->drawing_area
->window
,
540 drawing
->width
+ SAFETY
,
541 drawing
->height
+ height
+ SAFETY
,
544 /* Copy the high region */
545 gdk_draw_drawable (pixmap
,
546 drawing
->drawing_area
->style
->black_gc
,
550 drawing
->width
+ SAFETY
, y
);
555 /* add an empty square */
556 gdk_draw_rectangle (pixmap
,
557 drawing
->drawing_area
->style
->white_gc
,
560 drawing
->width
+ SAFETY
, // do not overlap
565 /* copy the bottom of the region */
566 gdk_draw_drawable (pixmap
,
567 drawing
->drawing_area
->style
->black_gc
,
571 drawing
->width
+SAFETY
, drawing
->height
- y
+ SAFETY
);
577 gdk_pixmap_unref(drawing
->pixmap
);
579 drawing
->pixmap
= pixmap
;
581 drawing
->height
+=height
;
583 /* Rectangle to update, from new drawing dimensions */
584 //update_rect.x = 0 ;
585 //update_rect.y = y ;
586 //update_rect.width = drawing->width;
587 //update_rect.height = drawing->height - y ;
588 //gtk_widget_draw( drawing->drawing_area, &update_rect);
592 /* Remove a square corresponding to a removed process in the list */
593 void drawing_remove_square(Drawing_t
*drawing
,
597 //GdkRectangle update_rect;
599 /* Allocate a new pixmap with new height */
600 GdkPixmap
*pixmap
= gdk_pixmap_new(
601 drawing
->drawing_area
->window
,
602 drawing
->width
+ SAFETY
,
603 drawing
->height
- height
+ SAFETY
,
606 /* Copy the high region */
607 gdk_draw_drawable (pixmap
,
608 drawing
->drawing_area
->style
->black_gc
,
612 drawing
->width
+ SAFETY
, y
);
616 /* Copy up the bottom of the region */
617 gdk_draw_drawable (pixmap
,
618 drawing
->drawing_area
->style
->black_gc
,
622 drawing
->width
, drawing
->height
- y
- height
+ SAFETY
);
626 gdk_pixmap_unref(drawing
->pixmap
);
628 drawing
->pixmap
= pixmap
;
630 drawing
->height
-=height
;
632 /* Rectangle to update, from new drawing dimensions */
633 //update_rect.x = 0 ;
634 //update_rect.y = y ;
635 //update_rect.width = drawing->width;
636 //update_rect.height = drawing->height - y ;
637 //gtk_widget_draw( drawing->drawing_area, &update_rect);