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