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