current time ready : zoom efficient
[lttv.git] / ltt / branches / poly / lttv / modules / guiControlFlow / Drawing.c
CommitLineData
fa2c4dbe 1
76a67e8a 2#include <gtk/gtk.h>
3#include <gdk/gdk.h>
f0d936c0 4
831a876d 5#include <lttv/processTrace.h>
f66eba62 6#include <lttv/gtkTraceSet.h>
7#include <lttv/hook.h>
831a876d 8
f66eba62 9#include "Drawing.h"
10#include "CFV.h"
11#include "CFV-private.h"
12#include "Event_Hooks.h"
6d5ed1c3 13
14#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
15#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
16
f0d936c0 17/*****************************************************************************
18 * Drawing functions *
19 *****************************************************************************/
20
831a876d 21//FIXME Colors will need to be dynamic. Graphic context part not done so far.
f0d936c0 22typedef enum
23{
24 RED,
25 GREEN,
26 BLUE,
27 WHITE,
28 BLACK
29
30} ControlFlowColors;
31
32/* Vector of unallocated colors */
33static GdkColor CF_Colors [] =
34{
35 { 0, 0xffff, 0x0000, 0x0000 }, // RED
36 { 0, 0x0000, 0xffff, 0x0000 }, // GREEN
37 { 0, 0x0000, 0x0000, 0xffff }, // BLUE
38 { 0, 0xffff, 0xffff, 0xffff }, // WHITE
39 { 0, 0x0000, 0x0000, 0x0000 } // BLACK
40};
41
42
831a876d 43/* Function responsible for updating the exposed area.
44 * It must call processTrace() to ask for this update.
432a7065 45 * Note : this function cannot clear the background, because it may
46 * erase drawing already present (SAFETY).
831a876d 47 */
4c69e0cc 48void drawing_data_request(Drawing_t *Drawing,
f7afe191 49 GdkPixmap **Pixmap,
847b479d 50 gint x, gint y,
4c69e0cc 51 gint width,
847b479d 52 gint height)
53{
d9b7ca88 54 if(width < 0) return ;
55 if(height < 0) return ;
f66eba62 56 ControlFlowData *control_flow_data =
57 (ControlFlowData*)g_object_get_data(
58 G_OBJECT(
59 Drawing->Drawing_Area_V),
60 "Control_Flow_Data");
61
62 LttTime start, end;
63 LttTime window_end = ltt_time_add(control_flow_data->Time_Window.time_width,
64 control_flow_data->Time_Window.start_time);
65
e9a9c513 66 g_critical("req : window_end : %u, %u", window_end.tv_sec,
67 window_end.tv_nsec);
68
69 g_critical("req : time width : %u, %u", control_flow_data->Time_Window.time_width.tv_sec,
70 control_flow_data->Time_Window.time_width.tv_nsec);
71
72 g_critical("x is : %i, x+width is : %i", x, x+width);
73
80a52ff8 74 convert_pixels_to_time(Drawing->Drawing_Area_V->allocation.width, x,
f66eba62 75 &control_flow_data->Time_Window.start_time,
76 &window_end,
77 &start);
78
80a52ff8 79 convert_pixels_to_time(Drawing->Drawing_Area_V->allocation.width, x + width,
f66eba62 80 &control_flow_data->Time_Window.start_time,
81 &window_end,
82 &end);
83
84 LttvTracesetContext * tsc =
85 get_traceset_context(control_flow_data->Parent_Window);
86
432a7065 87 //send_test_process(
e9a9c513 88 //guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
89 //Drawing);
f66eba62 90 //send_test_drawing(
91 //guicontrolflow_get_process_list(Drawing->Control_Flow_Data),
92 //Drawing, *Pixmap, x, y, width, height);
831a876d 93
8d088fb2 94 // Let's call processTrace() !!
f66eba62 95 EventRequest event_request; // Variable freed at the end of the function.
96 event_request.Control_Flow_Data = control_flow_data;
97 event_request.time_begin = start;
98 event_request.time_end = end;
8b90e648 99 event_request.x_begin = x;
100 event_request.x_end = x+width;
f66eba62 101
e9a9c513 102 g_critical("req : start : %u, %u", event_request.time_begin.tv_sec,
103 event_request.time_begin.tv_nsec);
104
105 g_critical("req : end : %u, %u", event_request.time_end.tv_sec,
106 event_request.time_end.tv_nsec);
107
e8814eec 108 LttvHooks *event = lttv_hooks_new();
50439712 109 LttvHooks *after_event = lttv_hooks_new();
8b90e648 110 LttvHooks *after_traceset = lttv_hooks_new();
111 lttv_hooks_add(after_traceset, after_data_request, &event_request);
e8814eec 112 lttv_hooks_add(event, draw_event_hook, &event_request);
9f6858a9 113 state_add_event_hooks_api(control_flow_data->Parent_Window);
50439712 114 lttv_hooks_add(after_event, draw_after_hook, &event_request);
f66eba62 115
116 lttv_process_traceset_seek_time(tsc, start);
8b90e648 117 // FIXME : would like to place the after_traceset hook after the traceset,
118 // but the traceset context state is not valid anymore.
f66eba62 119 lttv_traceset_context_add_hooks(tsc,
8b90e648 120 // NULL, after_traceset, NULL, NULL, NULL, NULL,
f66eba62 121 NULL, NULL, NULL, NULL, NULL, NULL,
8b90e648 122 NULL, after_traceset, NULL, event, after_event);
f66eba62 123 lttv_process_traceset(tsc, end, G_MAXULONG);
8b90e648 124 //after_data_request((void*)&event_request,(void*)tsc);
125 lttv_traceset_context_remove_hooks(tsc,
126 //NULL, after_traceset, NULL, NULL, NULL, NULL,
127 NULL, NULL, NULL, NULL, NULL, NULL,
128 NULL, after_traceset, NULL, event, after_event);
80a52ff8 129 state_remove_event_hooks_api(control_flow_data->Parent_Window);
9f6858a9 130
8b90e648 131 lttv_hooks_destroy(after_traceset);
e8814eec 132 lttv_hooks_destroy(event);
50439712 133 lttv_hooks_destroy(after_event);
8b90e648 134
135
847b479d 136}
137
138/* Callbacks */
139
140
141/* Create a new backing pixmap of the appropriate size */
bd24a9af 142/* As the scaling will always change, it's of no use to copy old
143 * pixmap.
144 */
847b479d 145static gboolean
146configure_event( GtkWidget *widget, GdkEventConfigure *event,
147 gpointer user_data)
f0d936c0 148{
847b479d 149 Drawing_t *Drawing = (Drawing_t*)user_data;
f0d936c0 150
86c520a7 151
152 /* First, get the new time interval of the main window */
153 /* we assume (see documentation) that the main window
154 * has updated the time interval before this configure gets
155 * executed.
156 */
157 get_time_window(Drawing->Control_Flow_Data->Parent_Window,
bd24a9af 158 &Drawing->Control_Flow_Data->Time_Window);
159
f7afe191 160 /* New Pixmap, size of the configure event */
bd24a9af 161 //GdkPixmap *Pixmap = gdk_pixmap_new(widget->window,
162 // widget->allocation.width + SAFETY,
163 // widget->allocation.height + SAFETY,
164 // -1);
847b479d 165
f7afe191 166 g_critical("drawing configure event");
bd24a9af 167 g_critical("New draw size : %i by %i",widget->allocation.width, widget->allocation.height);
168
169
170 if (Drawing->Pixmap)
171 gdk_pixmap_unref(Drawing->Pixmap);
172
f7afe191 173 /* If no old Pixmap present */
bd24a9af 174 //if(Drawing->Pixmap == NULL)
847b479d 175 {
f7afe191 176 Drawing->Pixmap = gdk_pixmap_new(
177 widget->window,
432a7065 178 widget->allocation.width + SAFETY,
179 widget->allocation.height + SAFETY,
f7afe191 180 //ProcessList_get_height
181 // (GuiControlFlow_get_Process_List(Drawing->Control_Flow_Data)),
182 -1);
432a7065 183 Drawing->width = widget->allocation.width;
184 Drawing->height = widget->allocation.height;
bd24a9af 185
432a7065 186
187 // Clear the image
188 gdk_draw_rectangle (Drawing->Pixmap,
189 widget->style->white_gc,
190 TRUE,
191 0, 0,
192 widget->allocation.width+SAFETY,
193 widget->allocation.height+SAFETY);
194
bd24a9af 195 //g_info("init data request");
432a7065 196
197
198 /* Initial data request */
bd24a9af 199 // Do not need to ask for data of 1 pixel : not synchronized with
200 // main window time at this moment.
432a7065 201 drawing_data_request(Drawing, &Drawing->Pixmap, 0, 0,
847b479d 202 widget->allocation.width,
432a7065 203 widget->allocation.height);
bd24a9af 204
205 Drawing->width = widget->allocation.width;
206 Drawing->height = widget->allocation.height;
207
208 return TRUE;
209
210
847b479d 211
212 }
bd24a9af 213#ifdef NOTUSE
847b479d 214// /* Draw empty background */
215// gdk_draw_rectangle (Pixmap,
216// widget->style->black_gc,
217// TRUE,
218// 0, 0,
219// widget->allocation.width,
220// widget->allocation.height);
221
bd24a9af 222 /* Copy old data to new pixmap */
223 gdk_draw_drawable (Pixmap,
224 widget->style->white_gc,
225 Drawing->Pixmap,
226 0, 0,
227 0, 0,
228 -1, -1);
229
80a52ff8 230 if (Drawing->Pixmap)
231 gdk_pixmap_unref(Drawing->Pixmap);
232
233 Drawing->Pixmap = Pixmap;
432a7065 234
235 // Clear the bottom part of the image (SAFETY)
236 gdk_draw_rectangle (Pixmap,
237 widget->style->white_gc,
238 TRUE,
239 0, Drawing->height+SAFETY,
240 Drawing->width+SAFETY, // do not overlap
241 (widget->allocation.height) - Drawing->height);
bd24a9af 242
432a7065 243 // Clear the right part of the image (SAFETY)
244 gdk_draw_rectangle (Pixmap,
245 widget->style->white_gc,
246 TRUE,
247 Drawing->width+SAFETY, 0,
248 (widget->allocation.width) - Drawing->width, // do not overlap
249 Drawing->height+SAFETY);
80a52ff8 250
432a7065 251 /* Clear the backgound for data request, but not SAFETY */
252 gdk_draw_rectangle (Pixmap,
253 Drawing->Drawing_Area_V->style->white_gc,
254 TRUE,
255 Drawing->width + SAFETY, 0,
256 widget->allocation.width - Drawing->width, // do not overlap
257 widget->allocation.height+SAFETY);
bd24a9af 258
432a7065 259 /* Request data for missing space */
260 g_info("missing data request");
261 drawing_data_request(Drawing, &Pixmap, Drawing->width, 0,
262 widget->allocation.width - Drawing->width,
847b479d 263 widget->allocation.height);
80fd7048 264
847b479d 265 Drawing->width = widget->allocation.width;
266 Drawing->height = widget->allocation.height;
267
268 return TRUE;
bd24a9af 269#endif //NOTUSE
847b479d 270}
271
272
273/* Redraw the screen from the backing pixmap */
274static gboolean
275expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
276{
277 Drawing_t *Drawing = (Drawing_t*)user_data;
8b90e648 278 ControlFlowData *control_flow_data =
279 (ControlFlowData*)g_object_get_data(
280 G_OBJECT(widget),
281 "Control_Flow_Data");
282
847b479d 283 g_critical("drawing expose event");
8b90e648 284
285 guint x=0;
286 LttTime* Current_Time =
287 guicontrolflow_get_current_time(control_flow_data);
847b479d 288
8b90e648 289 LttTime window_end = ltt_time_add(control_flow_data->Time_Window.time_width,
290 control_flow_data->Time_Window.start_time);
291
292 convert_time_to_pixels(
293 control_flow_data->Time_Window.start_time,
294 window_end,
295 *Current_Time,
296 widget->allocation.width,
297 &x);
298
847b479d 299 gdk_draw_pixmap(widget->window,
300 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
301 Drawing->Pixmap,
302 event->area.x, event->area.y,
303 event->area.x, event->area.y,
304 event->area.width, event->area.height);
305
8b90e648 306 if(x >= event->area.x && x <= event->area.x+event->area.width)
307 {
308 GdkGC *gc = gdk_gc_new(control_flow_data->Drawing->Pixmap);
309 gdk_gc_copy(gc, widget->style->black_gc);
310
311 drawing_draw_line(NULL, widget->window,
312 x, event->area.y,
313 x, event->area.y+event->area.height,
314 gc);
315 gdk_gc_unref(gc);
316 }
847b479d 317 return FALSE;
318}
319
8b90e648 320/* mouse click */
321static gboolean
322button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
323{
324 ControlFlowData *control_flow_data =
325 (ControlFlowData*)g_object_get_data(
326 G_OBJECT(widget),
327 "Control_Flow_Data");
328 Drawing_t *Drawing = control_flow_data->Drawing;
329
330
331 g_critical("click");
332 if(event->button == 1)
333 {
334 LttTime time;
335
336 LttTime window_end = ltt_time_add(control_flow_data->Time_Window.time_width,
337 control_flow_data->Time_Window.start_time);
338
339
340 /* left mouse button click */
341 g_critical("x click is : %f", event->x);
342
343 convert_pixels_to_time(widget->allocation.width, (guint)event->x,
344 &control_flow_data->Time_Window.start_time,
345 &window_end,
346 &time);
347
348 set_current_time(control_flow_data->Parent_Window, &time);
349
350 }
351
352 return FALSE;
353}
354
355
356
357
4c69e0cc 358Drawing_t *drawing_construct(ControlFlowData *Control_Flow_Data)
847b479d 359{
76a67e8a 360 Drawing_t *Drawing = g_new(Drawing_t, 1);
f0d936c0 361
362 Drawing->Drawing_Area_V = gtk_drawing_area_new ();
f7afe191 363 Drawing->Control_Flow_Data = Control_Flow_Data;
364
34b04882 365 Drawing->pango_layout =
366 gtk_widget_create_pango_layout(Drawing->Drawing_Area_V, NULL);
367
847b479d 368 //gtk_widget_set_size_request(Drawing->Drawing_Area_V->window, 50, 50);
f0d936c0 369 g_object_set_data_full(
370 G_OBJECT(Drawing->Drawing_Area_V),
76a67e8a 371 "Link_Drawing_Data",
f0d936c0 372 Drawing,
3cff8cc1 373 (GDestroyNotify)drawing_destroy);
f0d936c0 374
847b479d 375 //gtk_widget_modify_bg( Drawing->Drawing_Area_V,
376 // GTK_STATE_NORMAL,
377 // &CF_Colors[BLACK]);
378
379 //gdk_window_get_geometry(Drawing->Drawing_Area_V->window,
380 // NULL, NULL,
381 // &(Drawing->width),
382 // &(Drawing->height),
383 // -1);
384
385 //Drawing->Pixmap = gdk_pixmap_new(
386 // Drawing->Drawing_Area_V->window,
387 // Drawing->width,
388 // Drawing->height,
389 // Drawing->depth);
390
391 Drawing->Pixmap = NULL;
392
393// Drawing->Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
394// Drawing->Drawing_Area_V->allocation.width,
395// Drawing->Drawing_Area_V->allocation.height,
396// -1);
397
8b90e648 398 gtk_widget_add_events(Drawing->Drawing_Area_V, GDK_BUTTON_PRESS_MASK);
399
847b479d 400 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
401 "configure_event",
402 G_CALLBACK (configure_event),
403 (gpointer)Drawing);
404
405 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
406 "expose_event",
407 G_CALLBACK (expose_event),
408 (gpointer)Drawing);
409
8b90e648 410 g_signal_connect (G_OBJECT(Drawing->Drawing_Area_V),
411 "button-press-event",
412 G_CALLBACK (button_press_event),
413 (gpointer)Drawing);
414
415
f0d936c0 416 return Drawing;
417}
418
4c69e0cc 419void drawing_destroy(Drawing_t *Drawing)
f0d936c0 420{
421
76a67e8a 422 // Do not unref here, Drawing_t destroyed by it's widget.
423 //g_object_unref( G_OBJECT(Drawing->Drawing_Area_V));
f0d936c0 424
34b04882 425 g_free(Drawing->pango_layout);
f0d936c0 426 g_free(Drawing);
427}
428
4c69e0cc 429GtkWidget *drawing_get_widget(Drawing_t *Drawing)
76a67e8a 430{
431 return Drawing->Drawing_Area_V;
432}
433
f66eba62 434/* convert_pixels_to_time
f0d936c0 435 *
f66eba62 436 * Convert from window pixel and time interval to an absolute time.
f0d936c0 437 */
fa2c4dbe 438void convert_pixels_to_time(
e9a9c513 439 gint width,
fa2c4dbe 440 guint x,
441 LttTime *window_time_begin,
442 LttTime *window_time_end,
76a67e8a 443 LttTime *time)
f0d936c0 444{
fa2c4dbe 445 LttTime window_time_interval;
f0d936c0 446
308711e5 447 window_time_interval = ltt_time_sub(*window_time_end,
448 *window_time_begin);
e9a9c513 449 *time = ltt_time_mul(window_time_interval, (x/(float)width));
308711e5 450 *time = ltt_time_add(*window_time_begin, *time);
fa2c4dbe 451}
452
453
454
455void convert_time_to_pixels(
456 LttTime window_time_begin,
457 LttTime window_time_end,
458 LttTime time,
e9a9c513 459 int width,
76a67e8a 460 guint *x)
fa2c4dbe 461{
462 LttTime window_time_interval;
76a67e8a 463 float interval_float, time_float;
fa2c4dbe 464
308711e5 465 window_time_interval = ltt_time_sub(window_time_end,window_time_begin);
fa2c4dbe 466
308711e5 467 time = ltt_time_sub(time, window_time_begin);
fa2c4dbe 468
308711e5 469 interval_float = ltt_time_to_double(window_time_interval);
470 time_float = ltt_time_to_double(time);
76a67e8a 471
e9a9c513 472 *x = (guint)(time_float/interval_float * width);
f0d936c0 473
474}
475
4c69e0cc 476void drawing_refresh ( Drawing_t *Drawing,
847b479d 477 guint x, guint y,
478 guint width, guint height)
479{
6d5ed1c3 480 g_info("Drawing.c : drawing_refresh %u, %u, %u, %u", x, y, width, height);
f7afe191 481 GdkRectangle update_rect;
482
847b479d 483 gdk_draw_drawable(
484 Drawing->Drawing_Area_V->window,
485 Drawing->Drawing_Area_V->
486 style->fg_gc[GTK_WIDGET_STATE (Drawing->Drawing_Area_V)],
487 GDK_DRAWABLE(Drawing->Pixmap),
488 x, y,
489 x, y,
490 width, height);
f7afe191 491
492 update_rect.x = 0 ;
493 update_rect.y = 0 ;
494 update_rect.width = Drawing->width;
495 update_rect.height = Drawing->height ;
496 gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
497
847b479d 498}
499
500
4c69e0cc 501void drawing_draw_line( Drawing_t *Drawing,
847b479d 502 GdkPixmap *Pixmap,
503 guint x1, guint y1,
504 guint x2, guint y2,
505 GdkGC *GC)
506{
507 gdk_draw_line (Pixmap,
508 GC,
509 x1, y1, x2, y2);
510}
511
512
fa2c4dbe 513
514
4c69e0cc 515void drawing_resize(Drawing_t *Drawing, guint h, guint w)
f0d936c0 516{
f0d936c0 517 Drawing->height = h ;
76a67e8a 518 Drawing->width = w ;
f0d936c0 519
76a67e8a 520 gtk_widget_set_size_request ( Drawing->Drawing_Area_V,
521 Drawing->width,
f0d936c0 522 Drawing->height);
523
524
525}
847b479d 526
527
5f16133f 528/* Insert a square corresponding to a new process in the list */
529/* Applies to whole Drawing->width */
4c69e0cc 530void drawing_insert_square(Drawing_t *Drawing,
5f16133f 531 guint y,
532 guint height)
533{
bd24a9af 534 //GdkRectangle update_rect;
5f16133f 535
536 /* Allocate a new pixmap with new height */
537 GdkPixmap *Pixmap = gdk_pixmap_new(Drawing->Drawing_Area_V->window,
432a7065 538 Drawing->width + SAFETY,
539 Drawing->height + height + SAFETY,
5f16133f 540 -1);
541
542 /* Copy the high region */
543 gdk_draw_drawable (Pixmap,
544 Drawing->Drawing_Area_V->style->black_gc,
545 Drawing->Pixmap,
546 0, 0,
547 0, 0,
432a7065 548 Drawing->width + SAFETY, y);
5f16133f 549
550
551
552
553 /* add an empty square */
554 gdk_draw_rectangle (Pixmap,
50439712 555 Drawing->Drawing_Area_V->style->white_gc,
5f16133f 556 TRUE,
557 0, y,
432a7065 558 Drawing->width + SAFETY, // do not overlap
5f16133f 559 height);
560
561
562
563 /* copy the bottom of the region */
564 gdk_draw_drawable (Pixmap,
565 Drawing->Drawing_Area_V->style->black_gc,
566 Drawing->Pixmap,
567 0, y,
568 0, y + height,
bd24a9af 569 Drawing->width+SAFETY, Drawing->height - y + SAFETY);
5f16133f 570
571
572
573
574 if (Drawing->Pixmap)
575 gdk_pixmap_unref(Drawing->Pixmap);
576
577 Drawing->Pixmap = Pixmap;
578
579 Drawing->height+=height;
580
581 /* Rectangle to update, from new Drawing dimensions */
bd24a9af 582 //update_rect.x = 0 ;
583 //update_rect.y = y ;
584 //update_rect.width = Drawing->width;
585 //update_rect.height = Drawing->height - y ;
586 //gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
5f16133f 587}
588
589
590/* Remove a square corresponding to a removed process in the list */
4c69e0cc 591void drawing_remove_square(Drawing_t *Drawing,
5f16133f 592 guint y,
593 guint height)
594{
bd24a9af 595 //GdkRectangle update_rect;
5f16133f 596
597 /* Allocate a new pixmap with new height */
598 GdkPixmap *Pixmap = gdk_pixmap_new(
599 Drawing->Drawing_Area_V->window,
432a7065 600 Drawing->width + SAFETY,
601 Drawing->height - height + SAFETY,
5f16133f 602 -1);
603
604 /* Copy the high region */
605 gdk_draw_drawable (Pixmap,
606 Drawing->Drawing_Area_V->style->black_gc,
607 Drawing->Pixmap,
608 0, 0,
609 0, 0,
432a7065 610 Drawing->width + SAFETY, y);
5f16133f 611
612
613
614 /* Copy up the bottom of the region */
615 gdk_draw_drawable (Pixmap,
616 Drawing->Drawing_Area_V->style->black_gc,
617 Drawing->Pixmap,
618 0, y + height,
619 0, y,
432a7065 620 Drawing->width, Drawing->height - y - height + SAFETY);
5f16133f 621
622
623 if (Drawing->Pixmap)
624 gdk_pixmap_unref(Drawing->Pixmap);
625
626 Drawing->Pixmap = Pixmap;
627
628 Drawing->height-=height;
629
630 /* Rectangle to update, from new Drawing dimensions */
bd24a9af 631 //update_rect.x = 0 ;
632 //update_rect.y = y ;
633 //update_rect.width = Drawing->width;
634 //update_rect.height = Drawing->height - y ;
635 //gtk_widget_draw( Drawing->Drawing_Area_V, &update_rect);
5f16133f 636}
189a5d08 637
638
This page took 0.053292 seconds and 4 git commands to generate.