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