Add Histogram
[lttv.git] / ltt / branches / poly / lttv / modules / gui / histogram / histodrawing.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2006 Parisa heidari (inspired from CFV by Mathieu Desnoyers)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <gtk/gtk.h>
24 #include <gdk/gdk.h>
25 #include <string.h>
26
27 #include <ltt/trace.h>
28
29 #include <lttv/lttv.h>
30 #include <lttv/tracecontext.h>
31 #include <lttvwindow/lttvwindow.h>
32 #include <lttv/state.h>
33 #include <lttv/hook.h>
34
35 #include "histodrawing.h"
36 #include "histoeventhooks.h"
37 #include "histocfv.h"
38
39 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
40 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
41
42 //FIXME
43 #define TRACE_NUMBER 0
44 #define EXTRA_ALLOC 1024 // pixels
45 #define padding_width 50
46
47 #if 0 /* colors for two lines representation */
48 GdkColor histo_drawing_colors[NUM_COLORS] =
49 { /* Pixel, R, G, B */
50 { 0, 0, 0, 0 }, /* COL_BLACK */
51 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
52 { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
53 { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
54 { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
55 { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
56 { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
57 { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
58 { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
59 { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
60 { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
61 { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
62 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_MODE_UNKNOWN : white */
63
64 };
65 #endif //0
66
67
68 GdkColor histo_drawing_colors[NUM_COLORS] =
69 { /* Pixel, R, G, B */
70 { 0, 0, 0, 0 }, /* COL_BLACK */
71 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
72 { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
73 { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
74 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
75 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : red */
76 { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
77 { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
78 { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
79 { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
80 { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */
81 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */
82 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_UNNAMED : white */
83
84 };
85
86 /*
87 RUN+USER MODE green
88 RUN+SYSCALL
89 RUN+TRAP
90 RUN+IRQ
91 WAIT+foncé
92 WAIT CPU + WAIT FORK vert foncé ou jaune
93 IRQ rouge
94 TRAP: orange
95 SYSCALL: bleu pâle
96
97 ZOMBIE + WAIT EXIT
98 */
99
100
101 /*****************************************************************************
102 * drawing functions *
103 *****************************************************************************/
104
105 static gboolean
106 histo_expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
107
108 static gboolean
109 histo_expose_vertical_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
110
111 static gboolean
112 histo_motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
113
114 static gboolean
115 histo_motion_notify_vertical_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
116
117 /* Function responsible for updating the exposed area.
118 * It must do an events request to the lttvwindow API to ask for this update.
119 * Note : this function cannot clear the background, because it may
120 * erase drawing already present (SAFETY).
121 */
122 void histo_drawing_data_request(histoDrawing_t *drawing,
123 gint x, gint y,
124 gint width,
125 gint height)
126 {
127
128 }
129
130
131 void histo_drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss)
132 {
133 g_debug("Begin of data request");
134 HistoControlFlowData *cfd = events_request->viewer_data;
135 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
136 TimeWindow time_window =
137 lttvwindow_get_time_window(cfd->tab);
138
139 guint width = cfd->drawing->width;
140 guint x=0;
141
142 cfd->drawing->last_start = events_request->start_time;
143
144 histo_convert_time_to_pixels(
145 time_window,
146 events_request->start_time,
147 width,
148 &x);
149
150 }
151
152 void histo_drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss)
153 {
154 g_debug("Begin of chunk");
155 HistoControlFlowData *cfd = events_request->viewer_data;
156 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
157 //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
158 guint num_cpu =
159 ltt_trace_get_num_cpu(tss->parent.traces[TRACE_NUMBER]->t);
160
161 /* //disabled for histogram
162 cfd->process_list->current_hash_data = g_new(HashedProcessData*,num_cpu);
163 memset(cfd->process_list->current_hash_data, 0,
164 sizeof(HashedProcessData*)*num_cpu);*/
165 //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
166 // events_request->end_time);
167 }
168
169
170 void histo_drawing_request_expose(EventsRequest *events_request,
171 LttvTracesetState *tss,
172 LttTime end_time)
173 {
174 HistoControlFlowData *cfd = events_request->viewer_data;
175 histoDrawing_t *drawing = cfd->drawing;
176
177 gint x, x_end, width;
178 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
179
180 TimeWindow time_window =
181 lttvwindow_get_time_window(cfd->tab);
182
183 g_debug("histo request expose");
184
185 histo_convert_time_to_pixels(
186 time_window,
187 end_time,
188 drawing->width,
189 &x_end);
190 x = drawing->damage_begin;
191
192 width = x_end - x;
193
194 drawing->damage_begin = x+width;
195
196 // FIXME ?
197 //changed for histogram:
198 gtk_widget_queue_draw_area ( drawing->drawing_area,
199 x, 0,
200 width,
201 drawing->/*drawing_area->allocation.*/height);
202
203 // Update directly when scrolling
204 gdk_window_process_updates(drawing->drawing_area->window,
205 TRUE);
206 }
207
208
209 /* Callbacks */
210
211
212 /* Create a new backing pixmap of the appropriate size */
213 /* As the scaling will always change, it's of no use to copy old
214 * pixmap.
215 *
216 * Change the size if width or height changes.
217 * (different from control flow viewer!)
218 */
219 static gboolean
220 histo_configure_event( GtkWidget *widget, GdkEventConfigure *event,
221 gpointer user_data)
222 {
223 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
224
225 /* First, get the new time interval of the main window */
226 /* we assume (see documentation) that the main window
227 * has updated the time interval before this configure gets
228 * executed.
229 */
230 //lttvwindow_get_time_window(drawing->histo_control_flow_data->mw,
231 // &drawing->histo_control_flow_data->time_window);
232
233 /* New pixmap, size of the configure event */
234 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
235 // widget->allocation.width + SAFETY,
236 // widget->allocation.height + SAFETY,
237 // -1);
238 g_debug("drawing configure event");
239 g_debug("New alloc draw size : %i by %i",widget->allocation.width,
240 widget->allocation.height);
241
242 /*modified for histogram, if width is not changed, GArray is valid so
243 just redraw, else recalculate all.(event request again)*/
244
245 //enabled again for histogram:
246 if(drawing->pixmap)
247 gdk_pixmap_unref(drawing->pixmap);
248
249 drawing->pixmap = gdk_pixmap_new(widget->window,
250 widget->allocation.width ,//+ SAFETY + EXTRA_ALLOC,
251 widget->allocation.height + EXTRA_ALLOC,
252 -1);
253
254 //end add
255 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
256 drawing->alloc_height = drawing->height + EXTRA_ALLOC;
257
258 //drawing->height = widget->allocation.height;
259
260
261
262 // Clear the image
263 // gdk_draw_rectangle (drawing->pixmap,
264 // widget->style->black_gc,
265 // TRUE,
266 // 0, 0,
267 // drawing->width+SAFETY,
268 // drawing->height);
269
270 //g_info("init data request");
271
272
273 /* Initial data request */
274 /* no, do initial data request in the expose event */
275 // Do not need to ask for data of 1 pixel : not synchronized with
276 // main window time at this moment.
277 //histo_drawing_data_request(drawing, &drawing->pixmap, 0, 0,
278 // widget->allocation.width,
279 // widget->allocation.height);
280
281 //drawing->width = widget->allocation.width;
282 //drawing->height = widget->allocation.height;
283
284 drawing->damage_begin = 0;
285 drawing->damage_end = widget->allocation.width;
286
287 if((widget->allocation.width != 1 &&
288 widget->allocation.height != 1)
289 /*&& drawing->damage_begin < drawing->damage_end */)
290 {
291
292 gdk_draw_rectangle (drawing->pixmap,
293 drawing->drawing_area->style->black_gc,
294 TRUE,
295 0, 0,
296 drawing->drawing_area->allocation.width, drawing->drawing_area->allocation.height);
297 /* histo_drawing_data_request(drawing,
298 drawing->damage_begin,
299 0,
300 drawing->damage_end - drawing->damage_begin,
301 drawing->height);*/
302 }
303 //modified for histogram
304
305 if(widget->allocation.width == drawing->width)
306 {
307
308 drawing->height = widget->allocation.height;
309 histogram_show( drawing->histo_control_flow_data,0,
310 drawing->histo_control_flow_data->number_of_process->len);
311 }
312 else
313 {
314 drawing->width = widget->allocation.width;
315 drawing->height = widget->allocation.height;
316
317 g_array_set_size (drawing->histo_control_flow_data->number_of_process,
318 widget->allocation.width);
319 histo_request_event( drawing->histo_control_flow_data,drawing->damage_begin
320 ,drawing->damage_end - drawing->damage_begin);
321 }
322 return TRUE;
323 }
324
325
326 /* Redraw the screen from the backing pixmap */
327 static gboolean
328 histo_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
329 {
330 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
331
332 HistoControlFlowData *histo_control_flow_data =
333 (HistoControlFlowData*)g_object_get_data(
334 G_OBJECT(widget),
335 "histo_control_flow_data");
336 #if 0
337 if(unlikely(drawing->gc == NULL)) {
338 drawing->gc = gdk_gc_new(drawing->drawing_area->window);
339 gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc);
340 }
341 #endif //0
342 TimeWindow time_window =
343 lttvwindow_get_time_window(histo_control_flow_data->tab);
344 LttTime current_time =
345 lttvwindow_get_current_time(histo_control_flow_data->tab);
346
347 guint cursor_x=0;
348
349 LttTime window_end = time_window.end_time;
350
351
352 /* update the screen from the pixmap buffer */
353 //added again for histogram:
354
355 gdk_draw_pixmap(widget->window,
356 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
357 drawing->pixmap,
358 event->area.x, event->area.y,
359 event->area.x, event->area.y,
360 event->area.width, event->area.height);
361 //0
362
363 drawing->height = drawing-> drawing_area ->allocation.height;
364
365 #if 0
366 copy_pixmap_to_screen(histo_control_flow_data->process_list,
367 widget->window,
368 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
369 event->area.x, event->area.y,
370 event->area.width, event->area.height);
371 #endif //0
372
373
374 /* //disabled for histogram
375 copy_pixmap_to_screen(histo_control_flow_data->process_list,
376 widget->window,
377 drawing->gc,
378 event->area.x, event->area.y,
379 event->area.width, event->area.height);*/
380
381 /* Erase the dotted lines left.. */
382 if(widget->allocation.height > drawing->height)
383 {
384 gdk_draw_rectangle (widget->window,
385 drawing->drawing_area->style->black_gc,
386 TRUE,
387 event->area.x, drawing->height,
388 event->area.width, // do not overlap
389 widget->allocation.height - drawing->height);
390 }
391 if(ltt_time_compare(time_window.start_time, current_time) <= 0 &&
392 ltt_time_compare(window_end, current_time) >= 0)
393 {
394 /* Draw the dotted lines */
395 histo_convert_time_to_pixels(
396 time_window,
397 current_time,
398 drawing->width,
399 &cursor_x);
400
401 #if 0
402 if(drawing->dotted_gc == NULL) {
403
404 drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window);
405 gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc);
406
407 gint8 dash_list[] = { 1, 2 };
408 gdk_gc_set_line_attributes(drawing->dotted_gc,
409 1,
410 GDK_LINE_ON_OFF_DASH,
411 GDK_CAP_BUTT,
412 GDK_JOIN_MITER);
413 gdk_gc_set_dashes(drawing->dotted_gc,
414 0,
415 dash_list,
416 2);
417 }
418 #endif //0
419 gint height_tot = MAX(widget->allocation.height, drawing->height);
420 gdk_draw_line(widget->window,
421 drawing->dotted_gc,
422 cursor_x, 0,
423 cursor_x, height_tot);
424 }
425
426 return FALSE;
427 }
428
429 static gboolean
430 histo_after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
431 {
432 //g_assert(0);
433 g_debug("AFTER EXPOSE");
434
435 return FALSE;
436 }
437
438 /* mouse click */
439 static gboolean
440 histo_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
441 {
442 HistoControlFlowData *histo_control_flow_data =
443 (HistoControlFlowData*)g_object_get_data(
444 G_OBJECT(widget),
445 "histo_control_flow_data");
446 histoDrawing_t *drawing = histo_control_flow_data->drawing;
447 TimeWindow time_window =
448 lttvwindow_get_time_window(histo_control_flow_data->tab);
449
450 g_debug("click");
451 if(event->button == 1)
452 {
453 LttTime time;
454
455 /* left mouse button click */
456 g_debug("x click is : %f", event->x);
457
458 histo_convert_pixels_to_time(drawing->width, (guint)event->x,
459 time_window,
460 &time);
461
462 lttvwindow_report_current_time(histo_control_flow_data->tab, time);
463 ////report event->y for vertical zoom +,-
464 }
465
466 return FALSE;
467 }
468 /*
469 //Viewer's vertical scroll bar is already omitted, not needed for histogram.
470 static gboolean
471 scrollbar_size_allocate(GtkWidget *widget,
472 GtkAllocation *allocation,
473 gpointer user_data)
474 {
475 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
476
477 gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
478 //gtk_widget_queue_resize(drawing->padding);
479 //gtk_widget_queue_resize(drawing->ruler);
480 gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
481 return 0;
482 }
483 */
484
485
486 histoDrawing_t *histo_drawing_construct(HistoControlFlowData *histo_control_flow_data)
487 {
488 histoDrawing_t *drawing = g_new(histoDrawing_t, 1);
489
490 drawing->histo_control_flow_data = histo_control_flow_data;
491
492 drawing->vbox = gtk_vbox_new(FALSE, 1);
493
494
495 drawing->ruler_hbox = gtk_hbox_new(FALSE, 1);
496 drawing->ruler = gtk_drawing_area_new ();
497 //gtk_widget_set_size_request(drawing->ruler, -1, 27);
498
499 drawing->padding = gtk_drawing_area_new ();
500 //gtk_widget_set_size_request(drawing->padding, -1, 27);
501
502 gtk_box_pack_start(GTK_BOX(drawing->ruler_hbox), drawing->padding,FALSE, FALSE, 0);
503
504 gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->ruler,
505 TRUE, TRUE, 0);
506
507 drawing->drawing_area = gtk_drawing_area_new ();
508
509 drawing->gc = NULL;
510 /*
511 ///at this time not necessary for histogram
512 drawing->hbox = gtk_hbox_new(FALSE, 1);
513
514 drawing->viewport = gtk_viewport_new(NULL, histo_control_flow_data->v_adjust);
515 drawing->scrollbar = gtk_vscrollbar_new(histo_control_flow_data->v_adjust);
516 gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport,
517 TRUE, TRUE, 0);
518 gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar,
519 FALSE, FALSE, 0);
520 gtk_container_add(GTK_CONTAINER(drawing->viewport),
521 drawing->drawing_area);*/
522
523 //add vertical ruler:
524 drawing->vruler_drawing_hbox = gtk_hbox_new(FALSE, 1);
525 drawing-> vertical_ruler =gtk_drawing_area_new ();
526 gtk_box_pack_start(GTK_BOX(drawing->vruler_drawing_hbox), drawing->vertical_ruler,
527 FALSE, FALSE, 0);
528 gtk_box_pack_end(GTK_BOX(drawing->vruler_drawing_hbox), drawing->drawing_area,
529 TRUE, TRUE, 1);
530 gtk_widget_set_size_request(drawing->vertical_ruler, padding_width, -1);
531
532 gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox,
533 FALSE, FALSE, 1);
534 gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->vruler_drawing_hbox/*drawing_area*/,
535 TRUE, TRUE, 1);
536
537 drawing->pango_layout =
538 gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
539
540 drawing->height = 1;
541 drawing->width = 1;
542 drawing->depth = 0;
543 drawing->alloc_height = 1;
544 drawing->alloc_width = 1;
545
546 drawing->damage_begin = 0;
547 drawing->damage_end = 0;
548 drawing->horizontal_sel = -1;
549
550 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
551 g_object_set_data_full(
552 G_OBJECT(drawing->drawing_area),
553 "histo_Link_drawing_Data",
554 drawing,
555 (GDestroyNotify)histo_drawing_destroy);
556
557 g_object_set_data(
558 G_OBJECT(drawing->ruler),
559 "histo_drawing",
560 drawing);
561
562 g_object_set_data(
563 G_OBJECT(drawing->vertical_ruler),
564 "histo_drawing",
565 drawing);
566
567 //gtk_widget_modify_bg( drawing->drawing_area,
568 // GTK_STATE_NORMAL,
569 // &CF_Colors[BLACK]);
570
571 //gdk_window_get_geometry(drawing->drawing_area->window,
572 // NULL, NULL,
573 // &(drawing->width),
574 // &(drawing->height),
575 // -1);
576
577 //drawing->pixmap = gdk_pixmap_new(
578 // drawing->drawing_area->window,
579 // drawing->width,
580 // drawing->height,
581 // drawing->depth);
582
583 drawing->pixmap = NULL;
584
585 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
586 // drawing->drawing_area->allocation.width,
587 // drawing->drawing_area->allocation.height,
588 // -1);
589
590 g_signal_connect (G_OBJECT(drawing->drawing_area),
591 "configure_event",
592 G_CALLBACK (histo_configure_event),
593 (gpointer)drawing);
594
595 g_signal_connect (G_OBJECT(drawing->ruler),
596 "expose_event",
597 G_CALLBACK(histo_expose_ruler),
598 (gpointer)drawing);
599
600 gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK);
601 gtk_widget_add_events(drawing->vertical_ruler, GDK_POINTER_MOTION_MASK);
602
603 g_signal_connect (G_OBJECT(drawing->ruler),
604 "motion-notify-event",
605 G_CALLBACK(histo_motion_notify_ruler),
606 (gpointer)drawing);
607
608
609 g_signal_connect (G_OBJECT(drawing->vertical_ruler),
610 "expose_event",
611 G_CALLBACK(histo_expose_vertical_ruler),
612 (gpointer)drawing);
613
614 g_signal_connect (G_OBJECT(drawing->vertical_ruler),
615 "motion-notify-event",
616 G_CALLBACK(histo_motion_notify_vertical_ruler),
617 (gpointer)drawing);
618
619 /*//not necessary for historam.
620 g_signal_connect (G_OBJECT(drawing->drawing_area),
621 "size-allocate",
622 G_CALLBACK(scrollbar_size_allocate),
623 (gpointer)drawing); */
624
625
626 gtk_widget_set_size_request(drawing->padding, padding_width, -1);//use it for vertical ruler
627
628 g_signal_connect (G_OBJECT(drawing->drawing_area),
629 "expose_event",
630 G_CALLBACK (histo_expose_event),
631 (gpointer)drawing);
632
633 g_signal_connect_after (G_OBJECT(drawing->drawing_area),
634 "expose_event",
635 G_CALLBACK (histo_after_expose_event),
636 (gpointer)drawing);
637
638 g_signal_connect (G_OBJECT(drawing->drawing_area),
639 "button-press-event",
640 G_CALLBACK (histo_button_press_event),
641 (gpointer)drawing);
642
643 gtk_widget_show(drawing->ruler);
644 gtk_widget_show(drawing->padding);
645 gtk_widget_show(drawing->ruler_hbox);
646 gtk_widget_show(drawing->vertical_ruler);
647 gtk_widget_show(drawing->vruler_drawing_hbox);
648 gtk_widget_show(drawing->drawing_area);
649
650 /// gtk_widget_show(drawing->viewport);
651 /// gtk_widget_show(drawing->scrollbar);
652 /// gtk_widget_show(drawing->hbox);
653
654 /* Allocate the colors */
655 GdkColormap* colormap = gdk_colormap_get_system();
656 gboolean success[NUM_COLORS];
657 gdk_colormap_alloc_colors(colormap, histo_drawing_colors, NUM_COLORS, FALSE,
658 TRUE, success);
659
660 drawing->gc =
661 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
662 drawing->dotted_gc =
663 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
664
665 gdk_gc_copy(drawing->gc,
666 main_window_get_widget(histo_control_flow_data->tab)->style->black_gc);
667 gdk_gc_copy(drawing->dotted_gc,
668 main_window_get_widget(histo_control_flow_data->tab)->style->white_gc);
669
670 gint8 dash_list[] = { 1, 2 };
671 gdk_gc_set_line_attributes(drawing->dotted_gc,
672 1,
673 GDK_LINE_ON_OFF_DASH,
674 GDK_CAP_BUTT,
675 GDK_JOIN_MITER);
676 gdk_gc_set_dashes(drawing->dotted_gc,
677 0,
678 dash_list,
679 2);
680
681 drawing->ruler_gc_butt =
682 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
683 gdk_gc_copy(drawing->ruler_gc_butt,
684 main_window_get_widget(histo_control_flow_data->tab)->style->black_gc);
685 drawing->ruler_gc_round =
686 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(histo_control_flow_data->tab)->window));
687 gdk_gc_copy(drawing->ruler_gc_round,
688 main_window_get_widget(histo_control_flow_data->tab)->style->black_gc);
689
690
691 gdk_gc_set_line_attributes(drawing->ruler_gc_butt,
692 2,
693 GDK_LINE_SOLID,
694 GDK_CAP_BUTT,
695 GDK_JOIN_MITER);
696
697 gdk_gc_set_line_attributes(drawing->ruler_gc_round,
698 2,
699 GDK_LINE_SOLID,
700 GDK_CAP_ROUND,
701 GDK_JOIN_ROUND);
702 return drawing;
703 }
704
705 void histo_drawing_destroy(histoDrawing_t *drawing)
706 {
707 g_info("histo_drawing_destroy %p", drawing);
708
709 /* Free the colors */
710 GdkColormap* colormap = gdk_colormap_get_system();
711
712 gdk_colormap_free_colors(colormap, histo_drawing_colors, NUM_COLORS);
713
714 // Do not unref here, histoDrawing_t destroyed by it's widget.
715 //g_object_unref( G_OBJECT(drawing->drawing_area));
716 if(drawing->gc != NULL)
717 gdk_gc_unref(drawing->gc);
718
719 g_free(drawing->pango_layout);
720 if(drawing->dotted_gc != NULL) gdk_gc_unref(drawing->dotted_gc);
721 if(drawing->ruler_gc_butt != NULL) gdk_gc_unref(drawing->ruler_gc_butt);
722 if(drawing->ruler_gc_round != NULL) gdk_gc_unref(drawing->ruler_gc_round);
723
724 //added for histogram
725 if(drawing->pixmap)
726 gdk_pixmap_unref(drawing->pixmap);
727 g_free(drawing);
728 g_info("histo_drawing_destroy end");
729 }
730
731 GtkWidget *histo_drawing_get_drawing_area(histoDrawing_t *drawing)
732 {
733 return drawing->drawing_area;
734 }
735
736 GtkWidget *histo_drawing_get_widget(histoDrawing_t *drawing)
737 {
738 return drawing->vbox;
739 }
740
741 void histo_drawing_draw_line( histoDrawing_t *drawing,
742 GdkPixmap *pixmap,
743 guint x1, guint y1,
744 guint x2, guint y2,
745 GdkGC *GC)
746 {
747 gdk_draw_line (pixmap,
748 GC,
749 x1, y1, x2, y2);
750 }
751
752 void histo_drawing_clear(histoDrawing_t *drawing,guint clear_from,guint clear_to)
753 {
754
755 HistoControlFlowData *cfd = drawing->histo_control_flow_data;
756 guint clear_width = clear_to- clear_from;
757 /*
758 //disabled for histogram
759 rectangle_pixmap(cfd->process_list,
760 drawing->drawing_area->style->black_gc,
761 TRUE,
762 0, 0,
763 drawing->alloc_width, // do not overlap
764 -1);*/
765 //instead, this is added for histogram
766
767 histo_rectangle_pixmap (drawing->drawing_area->style->black_gc,
768 TRUE,
769 clear_from/*0*/, 0,
770 clear_width/*drawing->width*/,
771 -1,drawing);
772
773
774
775 /* gdk_draw_rectangle (drawing->pixmap,
776 drawing->drawing_area->style->black_gc,
777 TRUE,
778 0,0,
779 drawing->drawing_area->allocation.width,drawing->drawing_area->allocation.height );
780
781 /* ask for the buffer to be redrawn */
782 //enabled again for histogram.
783 gtk_widget_queue_draw_area ( drawing->drawing_area,
784 clear_from, 0,
785 clear_width, drawing->height);
786 gdk_window_process_updates(drawing->drawing_area->window,TRUE);
787 //disabled instead for histogram
788 //gtk_widget_queue_draw ( drawing->drawing_area);
789 return;
790 }
791
792 #if 0
793 /* Insert a square corresponding to a new process in the list */
794 /* Applies to whole drawing->width */
795 void drawing_insert_square(histoDrawing_t *drawing,
796 guint y,
797 guint height)
798 {
799 //GdkRectangle update_rect;
800 gboolean reallocate = FALSE;
801 GdkPixmap *new_pixmap;
802
803 /* Allocate a new pixmap with new height */
804 if(drawing->alloc_height < drawing->height + height) {
805
806 new_pixmap = gdk_pixmap_new(drawing->drawing_area->window,
807 drawing->width + SAFETY + EXTRA_ALLOC,
808 drawing->height + height + EXTRA_ALLOC,
809 -1);
810 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
811 drawing->alloc_height = drawing->height + height + EXTRA_ALLOC;
812 reallocate = TRUE;
813
814 /* Copy the high region */
815 gdk_draw_pixmap (new_pixmap,
816 drawing->drawing_area->style->black_gc,
817 drawing->pixmap,
818 0, 0,
819 0, 0,
820 drawing->width + SAFETY, y);
821
822 } else {
823 new_pixmap = drawing->pixmap;
824 }
825
826 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
827 // drawing->width + SAFETY,
828 // drawing->height + height,
829 // -1);
830
831 /* add an empty square */
832 gdk_draw_rectangle (new_pixmap,
833 drawing->drawing_area->style->black_gc,
834 TRUE,
835 0, y,
836 drawing->width + SAFETY, // do not overlap
837 height);
838
839 /* copy the bottom of the region */
840 gdk_draw_pixmap (new_pixmap,
841 drawing->drawing_area->style->black_gc,
842 drawing->pixmap,
843 0, y,
844 0, y + height,
845 drawing->width+SAFETY, drawing->height - y);
846
847
848 if(reallocate && likely(drawing->pixmap)) {
849 gdk_pixmap_unref(drawing->pixmap);
850 drawing->pixmap = new_pixmap;
851 }
852
853 if(unlikely(drawing->height==1)) drawing->height = height;
854 else drawing->height += height;
855
856 gtk_widget_set_size_request(drawing->drawing_area,
857 -1,
858 drawing->height);
859 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
860
861 /* ask for the buffer to be redrawn */
862 gtk_widget_queue_draw_area ( drawing->drawing_area,
863 0, y,
864 drawing->width, drawing->height-y);
865 }
866
867
868 /* Remove a square corresponding to a removed process in the list */
869 void drawing_remove_square(histoDrawing_t *drawing,
870 guint y,
871 guint height)
872 {
873 GdkPixmap *pixmap;
874
875 if(unlikely((guint)drawing->height == height)) {
876 //pixmap = gdk_pixmap_new(
877 // drawing->drawing_area->window,
878 // drawing->width + SAFETY,
879 // 1,
880 // -1);
881 pixmap = drawing->pixmap;
882 drawing->height=1;
883 } else {
884 /* Allocate a new pixmap with new height */
885 //pixmap = gdk_pixmap_new(
886 // drawing->drawing_area->window,
887 // drawing->width + SAFETY,
888 // drawing->height - height,
889 // -1);
890 /* Keep the same preallocated pixmap */
891 pixmap = drawing->pixmap;
892
893 /* Copy the high region */
894 gdk_draw_pixmap (pixmap,
895 drawing->drawing_area->style->black_gc,
896 drawing->pixmap,
897 0, 0,
898 0, 0,
899 drawing->width + SAFETY, y);
900
901 /* Copy up the bottom of the region */
902 gdk_draw_pixmap (pixmap,
903 drawing->drawing_area->style->black_gc,
904 drawing->pixmap,
905 0, y + height,
906 0, y,
907 drawing->width, drawing->height - y - height);
908
909 drawing->height-=height;
910 }
911
912 //if(likely(drawing->pixmap))
913 // gdk_pixmap_unref(drawing->pixmap);
914
915 //drawing->pixmap = pixmap;
916
917 gtk_widget_set_size_request(drawing->drawing_area,
918 -1,
919 drawing->height);
920 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
921 /* ask for the buffer to be redrawn */
922 gtk_widget_queue_draw_area ( drawing->drawing_area,
923 0, y,
924 drawing->width, MAX(drawing->height-y, 1));
925 }
926 #endif //0
927
928 void histo_drawing_update_ruler(histoDrawing_t *drawing, TimeWindow *time_window)
929 {
930 GtkRequisition req;
931 GdkRectangle rect;
932
933 req.width = drawing->ruler->allocation.width;
934 req.height = drawing->ruler->allocation.height;
935
936
937 rect.x = 0;
938 rect.y = 0;
939 rect.width = req.width;
940 rect.height = req.height;
941
942 gtk_widget_queue_draw(drawing->ruler);
943 //gtk_widget_draw( drawing->ruler, &rect);
944 }
945
946 /* Redraw the ruler */
947 static gboolean
948 histo_expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
949 {
950 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
951 TimeWindow time_window = lttvwindow_get_time_window(drawing->histo_control_flow_data->tab);
952 gchar text[255];
953
954 PangoContext *context;
955 PangoLayout *layout;
956 PangoFontDescription *FontDesc;
957 PangoRectangle ink_rect;
958 gint global_width=0;
959 GdkColor foreground = { 0, 0, 0, 0 };
960 GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
961
962 LttTime window_end = time_window.end_time;
963 LttTime half_width =
964 ltt_time_div(time_window.time_width,2.0);
965 LttTime window_middle =
966 ltt_time_add(half_width,
967 time_window.start_time);
968 g_debug("ruler expose event");
969
970 gdk_draw_rectangle (drawing->ruler->window,
971 drawing->ruler->style->white_gc,
972 TRUE,
973 event->area.x, event->area.y,
974 event->area.width,
975 event->area.height);
976
977 gdk_draw_line (drawing->ruler->window,
978 drawing->ruler_gc_butt,
979 event->area.x, 1,
980 event->area.x + event->area.width, 1);
981
982
983 snprintf(text, 255, "%lus\n%luns",
984 time_window.start_time.tv_sec,
985 time_window.start_time.tv_nsec);
986
987 layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
988
989 context = pango_layout_get_context(layout);
990 FontDesc = pango_context_get_font_description(context);
991
992 pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
993 pango_layout_context_changed(layout);
994
995 pango_layout_set_text(layout, text, -1);
996 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
997 global_width += ink_rect.width;
998
999 gdk_draw_layout_with_colors(drawing->ruler->window,
1000 drawing->ruler_gc_butt,
1001 0,
1002 6,
1003 layout, &foreground, &background);
1004
1005 gdk_draw_line (drawing->ruler->window,
1006 drawing->ruler_gc_round,
1007 1, 1,
1008 1, 7);
1009
1010
1011 snprintf(text, 255, "%lus\n%luns", window_end.tv_sec,
1012 window_end.tv_nsec);
1013
1014 pango_layout_set_text(layout, text, -1);
1015 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1016 global_width += ink_rect.width;
1017
1018 if(global_width <= drawing->ruler->allocation.width)
1019 {
1020 gdk_draw_layout_with_colors(drawing->ruler->window,
1021 drawing->ruler_gc_butt,
1022 drawing->ruler->allocation.width - ink_rect.width,
1023 6,
1024 layout, &foreground, &background);
1025
1026 gdk_draw_line (drawing->ruler->window,
1027 drawing->ruler_gc_butt,
1028 drawing->ruler->allocation.width-1, 1,
1029 drawing->ruler->allocation.width-1, 7);
1030 }
1031
1032
1033 snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec,
1034 window_middle.tv_nsec);
1035
1036 pango_layout_set_text(layout, text, -1);
1037 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1038 global_width += ink_rect.width;
1039
1040 if(global_width <= drawing->ruler->allocation.width)
1041 {
1042 gdk_draw_layout_with_colors(drawing->ruler->window,
1043 drawing->ruler_gc_butt,
1044 (drawing->ruler->allocation.width - ink_rect.width)/2,
1045 6,
1046 layout, &foreground, &background);
1047
1048 gdk_draw_line (drawing->ruler->window,
1049 drawing->ruler_gc_butt,
1050 drawing->ruler->allocation.width/2, 1,
1051 drawing->ruler->allocation.width/2, 7);
1052 }
1053
1054 g_object_unref(layout);
1055
1056 return FALSE;
1057 }
1058
1059 void histo_drawing_update_vertical_ruler(histoDrawing_t *drawing)//, TimeWindow *time_window)
1060 {
1061 GtkRequisition req;
1062 GdkRectangle rect;
1063
1064 req.width = drawing->vertical_ruler->allocation.width;
1065 req.height = drawing->vertical_ruler->allocation.height;
1066
1067 rect.x = 0;
1068 rect.y = 0;
1069 rect.width = req.width;
1070 rect.height = req.height;
1071
1072 gtk_widget_queue_draw(drawing->vertical_ruler);
1073 //gtk_widget_draw( drawing->ruler, &rect);
1074 }
1075
1076 /* notify mouse on ruler */
1077 static gboolean
1078 histo_motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
1079 {
1080 //g_debug("motion");
1081 //eventually follow mouse and show time here
1082 }
1083
1084 static gboolean
1085 histo_motion_notify_vertical_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
1086 {
1087 //g_debug("motion");
1088 //eventually follow mouse and show time here
1089 }
1090
1091
1092
1093 /* Redraw the vertical ruler */
1094 static gboolean
1095 histo_expose_vertical_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
1096 {
1097 histoDrawing_t *drawing = (histoDrawing_t*)user_data;
1098 HistoControlFlowData *histo_cfv = drawing->histo_control_flow_data;
1099 gchar text[255];
1100
1101 PangoContext *context;
1102 PangoLayout *layout;
1103 PangoFontDescription *FontDesc;
1104 PangoRectangle ink_rect;
1105 gint global_height=0;
1106 GdkColor foreground = { 0, 0, 0, 0 };
1107 GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
1108 GdkColor red ={ 0, 0xFFFF, 0x1E00, 0x1000 };
1109 GdkColor magneta ={ 0, 0x8900, 0x0000, 0x8400 };
1110 g_debug("vertical ruler expose event");
1111
1112 gdk_draw_rectangle (drawing->vertical_ruler->window,
1113 drawing->vertical_ruler->style->white_gc,
1114 TRUE,
1115 event->area.x, event->area.y,
1116 event->area.width,
1117 event->area.height);
1118
1119 gdk_draw_line (drawing->vertical_ruler->window,
1120 drawing->ruler_gc_butt,
1121 padding_width-1/*event->area.width-1*/,event->area.y,
1122 padding_width-1/*event->area.width-1*/,event->area.y + event->area.height);
1123
1124 snprintf(text, 255, "%.1f", (float)histo_cfv->max_height);
1125
1126 layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
1127
1128 context = pango_layout_get_context(layout);
1129 FontDesc = pango_context_get_font_description(context);
1130
1131 pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
1132 pango_layout_context_changed(layout);
1133
1134 pango_layout_set_text(layout, text, -1);
1135 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1136 global_height += ink_rect.height;
1137
1138 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1139 drawing->ruler_gc_butt,
1140 1,
1141 1,
1142 layout, &foreground, &background);
1143
1144 gdk_draw_line (drawing->vertical_ruler->window,
1145 drawing->ruler_gc_round,
1146 drawing->vertical_ruler-> allocation.width-1, 1,
1147 drawing->vertical_ruler-> allocation.width-7, 1);
1148
1149
1150 snprintf(text, 255, "%lu",0);
1151
1152 pango_layout_set_text(layout, text, -1);
1153 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1154 global_height += ink_rect.height;
1155
1156 if(global_height <= drawing->vertical_ruler->allocation.height)
1157 {
1158 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1159 drawing->ruler_gc_butt,
1160 1,
1161 drawing->vertical_ruler->allocation.height - ink_rect.height-2,
1162 layout, &foreground, &background);
1163
1164 gdk_draw_line (drawing->vertical_ruler->window,
1165 drawing->ruler_gc_butt,
1166 drawing->vertical_ruler-> allocation.width-1,
1167 drawing->vertical_ruler->allocation.height-1,
1168 drawing->vertical_ruler-> allocation.width-7,
1169 drawing->vertical_ruler->allocation.height-1);
1170 }
1171
1172
1173 snprintf(text, 255, "%.1f",(float) histo_cfv->max_height/2.0);
1174
1175 pango_layout_set_text(layout, text, -1);
1176 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1177 global_height += ink_rect.height;
1178
1179 if(global_height <= drawing->vertical_ruler->allocation.height)
1180 {
1181 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1182 drawing->ruler_gc_butt,
1183 1,
1184 (drawing->vertical_ruler->allocation.height - ink_rect.height)/2,
1185 layout, &foreground, &background);
1186
1187 gdk_draw_line (drawing->vertical_ruler->window,
1188 drawing->ruler_gc_butt,
1189 drawing->vertical_ruler-> allocation.width-1,
1190 drawing->vertical_ruler-> allocation.height/2,
1191 drawing->vertical_ruler-> allocation.width-7,
1192 drawing->vertical_ruler->allocation.height/2);
1193 }
1194
1195 //show number of events at current time:
1196 LttTime current_time =
1197 lttvwindow_get_current_time(histo_cfv->tab);
1198 TimeWindow time_window =
1199 lttvwindow_get_time_window(histo_cfv->tab);
1200 LttTime time_begin = time_window.start_time;
1201 LttTime time_width = time_window.time_width;
1202 LttTime time_end = ltt_time_add(time_begin, time_width);
1203 if((ltt_time_compare(current_time, time_begin) >= 0)&&
1204 (ltt_time_compare(current_time, time_end) <= 0))
1205 {
1206 guint *events_at_currenttime;
1207 guint max_height=histo_cfv ->max_height;
1208 guint x;
1209 histo_convert_time_to_pixels(
1210 time_window,
1211 current_time,
1212 drawing->width,
1213 &x);
1214 // if(x_test<histo_cfv->number_of_process->len)
1215
1216 {
1217 events_at_currenttime =
1218 &g_array_index(histo_cfv->number_of_process,guint,x);
1219
1220
1221 if((*events_at_currenttime) > max_height)
1222 {
1223 snprintf(text, 255, "OverFlow!");
1224 pango_layout_set_text(layout, text, -1);
1225 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1226 global_height += ink_rect.height;
1227 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1228 drawing->ruler_gc_butt,
1229 1,
1230 (drawing->vertical_ruler->allocation.height - ink_rect.height)/5,
1231 layout, &red, &background);
1232 }else
1233 // if((*events_at_currenttime) <= max_height)
1234 {
1235 snprintf(text, 255, "%.1f",
1236 (float) *events_at_currenttime);
1237
1238 pango_layout_set_text(layout, text, -1);
1239 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1240 global_height += ink_rect.height;
1241
1242 if ((*events_at_currenttime) == 0)
1243 {
1244 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1245 drawing->ruler_gc_butt,
1246 1,
1247 (drawing->vertical_ruler->allocation.height - ink_rect.height)-2,
1248 layout, &red, &background);
1249 }
1250 else if ((*events_at_currenttime) == max_height)
1251 {
1252 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1253 drawing->ruler_gc_butt,
1254 1,
1255 1,
1256 layout, &red, &background);
1257 }
1258 /*else if ((*events_at_currenttime) == max_height/2)
1259 {
1260 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1261 drawing->ruler_gc_butt,
1262 1,
1263 (drawing->vertical_ruler->allocation.height - ink_rect.height)/2,
1264 layout, &red, &background);
1265 }*/
1266 else if ((*events_at_currenttime) > max_height/2)
1267 {
1268 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1269 drawing->ruler_gc_butt,
1270 1,
1271 (drawing->vertical_ruler->allocation.height - ink_rect.height)/4,
1272 layout, &red, &background);
1273 }
1274 else{
1275 gdk_draw_layout_with_colors(drawing->vertical_ruler->window,
1276 drawing->ruler_gc_butt,
1277 1,
1278 ((drawing->vertical_ruler->allocation.height
1279 - ink_rect.height)*3)/4,
1280 layout, &red, &background);
1281 }
1282 }
1283
1284 }
1285 }
1286
1287 g_object_unref(layout);
1288
1289 return FALSE;
1290 }
1291
This page took 0.130409 seconds and 5 git commands to generate.