mega modif by Mathieu Desnoyers. Independant main windows, multiple tracesets, contro...
[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. This
248 * function uses TimeMul, which should only be used if the float value is lower
249 * that 4, and here it's always lower than 1, so it's ok.
250 */
251 void convert_pixels_to_time(
252 Drawing_t *Drawing,
253 guint x,
254 LttTime *window_time_begin,
255 LttTime *window_time_end,
256 LttTime *time)
257 {
258 LttTime window_time_interval;
259
260 TimeSub(window_time_interval, *window_time_end, *window_time_begin);
261
262
263 TimeMul(*time, window_time_interval,
264 (x/(float)Drawing->width));
265 TimeAdd(*time, *window_time_begin, *time);
266
267 }
268
269
270
271 void convert_time_to_pixels(
272 LttTime window_time_begin,
273 LttTime window_time_end,
274 LttTime time,
275 Drawing_t *Drawing,
276 guint *x)
277 {
278 LttTime window_time_interval;
279 float interval_float, time_float;
280
281 TimeSub(window_time_interval, window_time_end, window_time_begin);
282
283 TimeSub(time, time, window_time_begin);
284
285 interval_float = (window_time_interval.tv_sec * NANSECOND_CONST)
286 + window_time_interval.tv_nsec;
287 time_float = (time.tv_sec * NANSECOND_CONST)
288 + time.tv_nsec;
289
290 *x = (guint)(time_float/interval_float * Drawing->width);
291
292 }
293
294 void Drawing_Refresh ( Drawing_t *Drawing,
295 guint x, guint y,
296 guint width, guint height)
297 {
298 GdkRectangle update_rect;
299
300 gdk_draw_drawable(
301 Drawing->Drawing_Area_V->window,
302 Drawing->Drawing_Area_V->
303 style->fg_gc[GTK_WIDGET_STATE (Drawing->Drawing_Area_V)],
304 GDK_DRAWABLE(Drawing->Pixmap),
305 x, y,
306 x, y,
307 width, height);
308
309 update_rect.x = 0 ;
310 update_rect.y = 0 ;
311 update_rect.width = Drawing->width;
312 update_rect.height = Drawing->height ;
313 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
314
315 }
316
317
318 void Drawing_draw_line( Drawing_t *Drawing,
319 GdkPixmap *Pixmap,
320 guint x1, guint y1,
321 guint x2, guint y2,
322 GdkGC *GC)
323 {
324 gdk_draw_line (Pixmap,
325 GC,
326 x1, y1, x2, y2);
327 }
328
329
330
331
332 void Drawing_Resize(Drawing_t *Drawing, guint h, guint w)
333 {
334 Drawing->height = h ;
335 Drawing->width = w ;
336
337 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
338 Drawing->width,
339 Drawing->height);
340
341
342 }
343
344
345 /* Insert a square corresponding to a new process in the list */
346 /* Applies to whole Drawing->width */
347 void Drawing_Insert_Square(Drawing_t *Drawing,
348 guint y,
349 guint height)
350 {
351 GdkRectangle update_rect;
352
353 /* Allocate a new pixmap with new height */
354 GdkPixmap *Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
355 Drawing->width,
356 Drawing->height + height,
357 -1);
358
359 /* Copy the high region */
360 gdk_draw_drawable (Pixmap,
361 Drawing->Drawing_Area_V->style->black_gc,
362 Drawing->Pixmap,
363 0, 0,
364 0, 0,
365 Drawing->width, y);
366
367
368
369
370 /* add an empty square */
371 gdk_draw_rectangle (Pixmap,
372 Drawing->Drawing_Area_V->style->black_gc,
373 TRUE,
374 0, y,
375 Drawing->width, // do not overlap
376 height);
377
378
379
380 /* copy the bottom of the region */
381 gdk_draw_drawable (Pixmap,
382 Drawing->Drawing_Area_V->style->black_gc,
383 Drawing->Pixmap,
384 0, y,
385 0, y + height,
386 Drawing->width, Drawing->height - y);
387
388
389
390
391 if (Drawing->Pixmap)
392 gdk_pixmap_unref(Drawing->Pixmap);
393
394 Drawing->Pixmap = Pixmap;
395
396 Drawing->height+=height;
397
398 /* Rectangle to update, from new Drawing dimensions */
399 update_rect.x = 0 ;
400 update_rect.y = y ;
401 update_rect.width = Drawing->width;
402 update_rect.height = Drawing->height - y ;
403 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
404 }
405
406
407 /* Remove a square corresponding to a removed process in the list */
408 void Drawing_Remove_Square(Drawing_t *Drawing,
409 guint y,
410 guint height)
411 {
412 GdkRectangle update_rect;
413
414 /* Allocate a new pixmap with new height */
415 GdkPixmap *Pixmap = gdk_pixmap_new(
416 Drawing->Drawing_Area_V->window,
417 Drawing->width,
418 Drawing->height - height,
419 -1);
420
421 /* Copy the high region */
422 gdk_draw_drawable (Pixmap,
423 Drawing->Drawing_Area_V->style->black_gc,
424 Drawing->Pixmap,
425 0, 0,
426 0, 0,
427 Drawing->width, y);
428
429
430
431 /* Copy up the bottom of the region */
432 gdk_draw_drawable (Pixmap,
433 Drawing->Drawing_Area_V->style->black_gc,
434 Drawing->Pixmap,
435 0, y + height,
436 0, y,
437 Drawing->width, Drawing->height - y - height);
438
439
440 if (Drawing->Pixmap)
441 gdk_pixmap_unref(Drawing->Pixmap);
442
443 Drawing->Pixmap = Pixmap;
444
445 Drawing->height-=height;
446
447 /* Rectangle to update, from new Drawing dimensions */
448 update_rect.x = 0 ;
449 update_rect.y = y ;
450 update_rect.width = Drawing->width;
451 update_rect.height = Drawing->height - y ;
452 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
453 }
This page took 0.039386 seconds and 4 git commands to generate.