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