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