fixed some drawing details
[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 state_add_event_hooks_api(control_flow_data->Parent_Window);
108 lttv_hooks_add(event, draw_event_hook, &event_request);
109
110 lttv_process_traceset_seek_time(tsc, start);
111 lttv_traceset_context_add_hooks(tsc,
112 NULL, NULL, NULL, NULL, NULL, NULL,
113 NULL, NULL, NULL, event, NULL);
114 lttv_process_traceset(tsc, end, G_MAXULONG);
115 lttv_traceset_context_remove_hooks(tsc, NULL, NULL, NULL, NULL, NULL, NULL,
116 NULL, NULL, NULL, event, NULL);
117
118 state_remove_event_hooks_api(control_flow_data->Parent_Window);
119 lttv_hooks_destroy(event);
120 }
121
122 /* Callbacks */
123
124
125 /* Create a new backing pixmap of the appropriate size */
126 static gboolean
127 configure_event( GtkWidget *widget, GdkEventConfigure *event,
128 gpointer user_data)
129 {
130 Drawing_t *Drawing = (Drawing_t*)user_data;
131
132
133 /* First, get the new time interval of the main window */
134 /* we assume (see documentation) that the main window
135 * has updated the time interval before this configure gets
136 * executed.
137 */
138 get_time_window(Drawing->Control_Flow_Data->Parent_Window,
139 &Drawing->Control_Flow_Data->Time_Window);
140
141 /* New Pixmap, size of the configure event */
142 GdkPixmap *Pixmap = gdk_pixmap_new(widget->window,
143 widget->allocation.width + SAFETY,
144 widget->allocation.height + SAFETY,
145 -1);
146
147 g_critical("drawing configure event");
148
149 /* If no old Pixmap present */
150 if(Drawing->Pixmap == NULL)
151 {
152 Drawing->Pixmap = gdk_pixmap_new(
153 widget->window,
154 widget->allocation.width + SAFETY,
155 widget->allocation.height + SAFETY,
156 //ProcessList_get_height
157 // (GuiControlFlow_get_Process_List(Drawing->Control_Flow_Data)),
158 -1);
159 Drawing->width = widget->allocation.width;
160 Drawing->height = widget->allocation.height;
161
162 // Clear the image
163 gdk_draw_rectangle (Drawing->Pixmap,
164 widget->style->white_gc,
165 TRUE,
166 0, 0,
167 widget->allocation.width+SAFETY,
168 widget->allocation.height+SAFETY);
169
170 g_info("init data request");
171
172
173 /* Initial data request */
174 drawing_data_request(Drawing, &Drawing->Pixmap, 0, 0,
175 widget->allocation.width,
176 widget->allocation.height);
177
178 }
179 // /* Draw empty background */
180 // gdk_draw_rectangle (Pixmap,
181 // widget->style->black_gc,
182 // TRUE,
183 // 0, 0,
184 // widget->allocation.width,
185 // widget->allocation.height);
186
187 /* Copy old data to new pixmap */
188 gdk_draw_drawable (Pixmap,
189 widget->style->white_gc,
190 Drawing->Pixmap,
191 0, 0,
192 0, 0,
193 -1, -1);
194
195 if (Drawing->Pixmap)
196 gdk_pixmap_unref(Drawing->Pixmap);
197
198 Drawing->Pixmap = Pixmap;
199
200 // Clear the bottom part of the image (SAFETY)
201 gdk_draw_rectangle (Pixmap,
202 widget->style->white_gc,
203 TRUE,
204 0, Drawing->height+SAFETY,
205 Drawing->width+SAFETY, // do not overlap
206 (widget->allocation.height) - Drawing->height);
207 // Clear the right part of the image (SAFETY)
208 gdk_draw_rectangle (Pixmap,
209 widget->style->white_gc,
210 TRUE,
211 Drawing->width+SAFETY, 0,
212 (widget->allocation.width) - Drawing->width, // do not overlap
213 Drawing->height+SAFETY);
214
215 /* Clear the backgound for data request, but not SAFETY */
216 gdk_draw_rectangle (Pixmap,
217 Drawing->Drawing_Area_V->style->white_gc,
218 TRUE,
219 Drawing->width + SAFETY, 0,
220 widget->allocation.width - Drawing->width, // do not overlap
221 widget->allocation.height+SAFETY);
222 /* Request data for missing space */
223 g_info("missing data request");
224 drawing_data_request(Drawing, &Pixmap, Drawing->width, 0,
225 widget->allocation.width - Drawing->width,
226 widget->allocation.height);
227 // we do not request data vertically!
228 // drawing_data_request(Drawing, &Pixmap, 0, Drawing->height,
229 // Drawing->width,
230 // widget->allocation.height - Drawing->height);
231
232 // gdk_draw_rectangle (Pixmap,
233 // widget->style->white_gc,
234 // TRUE,
235 // Drawing->width, 0,
236 // widget->allocation.width -
237 // Drawing->width,
238 // widget->allocation.height);
239 Drawing->width = widget->allocation.width;
240 Drawing->height = widget->allocation.height;
241
242 return TRUE;
243 }
244
245
246 /* Redraw the screen from the backing pixmap */
247 static gboolean
248 expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
249 {
250 Drawing_t *Drawing = (Drawing_t*)user_data;
251 g_critical("drawing expose event");
252
253 gdk_draw_pixmap(widget->window,
254 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
255 Drawing->Pixmap,
256 event->area.x, event->area.y,
257 event->area.x, event->area.y,
258 event->area.width, event->area.height);
259
260 return FALSE;
261 }
262
263 Drawing_t *drawing_construct(ControlFlowData *Control_Flow_Data)
264 {
265 Drawing_t *Drawing = g_new(Drawing_t, 1);
266
267 Drawing->Drawing_Area_V = gtk_drawing_area_new ();
268 Drawing->Control_Flow_Data = Control_Flow_Data;
269
270 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
271 g_object_set_data_full(
272 G_OBJECT(Drawing->Drawing_Area_V),
273 "Link_Drawing_Data",
274 Drawing,
275 (GDestroyNotify)drawing_destroy);
276
277 //gtk_widget_modify_bg( Drawing->Drawing_Area_V,
278 // GTK_STATE_NORMAL,
279 // &CF_Colors[BLACK]);
280
281 //gdk_window_get_geometry(Drawing->Drawing_Area_V->window,
282 // NULL, NULL,
283 // &(Drawing->width),
284 // &(Drawing->height),
285 // -1);
286
287 //Drawing->Pixmap = gdk_pixmap_new(
288 // Drawing->Drawing_Area_V->window,
289 // Drawing->width,
290 // Drawing->height,
291 // Drawing->depth);
292
293 Drawing->Pixmap = NULL;
294
295 // Drawing->Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
296 // Drawing->Drawing_Area_V->allocation.width,
297 // Drawing->Drawing_Area_V->allocation.height,
298 // -1);
299
300 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
301 "configure_event",
302 G_CALLBACK (configure_event),
303 (gpointer)Drawing);
304
305 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
306 "expose_event",
307 G_CALLBACK (expose_event),
308 (gpointer)Drawing);
309
310 return Drawing;
311 }
312
313 void drawing_destroy(Drawing_t *Drawing)
314 {
315
316 // Do not unref here, Drawing_t destroyed by it's widget.
317 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
318
319 g_free(Drawing);
320 }
321
322 GtkWidget *drawing_get_widget(Drawing_t *Drawing)
323 {
324 return Drawing->Drawing_Area_V;
325 }
326
327 /* convert_pixels_to_time
328 *
329 * Convert from window pixel and time interval to an absolute time.
330 */
331 void convert_pixels_to_time(
332 gint width,
333 guint x,
334 LttTime *window_time_begin,
335 LttTime *window_time_end,
336 LttTime *time)
337 {
338 LttTime window_time_interval;
339
340 window_time_interval = ltt_time_sub(*window_time_end,
341 *window_time_begin);
342 *time = ltt_time_mul(window_time_interval, (x/(float)width));
343 *time = ltt_time_add(*window_time_begin, *time);
344 }
345
346
347
348 void convert_time_to_pixels(
349 LttTime window_time_begin,
350 LttTime window_time_end,
351 LttTime time,
352 int width,
353 guint *x)
354 {
355 LttTime window_time_interval;
356 float interval_float, time_float;
357
358 window_time_interval = ltt_time_sub(window_time_end,window_time_begin);
359
360 time = ltt_time_sub(time, window_time_begin);
361
362 interval_float = ltt_time_to_double(window_time_interval);
363 time_float = ltt_time_to_double(time);
364
365 *x = (guint)(time_float/interval_float * width);
366
367 }
368
369 void drawing_refresh ( Drawing_t *Drawing,
370 guint x, guint y,
371 guint width, guint height)
372 {
373 g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x, y, width, height);
374 GdkRectangle update_rect;
375
376 gdk_draw_drawable(
377 Drawing->Drawing_Area_V->window,
378 Drawing->Drawing_Area_V->
379 style->fg_gc[GTK_WIDGET_STATE (Drawing->Drawing_Area_V)],
380 GDK_DRAWABLE(Drawing->Pixmap),
381 x, y,
382 x, y,
383 width, height);
384
385 update_rect.x = 0 ;
386 update_rect.y = 0 ;
387 update_rect.width = Drawing->width;
388 update_rect.height = Drawing->height ;
389 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
390
391 }
392
393
394 void drawing_draw_line( Drawing_t *Drawing,
395 GdkPixmap *Pixmap,
396 guint x1, guint y1,
397 guint x2, guint y2,
398 GdkGC *GC)
399 {
400 gdk_draw_line (Pixmap,
401 GC,
402 x1, y1, x2, y2);
403 }
404
405
406
407
408 void drawing_resize(Drawing_t *Drawing, guint h, guint w)
409 {
410 Drawing->height = h ;
411 Drawing->width = w ;
412
413 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
414 Drawing->width,
415 Drawing->height);
416
417
418 }
419
420
421 /* Insert a square corresponding to a new process in the list */
422 /* Applies to whole Drawing->width */
423 void drawing_insert_square(Drawing_t *Drawing,
424 guint y,
425 guint height)
426 {
427 GdkRectangle update_rect;
428
429 /* Allocate a new pixmap with new height */
430 GdkPixmap *Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
431 Drawing->width + SAFETY,
432 Drawing->height + height + SAFETY,
433 -1);
434
435 /* Copy the high region */
436 gdk_draw_drawable (Pixmap,
437 Drawing->Drawing_Area_V->style->black_gc,
438 Drawing->Pixmap,
439 0, 0,
440 0, 0,
441 Drawing->width + SAFETY, y);
442
443
444
445
446 /* add an empty square */
447 gdk_draw_rectangle (Pixmap,
448 Drawing->Drawing_Area_V->style->black_gc,
449 TRUE,
450 0, y,
451 Drawing->width + SAFETY, // do not overlap
452 height);
453
454
455
456 /* copy the bottom of the region */
457 gdk_draw_drawable (Pixmap,
458 Drawing->Drawing_Area_V->style->black_gc,
459 Drawing->Pixmap,
460 0, y,
461 0, y + height,
462 Drawing->width, Drawing->height - y + SAFETY);
463
464
465
466
467 if (Drawing->Pixmap)
468 gdk_pixmap_unref(Drawing->Pixmap);
469
470 Drawing->Pixmap = Pixmap;
471
472 Drawing->height+=height;
473
474 /* Rectangle to update, from new Drawing dimensions */
475 update_rect.x = 0 ;
476 update_rect.y = y ;
477 update_rect.width = Drawing->width;
478 update_rect.height = Drawing->height - y ;
479 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
480 }
481
482
483 /* Remove a square corresponding to a removed process in the list */
484 void drawing_remove_square(Drawing_t *Drawing,
485 guint y,
486 guint height)
487 {
488 GdkRectangle update_rect;
489
490 /* Allocate a new pixmap with new height */
491 GdkPixmap *Pixmap = gdk_pixmap_new(
492 Drawing->Drawing_Area_V->window,
493 Drawing->width + SAFETY,
494 Drawing->height - height + SAFETY,
495 -1);
496
497 /* Copy the high region */
498 gdk_draw_drawable (Pixmap,
499 Drawing->Drawing_Area_V->style->black_gc,
500 Drawing->Pixmap,
501 0, 0,
502 0, 0,
503 Drawing->width + SAFETY, y);
504
505
506
507 /* Copy up the bottom of the region */
508 gdk_draw_drawable (Pixmap,
509 Drawing->Drawing_Area_V->style->black_gc,
510 Drawing->Pixmap,
511 0, y + height,
512 0, y,
513 Drawing->width, Drawing->height - y - height + SAFETY);
514
515
516 if (Drawing->Pixmap)
517 gdk_pixmap_unref(Drawing->Pixmap);
518
519 Drawing->Pixmap = Pixmap;
520
521 Drawing->height-=height;
522
523 /* Rectangle to update, from new Drawing dimensions */
524 update_rect.x = 0 ;
525 update_rect.y = y ;
526 update_rect.width = Drawing->width;
527 update_rect.height = Drawing->height - y ;
528 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
529 }
530
531
This page took 0.040416 seconds and 4 git commands to generate.