gui control flow working with text, need hooking after trace state processing of...
[lttv.git] / ltt / branches / poly / lttv / modules / guiControlFlow / Drawing.c
1
2 #include <gtk/gtk.h>
3 #include <gdk/gdk.h>
4
5 #include <lttv/processTrace.h>
6 #include <lttv/gtkTraceSet.h>
7 #include <lttv/hook.h>
8
9 #include "Drawing.h"
10 #include "CFV.h"
11 #include "CFV-private.h"
12 #include "Event_Hooks.h"
13
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)
16
17 /*****************************************************************************
18 * Drawing functions *
19 *****************************************************************************/
20
21 //FIXME Colors will need to be dynamic. Graphic context part not done so far.
22 typedef enum
23 {
24 RED,
25 GREEN,
26 BLUE,
27 WHITE,
28 BLACK
29
30 } ControlFlowColors;
31
32 /* Vector of unallocated colors */
33 static GdkColor CF_Colors [] =
34 {
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
40 };
41
42
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).
47 */
48 void drawing_data_request(Drawing_t *Drawing,
49 GdkPixmap **Pixmap,
50 gint x, gint y,
51 gint width,
52 gint height)
53 {
54 if(width < 0) return ;
55 if(height < 0) return ;
56 ControlFlowData *control_flow_data =
57 (ControlFlowData*)g_object_get_data(
58 G_OBJECT(
59 Drawing->Drawing_Area_V),
60 "Control_Flow_Data");
61
62 LttTime start, end;
63 LttTime window_end = ltt_time_add(control_flow_data->Time_Window.time_width,
64 control_flow_data->Time_Window.start_time);
65
66 g_critical("req : window_end : %u, %u", window_end.tv_sec,
67 window_end.tv_nsec);
68
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);
71
72 g_critical("x is : %i, x+width is : %i", x, x+width);
73
74 convert_pixels_to_time(Drawing->Drawing_Area_V->allocation.width, x,
75 &control_flow_data->Time_Window.start_time,
76 &window_end,
77 &start);
78
79 convert_pixels_to_time(Drawing->Drawing_Area_V->allocation.width, x + width,
80 &control_flow_data->Time_Window.start_time,
81 &window_end,
82 &end);
83
84 LttvTracesetContext * tsc =
85 get_traceset_context(control_flow_data->Parent_Window);
86
87 //send_test_process(
88 //guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
89 //Drawing);
90 //send_test_drawing(
91 //guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
92 //Drawing, *Pixmap, x, y, width, height);
93
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
100 g_critical("req : start : %u, %u", event_request.time_begin.tv_sec,
101 event_request.time_begin.tv_nsec);
102
103 g_critical("req : end : %u, %u", event_request.time_end.tv_sec,
104 event_request.time_end.tv_nsec);
105
106 //LttvHooks *event = lttv_hooks_new();
107 LttvHooks *after_event = lttv_hooks_new();
108 state_add_event_hooks_api(control_flow_data->Parent_Window);
109 //lttv_hooks_add(event, draw_event_hook, &event_request);
110 lttv_hooks_add(after_event, draw_after_hook, &event_request);
111
112 lttv_process_traceset_seek_time(tsc, start);
113 lttv_traceset_context_add_hooks(tsc,
114 NULL, NULL, NULL, NULL, NULL, NULL,
115 NULL, NULL, NULL, NULL, after_event);
116 lttv_process_traceset(tsc, end, G_MAXULONG);
117 lttv_traceset_context_remove_hooks(tsc, NULL, NULL, NULL, NULL, NULL, NULL,
118 NULL, NULL, NULL, NULL,after_event);
119
120 state_remove_event_hooks_api(control_flow_data->Parent_Window);
121 //lttv_hooks_destroy(event);
122 lttv_hooks_destroy(after_event);
123 }
124
125 /* Callbacks */
126
127
128 /* Create a new backing pixmap of the appropriate size */
129 /* As the scaling will always change, it's of no use to copy old
130 * pixmap.
131 */
132 static gboolean
133 configure_event( GtkWidget *widget, GdkEventConfigure *event,
134 gpointer user_data)
135 {
136 Drawing_t *Drawing = (Drawing_t*)user_data;
137
138
139 /* First, get the new time interval of the main window */
140 /* we assume (see documentation) that the main window
141 * has updated the time interval before this configure gets
142 * executed.
143 */
144 get_time_window(Drawing->Control_Flow_Data->Parent_Window,
145 &Drawing->Control_Flow_Data->Time_Window);
146
147 /* New Pixmap, size of the configure event */
148 //GdkPixmap *Pixmap = gdk_pixmap_new(widget->window,
149 // widget->allocation.width + SAFETY,
150 // widget->allocation.height + SAFETY,
151 // -1);
152
153 g_critical("drawing configure event");
154 g_critical("New draw size : %i by %i",widget->allocation.width, widget->allocation.height);
155
156
157 if (Drawing->Pixmap)
158 gdk_pixmap_unref(Drawing->Pixmap);
159
160 /* If no old Pixmap present */
161 //if(Drawing->Pixmap == NULL)
162 {
163 Drawing->Pixmap = gdk_pixmap_new(
164 widget->window,
165 widget->allocation.width + SAFETY,
166 widget->allocation.height + SAFETY,
167 //ProcessList_get_height
168 // (GuiControlFlow_get_Process_List(Drawing->Control_Flow_Data)),
169 -1);
170 Drawing->width = widget->allocation.width;
171 Drawing->height = widget->allocation.height;
172
173
174 // Clear the image
175 gdk_draw_rectangle (Drawing->Pixmap,
176 widget->style->white_gc,
177 TRUE,
178 0, 0,
179 widget->allocation.width+SAFETY,
180 widget->allocation.height+SAFETY);
181
182 //g_info("init data request");
183
184
185 /* Initial data request */
186 // Do not need to ask for data of 1 pixel : not synchronized with
187 // main window time at this moment.
188 drawing_data_request(Drawing, &Drawing->Pixmap, 0, 0,
189 widget->allocation.width,
190 widget->allocation.height);
191
192 Drawing->width = widget->allocation.width;
193 Drawing->height = widget->allocation.height;
194
195 return TRUE;
196
197
198
199 }
200 #ifdef NOTUSE
201 // /* Draw empty background */
202 // gdk_draw_rectangle (Pixmap,
203 // widget->style->black_gc,
204 // TRUE,
205 // 0, 0,
206 // widget->allocation.width,
207 // widget->allocation.height);
208
209 /* Copy old data to new pixmap */
210 gdk_draw_drawable (Pixmap,
211 widget->style->white_gc,
212 Drawing->Pixmap,
213 0, 0,
214 0, 0,
215 -1, -1);
216
217 if (Drawing->Pixmap)
218 gdk_pixmap_unref(Drawing->Pixmap);
219
220 Drawing->Pixmap = Pixmap;
221
222 // Clear the bottom part of the image (SAFETY)
223 gdk_draw_rectangle (Pixmap,
224 widget->style->white_gc,
225 TRUE,
226 0, Drawing->height+SAFETY,
227 Drawing->width+SAFETY, // do not overlap
228 (widget->allocation.height) - Drawing->height);
229
230 // Clear the right part of the image (SAFETY)
231 gdk_draw_rectangle (Pixmap,
232 widget->style->white_gc,
233 TRUE,
234 Drawing->width+SAFETY, 0,
235 (widget->allocation.width) - Drawing->width, // do not overlap
236 Drawing->height+SAFETY);
237
238 /* Clear the backgound for data request, but not SAFETY */
239 gdk_draw_rectangle (Pixmap,
240 Drawing->Drawing_Area_V->style->white_gc,
241 TRUE,
242 Drawing->width + SAFETY, 0,
243 widget->allocation.width - Drawing->width, // do not overlap
244 widget->allocation.height+SAFETY);
245
246 /* Request data for missing space */
247 g_info("missing data request");
248 drawing_data_request(Drawing, &Pixmap, Drawing->width, 0,
249 widget->allocation.width - Drawing->width,
250 widget->allocation.height);
251
252 Drawing->width = widget->allocation.width;
253 Drawing->height = widget->allocation.height;
254
255 return TRUE;
256 #endif //NOTUSE
257 }
258
259
260 /* Redraw the screen from the backing pixmap */
261 static gboolean
262 expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
263 {
264 Drawing_t *Drawing = (Drawing_t*)user_data;
265 g_critical("drawing expose event");
266
267 gdk_draw_pixmap(widget->window,
268 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
269 Drawing->Pixmap,
270 event->area.x, event->area.y,
271 event->area.x, event->area.y,
272 event->area.width, event->area.height);
273
274 return FALSE;
275 }
276
277 Drawing_t *drawing_construct(ControlFlowData *Control_Flow_Data)
278 {
279 Drawing_t *Drawing = g_new(Drawing_t, 1);
280
281 Drawing->Drawing_Area_V = gtk_drawing_area_new ();
282 Drawing->Control_Flow_Data = Control_Flow_Data;
283
284 Drawing->pango_layout =
285 gtk_widget_create_pango_layout(Drawing->Drawing_Area_V, NULL);
286
287 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
288 g_object_set_data_full(
289 G_OBJECT(Drawing->Drawing_Area_V),
290 "Link_Drawing_Data",
291 Drawing,
292 (GDestroyNotify)drawing_destroy);
293
294 //gtk_widget_modify_bg( Drawing->Drawing_Area_V,
295 // GTK_STATE_NORMAL,
296 // &CF_Colors[BLACK]);
297
298 //gdk_window_get_geometry(Drawing->Drawing_Area_V->window,
299 // NULL, NULL,
300 // &(Drawing->width),
301 // &(Drawing->height),
302 // -1);
303
304 //Drawing->Pixmap = gdk_pixmap_new(
305 // Drawing->Drawing_Area_V->window,
306 // Drawing->width,
307 // Drawing->height,
308 // Drawing->depth);
309
310 Drawing->Pixmap = NULL;
311
312 // Drawing->Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
313 // Drawing->Drawing_Area_V->allocation.width,
314 // Drawing->Drawing_Area_V->allocation.height,
315 // -1);
316
317 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
318 "configure_event",
319 G_CALLBACK (configure_event),
320 (gpointer)Drawing);
321
322 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
323 "expose_event",
324 G_CALLBACK (expose_event),
325 (gpointer)Drawing);
326
327 return Drawing;
328 }
329
330 void drawing_destroy(Drawing_t *Drawing)
331 {
332
333 // Do not unref here, Drawing_t destroyed by it's widget.
334 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
335
336 g_free(Drawing->pango_layout);
337 g_free(Drawing);
338 }
339
340 GtkWidget *drawing_get_widget(Drawing_t *Drawing)
341 {
342 return Drawing->Drawing_Area_V;
343 }
344
345 /* convert_pixels_to_time
346 *
347 * Convert from window pixel and time interval to an absolute time.
348 */
349 void convert_pixels_to_time(
350 gint width,
351 guint x,
352 LttTime *window_time_begin,
353 LttTime *window_time_end,
354 LttTime *time)
355 {
356 LttTime window_time_interval;
357
358 window_time_interval = ltt_time_sub(*window_time_end,
359 *window_time_begin);
360 *time = ltt_time_mul(window_time_interval, (x/(float)width));
361 *time = ltt_time_add(*window_time_begin, *time);
362 }
363
364
365
366 void convert_time_to_pixels(
367 LttTime window_time_begin,
368 LttTime window_time_end,
369 LttTime time,
370 int width,
371 guint *x)
372 {
373 LttTime window_time_interval;
374 float interval_float, time_float;
375
376 window_time_interval = ltt_time_sub(window_time_end,window_time_begin);
377
378 time = ltt_time_sub(time, window_time_begin);
379
380 interval_float = ltt_time_to_double(window_time_interval);
381 time_float = ltt_time_to_double(time);
382
383 *x = (guint)(time_float/interval_float * width);
384
385 }
386
387 void drawing_refresh ( Drawing_t *Drawing,
388 guint x, guint y,
389 guint width, guint height)
390 {
391 g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x, y, width, height);
392 GdkRectangle update_rect;
393
394 gdk_draw_drawable(
395 Drawing->Drawing_Area_V->window,
396 Drawing->Drawing_Area_V->
397 style->fg_gc[GTK_WIDGET_STATE (Drawing->Drawing_Area_V)],
398 GDK_DRAWABLE(Drawing->Pixmap),
399 x, y,
400 x, y,
401 width, height);
402
403 update_rect.x = 0 ;
404 update_rect.y = 0 ;
405 update_rect.width = Drawing->width;
406 update_rect.height = Drawing->height ;
407 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
408
409 }
410
411
412 void drawing_draw_line( Drawing_t *Drawing,
413 GdkPixmap *Pixmap,
414 guint x1, guint y1,
415 guint x2, guint y2,
416 GdkGC *GC)
417 {
418 gdk_draw_line (Pixmap,
419 GC,
420 x1, y1, x2, y2);
421 }
422
423
424
425
426 void drawing_resize(Drawing_t *Drawing, guint h, guint w)
427 {
428 Drawing->height = h ;
429 Drawing->width = w ;
430
431 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
432 Drawing->width,
433 Drawing->height);
434
435
436 }
437
438
439 /* Insert a square corresponding to a new process in the list */
440 /* Applies to whole Drawing->width */
441 void drawing_insert_square(Drawing_t *Drawing,
442 guint y,
443 guint height)
444 {
445 //GdkRectangle update_rect;
446
447 /* Allocate a new pixmap with new height */
448 GdkPixmap *Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
449 Drawing->width + SAFETY,
450 Drawing->height + height + SAFETY,
451 -1);
452
453 /* Copy the high region */
454 gdk_draw_drawable (Pixmap,
455 Drawing->Drawing_Area_V->style->black_gc,
456 Drawing->Pixmap,
457 0, 0,
458 0, 0,
459 Drawing->width + SAFETY, y);
460
461
462
463
464 /* add an empty square */
465 gdk_draw_rectangle (Pixmap,
466 Drawing->Drawing_Area_V->style->white_gc,
467 TRUE,
468 0, y,
469 Drawing->width + SAFETY, // do not overlap
470 height);
471
472
473
474 /* copy the bottom of the region */
475 gdk_draw_drawable (Pixmap,
476 Drawing->Drawing_Area_V->style->black_gc,
477 Drawing->Pixmap,
478 0, y,
479 0, y + height,
480 Drawing->width+SAFETY, Drawing->height - y + SAFETY);
481
482
483
484
485 if (Drawing->Pixmap)
486 gdk_pixmap_unref(Drawing->Pixmap);
487
488 Drawing->Pixmap = Pixmap;
489
490 Drawing->height+=height;
491
492 /* Rectangle to update, from new Drawing dimensions */
493 //update_rect.x = 0 ;
494 //update_rect.y = y ;
495 //update_rect.width = Drawing->width;
496 //update_rect.height = Drawing->height - y ;
497 //gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
498 }
499
500
501 /* Remove a square corresponding to a removed process in the list */
502 void drawing_remove_square(Drawing_t *Drawing,
503 guint y,
504 guint height)
505 {
506 //GdkRectangle update_rect;
507
508 /* Allocate a new pixmap with new height */
509 GdkPixmap *Pixmap = gdk_pixmap_new(
510 Drawing->Drawing_Area_V->window,
511 Drawing->width + SAFETY,
512 Drawing->height - height + SAFETY,
513 -1);
514
515 /* Copy the high region */
516 gdk_draw_drawable (Pixmap,
517 Drawing->Drawing_Area_V->style->black_gc,
518 Drawing->Pixmap,
519 0, 0,
520 0, 0,
521 Drawing->width + SAFETY, y);
522
523
524
525 /* Copy up the bottom of the region */
526 gdk_draw_drawable (Pixmap,
527 Drawing->Drawing_Area_V->style->black_gc,
528 Drawing->Pixmap,
529 0, y + height,
530 0, y,
531 Drawing->width, Drawing->height - y - height + SAFETY);
532
533
534 if (Drawing->Pixmap)
535 gdk_pixmap_unref(Drawing->Pixmap);
536
537 Drawing->Pixmap = Pixmap;
538
539 Drawing->height-=height;
540
541 /* Rectangle to update, from new Drawing dimensions */
542 //update_rect.x = 0 ;
543 //update_rect.y = y ;
544 //update_rect.width = Drawing->width;
545 //update_rect.height = Drawing->height - y ;
546 //gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
547 }
548
549
This page took 0.04105 seconds and 4 git commands to generate.