mega modif by Mathieu Desnoyers. Independant main windows, multiple tracesets, contro...
[lttv.git] / ltt / branches / poly / lttv / modules / guiControlFlow / Drawing.c
CommitLineData
fa2c4dbe 1
f0d936c0 2#include "Drawing.h"
f7afe191 3#include "CFV.h"
76a67e8a 4#include <gtk/gtk.h>
5#include <gdk/gdk.h>
f0d936c0 6
831a876d 7#include <lttv/processTrace.h>
8
f0d936c0 9/*****************************************************************************
10 * Drawing functions *
11 *****************************************************************************/
12
831a876d 13//FIXME Colors will need to be dynamic. Graphic context part not done so far.
f0d936c0 14typedef enum
15{
16 RED,
17 GREEN,
18 BLUE,
19 WHITE,
20 BLACK
21
22} ControlFlowColors;
23
24/* Vector of unallocated colors */
25static 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
f7afe191 35//struct _Drawing_t {
36// GtkWidget *Drawing_Area_V;
37// GdkPixmap *Pixmap;
38// ControlFlowData *Control_Flow_Data;
f0d936c0 39
f7afe191 40// gint height, width, depth;
f0d936c0 41
f7afe191 42//};
f0d936c0 43
831a876d 44/* Function responsible for updating the exposed area.
45 * It must call processTrace() to ask for this update.
46 */
847b479d 47void Drawing_Data_Request(Drawing_t *Drawing,
f7afe191 48 GdkPixmap **Pixmap,
847b479d 49 gint x, gint y,
50 gint width,
51 gint height)
52{
d9b7ca88 53 if(width < 0) return ;
54 if(height < 0) return ;
55
f7afe191 56 gdk_draw_rectangle (*Pixmap,
847b479d 57 Drawing->Drawing_Area_V->style->white_gc,
58 TRUE,
59 x, y,
60 width, // do not overlap
61 height);
62
f7afe191 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);
831a876d 69
847b479d 70}
71
72/* Callbacks */
73
74
75/* Create a new backing pixmap of the appropriate size */
76static gboolean
77configure_event( GtkWidget *widget, GdkEventConfigure *event,
78 gpointer user_data)
f0d936c0 79{
847b479d 80 Drawing_t *Drawing = (Drawing_t*)user_data;
f0d936c0 81
f7afe191 82 /* New Pixmap, size of the configure event */
847b479d 83 GdkPixmap *Pixmap = gdk_pixmap_new(widget->window,
84 widget->allocation.width,
85 widget->allocation.height,
86 -1);
87
f7afe191 88 g_critical("drawing configure event");
89
90 /* If no old Pixmap present */
847b479d 91 if(Drawing->Pixmap == NULL)
92 {
f7afe191 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);
847b479d 100 Drawing->width = widget->allocation.width;
101 Drawing->height = widget->allocation.height;
f7afe191 102g_critical("init data");
847b479d 103 /* Initial data request */
f7afe191 104 Drawing_Data_Request(Drawing, &Drawing->Pixmap, 0, 0,
847b479d 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 */
f7afe191 126g_critical("missing data");
127 Drawing_Data_Request(Drawing, &Pixmap, Drawing->width, 0,
847b479d 128 widget->allocation.width - Drawing->width,
129 widget->allocation.height);
f7afe191 130 Drawing_Data_Request(Drawing, &Pixmap, 0, Drawing->height,
847b479d 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
847b479d 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 */
165static gboolean
166expose_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
f7afe191 181Drawing_t *Drawing_construct(ControlFlowData *Control_Flow_Data)
847b479d 182{
76a67e8a 183 Drawing_t *Drawing = g_new(Drawing_t, 1);
f0d936c0 184
185 Drawing->Drawing_Area_V = gtk_drawing_area_new ();
f7afe191 186 Drawing->Control_Flow_Data = Control_Flow_Data;
187
847b479d 188 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
f0d936c0 189 g_object_set_data_full(
190 G_OBJECT(Drawing->Drawing_Area_V),
76a67e8a 191 "Link_Drawing_Data",
f0d936c0 192 Drawing,
fa2c4dbe 193 (GDestroyNotify)Drawing_destroy);
f0d936c0 194
847b479d 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
847b479d 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
f0d936c0 228 return Drawing;
229}
230
231void Drawing_destroy(Drawing_t *Drawing)
232{
233
76a67e8a 234 // Do not unref here, Drawing_t destroyed by it's widget.
235 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
f0d936c0 236
237 g_free(Drawing);
238}
239
76a67e8a 240GtkWidget *Drawing_getWidget(Drawing_t *Drawing)
241{
242 return Drawing->Drawing_Area_V;
243}
244
f0d936c0 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 */
fa2c4dbe 251void convert_pixels_to_time(
252 Drawing_t *Drawing,
253 guint x,
254 LttTime *window_time_begin,
255 LttTime *window_time_end,
76a67e8a 256 LttTime *time)
f0d936c0 257{
fa2c4dbe 258 LttTime window_time_interval;
f0d936c0 259
76a67e8a 260 TimeSub(window_time_interval, *window_time_end, *window_time_begin);
f0d936c0 261
262
fa2c4dbe 263 TimeMul(*time, window_time_interval,
264 (x/(float)Drawing->width));
76a67e8a 265 TimeAdd(*time, *window_time_begin, *time);
f0d936c0 266
fa2c4dbe 267}
268
269
270
271void convert_time_to_pixels(
272 LttTime window_time_begin,
273 LttTime window_time_end,
274 LttTime time,
275 Drawing_t *Drawing,
76a67e8a 276 guint *x)
fa2c4dbe 277{
278 LttTime window_time_interval;
76a67e8a 279 float interval_float, time_float;
fa2c4dbe 280
281 TimeSub(window_time_interval, window_time_end, window_time_begin);
282
76a67e8a 283 TimeSub(time, time, window_time_begin);
fa2c4dbe 284
76a67e8a 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);
f0d936c0 291
292}
293
847b479d 294void Drawing_Refresh ( Drawing_t *Drawing,
295 guint x, guint y,
296 guint width, guint height)
297{
f7afe191 298 GdkRectangle update_rect;
299
847b479d 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);
f7afe191 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
847b479d 315}
316
317
318void 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
fa2c4dbe 330
331
76a67e8a 332void Drawing_Resize(Drawing_t *Drawing, guint h, guint w)
f0d936c0 333{
f0d936c0 334 Drawing->height = h ;
76a67e8a 335 Drawing->width = w ;
f0d936c0 336
76a67e8a 337 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
338 Drawing->width,
f0d936c0 339 Drawing->height);
340
341
342}
847b479d 343
344
5f16133f 345/* Insert a square corresponding to a new process in the list */
346/* Applies to whole Drawing->width */
347void 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,
1ab3d149 372 Drawing->Drawing_Area_V->style->black_gc,
5f16133f 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 */
408void 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.042295 seconds and 4 git commands to generate.