test data sent from hook file, square insert implemented
[lttv.git] / ltt / branches / poly / lttv / modules / guiControlFlow / Drawing.c
1
2 #include "Drawing.h"
3 #include <gtk/gtk.h>
4 #include <gdk/gdk.h>
5
6 #include <lttv/processTrace.h>
7
8 /*****************************************************************************
9 * Drawing functions *
10 *****************************************************************************/
11
12 //FIXME Colors will need to be dynamic. Graphic context part not done so far.
13 typedef enum
14 {
15 RED,
16 GREEN,
17 BLUE,
18 WHITE,
19 BLACK
20
21 } ControlFlowColors;
22
23 /* Vector of unallocated colors */
24 static 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
34 struct _Drawing_t {
35 GtkWidget *Drawing_Area_V;
36 GdkPixmap *Pixmap;
37
38 gint height, width, depth;
39
40 };
41
42 /* Function responsible for updating the exposed area.
43 * It must call processTrace() to ask for this update.
44 */
45 void Drawing_Data_Request(Drawing_t *Drawing,
46 GdkPixmap *Pixmap,
47 gint x, gint y,
48 gint width,
49 gint height)
50 {
51 if(width < 0) return ;
52 if(height < 0) return ;
53
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
64
65 }
66
67 /* Callbacks */
68
69
70 /* Create a new backing pixmap of the appropriate size */
71 static gboolean
72 configure_event( GtkWidget *widget, GdkEventConfigure *event,
73 gpointer user_data)
74 {
75 Drawing_t *Drawing = (Drawing_t*)user_data;
76
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 */
154 static gboolean
155 expose_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
170 Drawing_t *Drawing_construct(void)
171 {
172 Drawing_t *Drawing = g_new(Drawing_t, 1);
173
174 Drawing->Drawing_Area_V = gtk_drawing_area_new ();
175
176 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
177 g_object_set_data_full(
178 G_OBJECT(Drawing->Drawing_Area_V),
179 "Link_Drawing_Data",
180 Drawing,
181 (GDestroyNotify)Drawing_destroy);
182
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
217 return Drawing;
218 }
219
220 void Drawing_destroy(Drawing_t *Drawing)
221 {
222
223 // Do not unref here, Drawing_t destroyed by it's widget.
224 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
225
226 g_free(Drawing);
227 }
228
229 GtkWidget *Drawing_getWidget(Drawing_t *Drawing)
230 {
231 return Drawing->Drawing_Area_V;
232 }
233
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 */
240 void convert_pixels_to_time(
241 Drawing_t *Drawing,
242 guint x,
243 LttTime *window_time_begin,
244 LttTime *window_time_end,
245 LttTime *time)
246 {
247 LttTime window_time_interval;
248
249 TimeSub(window_time_interval, *window_time_end, *window_time_begin);
250
251
252 TimeMul(*time, window_time_interval,
253 (x/(float)Drawing->width));
254 TimeAdd(*time, *window_time_begin, *time);
255
256 }
257
258
259
260 void convert_time_to_pixels(
261 LttTime window_time_begin,
262 LttTime window_time_end,
263 LttTime time,
264 Drawing_t *Drawing,
265 guint *x)
266 {
267 LttTime window_time_interval;
268 float interval_float, time_float;
269
270 TimeSub(window_time_interval, window_time_end, window_time_begin);
271
272 TimeSub(time, time, window_time_begin);
273
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);
280
281 }
282
283 void 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
298 void 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
310
311
312 void Drawing_Resize(Drawing_t *Drawing, guint h, guint w)
313 {
314 Drawing->height = h ;
315 Drawing->width = w ;
316
317 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
318 Drawing->width,
319 Drawing->height);
320
321
322 }
323
324
325 /* Insert a square corresponding to a new process in the list */
326 /* Applies to whole Drawing->width */
327 void 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,
352 Drawing->Drawing_Area_V->style->white_gc,
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 */
388 void 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.04755 seconds and 4 git commands to generate.