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