1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
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;
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.
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,
27 #include <ltt/trace.h>
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>
36 #include "eventhooks.h"
39 //#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
42 // fixed #define TRACE_NUMBER 0
43 #define EXTRA_ALLOC 1024 // pixels
46 #if 0 /* colors for two lines representation */
47 GdkColor drawing_colors
[NUM_COLORS
] =
48 { /* Pixel, R, G, B */
49 { 0, 0, 0, 0 }, /* COL_BLACK */
50 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
51 { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
52 { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
53 { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
54 { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
55 { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
56 { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
57 { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
58 { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
59 { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
60 { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
61 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_MODE_UNKNOWN : white */
67 GdkColor drawing_colors
[NUM_COLORS
] =
68 { /* Pixel, R, G, B */
69 { 0, 0, 0, 0 }, /* COL_BLACK */
70 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
71 { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
72 { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
73 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
74 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : orange */
75 { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_RUN_SOFT_IRQ : pink */
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 */
86 GdkColor drawing_colors_cpu
[NUM_COLORS_CPU
] =
87 { /* Pixel, R, G, B */
88 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_CPU_UNKNOWN */
89 { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_CPU_IDLE */
90 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_CPU_BUSY */
91 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_CPU_IRQ */
92 { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_CPU_SOFT_IRQ */
93 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_CPU_TRAP */
96 GdkColor drawing_colors_irq
[NUM_COLORS_IRQ
] =
97 { /* Pixel, R, G, B */
98 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_IRQ_UNKNOWN */
99 { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_IRQ_IDLE */
100 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_IRQ_BUSY */
103 GdkColor drawing_colors_soft_irq
[NUM_COLORS_SOFT_IRQ
] =
104 { /* Pixel, R, G, B */
105 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_SOFT_IRQ_UNKNOWN */
106 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_SOFT_IRQ_IDLE */
107 { 0, 0xFFFF, 0xD400, 0xD400 }, /* COL_SOFT_IRQ_PENDING */
108 { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_SOFT_IRQ_BUSY */
111 GdkColor drawing_colors_trap
[NUM_COLORS_TRAP
] =
112 { /* Pixel, R, G, B */
113 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_TRAP_UNKNOWN */
114 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_TRAP_IDLE */
115 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_TRAP_BUSY */
118 GdkColor drawing_colors_bdev
[NUM_COLORS_BDEV
] =
119 { /* Pixel, R, G, B */
120 { 0, 0x0000, 0x0000, 0x0000 }, /* COL_BDEV_UNKNOWN */
121 { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_BDEV_IDLE */
122 { 0, 0x0000, 0x0000, 0xFFFF }, /* COL_BDEV_BUSY_READING */
123 { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_BDEV_BUSY_WRITING */
126 /*****************************************************************************
127 * drawing functions *
128 *****************************************************************************/
131 expose_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
);
134 motion_notify_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
);
137 /* Function responsible for updating the exposed area.
138 * It must do an events request to the lttvwindow API to ask for this update.
139 * Note : this function cannot clear the background, because it may
140 * erase drawing already present (SAFETY).
142 void drawing_data_request(Drawing_t
*drawing
,
147 if(width
< 0) return ;
148 if(height
< 0) return ;
151 Tab
*tab
= drawing
->control_flow_data
->tab
;
152 TimeWindow time_window
=
153 lttvwindow_get_time_window(tab
);
155 ControlFlowData
*control_flow_data
= drawing
->control_flow_data
;
156 // (ControlFlowData*)g_object_get_data(
157 // G_OBJECT(drawing->drawing_area), "resourceview_data");
159 LttTime start
, time_end
;
160 LttTime window_end
= time_window
.end_time
;
162 g_debug("req : window start_time : %lu, %lu", time_window
.start_time
.tv_sec
,
163 time_window
.start_time
.tv_nsec
);
165 g_debug("req : window time width : %lu, %lu", time_window
.time_width
.tv_sec
,
166 time_window
.time_width
.tv_nsec
);
168 g_debug("req : window_end : %lu, %lu", window_end
.tv_sec
,
171 g_debug("x is : %i, x+width is : %i", x
, x
+width
);
173 convert_pixels_to_time(drawing
->width
, x
,
177 convert_pixels_to_time(drawing
->width
, x
+width
,
180 time_end
= ltt_time_add(time_end
, ltt_time_one
); // because main window
181 // doesn't deliver end time.
183 lttvwindow_events_request_remove_all(tab
,
187 /* find the tracehooks */
188 LttvTracesetContext
*tsc
= lttvwindow_get_traceset_context(tab
);
190 LttvTraceset
*traceset
= tsc
->ts
;
192 guint i
, k
, l
, nb_trace
;
196 LttvTracefileState
*tfs
;
207 nb_trace
= lttv_traceset_number(traceset
);
208 // FIXME (fixed) : eventually request for more traces
209 for(i
= 0 ; i
< nb_trace
; i
++) {
210 EventsRequest
*events_request
= g_new(EventsRequest
, 1);
212 //LttvHooks *event = lttv_hooks_new();
213 LttvHooksById
*event_by_id
= lttv_hooks_by_id_new();
214 LttvHooks
*before_chunk_traceset
= lttv_hooks_new();
215 LttvHooks
*after_chunk_traceset
= lttv_hooks_new();
216 LttvHooks
*before_request_hook
= lttv_hooks_new();
217 LttvHooks
*after_request_hook
= lttv_hooks_new();
219 lttv_hooks_add(before_chunk_traceset
,
224 lttv_hooks_add(after_chunk_traceset
,
229 lttv_hooks_add(before_request_hook
,
234 lttv_hooks_add(after_request_hook
,
240 ts
= (LttvTraceState
*)tsc
->traces
[i
];
242 /* Find the eventtype id for the following events and register the
243 associated by id hooks. */
245 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 18);
249 // lttv_trace_find_hook(ts->parent.t,
250 // LTT_FACILITY_KERNEL_ARCH,
251 // LTT_EVENT_SYSCALL_ENTRY,
252 // FIELD_ARRAY(LTT_FIELD_SYSCALL_ID),
253 // before_execmode_hook,
257 // lttv_trace_find_hook(ts->parent.t,
258 // LTT_FACILITY_KERNEL_ARCH,
259 // LTT_EVENT_SYSCALL_EXIT,
261 // before_execmode_hook,
265 lttv_trace_find_hook(ts
->parent
.t
,
266 LTT_FACILITY_KERNEL_ARCH
,
267 LTT_EVENT_TRAP_ENTRY
,
268 FIELD_ARRAY(LTT_FIELD_TRAP_ID
),
269 before_execmode_hook
,
273 lttv_trace_find_hook(ts
->parent
.t
,
274 LTT_FACILITY_KERNEL_ARCH
,
277 before_execmode_hook
,
281 lttv_trace_find_hook(ts
->parent
.t
,
284 FIELD_ARRAY(LTT_FIELD_IRQ_ID
),
285 before_execmode_hook
,
289 lttv_trace_find_hook(ts
->parent
.t
,
293 before_execmode_hook
,
297 lttv_trace_find_hook(ts
->parent
.t
,
299 LTT_EVENT_SOFT_IRQ_RAISE
,
300 FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID
),
301 before_execmode_hook
,
305 lttv_trace_find_hook(ts
->parent
.t
,
307 LTT_EVENT_SOFT_IRQ_ENTRY
,
308 FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID
),
309 before_execmode_hook
,
313 lttv_trace_find_hook(ts
->parent
.t
,
315 LTT_EVENT_SOFT_IRQ_EXIT
,
317 before_execmode_hook
,
322 lttv_trace_find_hook(ts
->parent
.t
,
324 LTT_EVENT_SCHED_SCHEDULE
,
325 FIELD_ARRAY(LTT_FIELD_PREV_PID
, LTT_FIELD_NEXT_PID
, LTT_FIELD_PREV_STATE
),
326 before_schedchange_hook
,
330 // lttv_trace_find_hook(ts->parent.t,
331 // LTT_FACILITY_KERNEL,
332 // LTT_EVENT_PROCESS_EXIT,
333 // FIELD_ARRAY(LTT_FIELD_PID),
334 // before_process_exit_hook,
338 // lttv_trace_find_hook(ts->parent.t,
339 // LTT_FACILITY_KERNEL,
340 // LTT_EVENT_PROCESS_FREE,
341 // FIELD_ARRAY(LTT_FIELD_PID),
342 // before_process_release_hook,
346 // lttv_trace_find_hook(ts->parent.t,
347 // LTT_FACILITY_LIST,
348 // LTT_EVENT_STATEDUMP_END,
350 // before_statedump_end,
354 lttv_trace_find_hook(ts
->parent
.t
,
356 LTT_EVENT_REQUEST_ISSUE
,
357 FIELD_ARRAY(LTT_FIELD_MAJOR
, LTT_FIELD_MINOR
, LTT_FIELD_OPERATION
),
358 before_bdev_event_hook
,
362 lttv_trace_find_hook(ts
->parent
.t
,
364 LTT_EVENT_REQUEST_COMPLETE
,
365 FIELD_ARRAY(LTT_FIELD_MAJOR
, LTT_FIELD_MINOR
, LTT_FIELD_OPERATION
),
366 before_bdev_event_hook
,
371 first_after
= hooks
->len
;
373 lttv_trace_find_hook(ts
->parent
.t
,
375 LTT_EVENT_SCHED_SCHEDULE
,
376 FIELD_ARRAY(LTT_FIELD_PREV_PID
, LTT_FIELD_NEXT_PID
, LTT_FIELD_PREV_STATE
),
377 after_schedchange_hook
,
381 // lttv_trace_find_hook(ts->parent.t,
382 // LTT_FACILITY_KERNEL,
383 // LTT_EVENT_PROCESS_FORK,
384 // FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID),
385 // after_process_fork_hook,
389 // lttv_trace_find_hook(ts->parent.t,
390 // LTT_FACILITY_KERNEL,
391 // LTT_EVENT_PROCESS_EXIT,
392 // FIELD_ARRAY(LTT_FIELD_PID),
393 // after_process_exit_hook,
397 // lttv_trace_find_hook(ts->parent.t,
398 // LTT_FACILITY_KERNEL,
401 // after_fs_exec_hook,
405 // lttv_trace_find_hook(ts->parent.t,
406 // LTT_FACILITY_USER_GENERIC,
407 // LTT_EVENT_THREAD_BRAND,
408 // FIELD_ARRAY(LTT_FIELD_NAME),
409 // after_user_generic_thread_brand_hook,
413 // lttv_trace_find_hook(ts->parent.t,
414 // LTT_FACILITY_LIST,
415 // LTT_EVENT_PROCESS_STATE,
416 // FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME),
417 // after_event_enum_process_hook,
422 /* Add these hooks to each event_by_id hooks list */
424 for(k
= 0 ; k
< first_after
; k
++) {
425 th
= &g_array_index(hooks
, LttvTraceHook
, k
);
426 lttv_hooks_add(lttv_hooks_by_id_find(event_by_id
, th
->id
),
433 for(k
= first_after
; k
< hooks
->len
; k
++) {
434 th
= &g_array_index(hooks
, LttvTraceHook
, k
);
435 lttv_hooks_add(lttv_hooks_by_id_find(event_by_id
, th
->id
),
441 events_request
->hooks
= hooks
;
443 // Fill the events request
444 events_request
->owner
= control_flow_data
;
445 events_request
->viewer_data
= control_flow_data
;
446 events_request
->servicing
= FALSE
;
447 events_request
->start_time
= start
;
448 events_request
->start_position
= NULL
;
449 events_request
->stop_flag
= FALSE
;
450 events_request
->end_time
= time_end
;
451 events_request
->num_events
= G_MAXUINT
;
452 events_request
->end_position
= NULL
;
453 events_request
->trace
= i
; //fixed /* FIXME */
454 events_request
->before_chunk_traceset
= before_chunk_traceset
;
455 events_request
->before_chunk_trace
= NULL
;
456 events_request
->before_chunk_tracefile
= NULL
;
457 events_request
->event
= NULL
;
458 events_request
->event_by_id
= event_by_id
;
459 events_request
->after_chunk_tracefile
= NULL
;
460 events_request
->after_chunk_trace
= NULL
;
461 events_request
->after_chunk_traceset
= after_chunk_traceset
;
462 events_request
->before_request
= before_request_hook
;
463 events_request
->after_request
= after_request_hook
;
465 g_debug("req : start : %lu, %lu", start
.tv_sec
,
468 g_debug("req : end : %lu, %lu", time_end
.tv_sec
,
471 lttvwindow_events_request(tab
, events_request
);
478 static void set_last_start(gpointer key
, gpointer value
, gpointer user_data
)
480 //ResourceInfo *process_info = (ResourceInfo*)key;
481 HashedResourceData
*hashed_process_data
= (HashedResourceData
*)value
;
482 guint x
= (guint
)user_data
;
484 hashed_process_data
->x
.over
= x
;
485 hashed_process_data
->x
.over_used
= FALSE
;
486 hashed_process_data
->x
.over_marked
= FALSE
;
487 hashed_process_data
->x
.middle
= x
;
488 hashed_process_data
->x
.middle_used
= FALSE
;
489 hashed_process_data
->x
.middle_marked
= FALSE
;
490 hashed_process_data
->x
.under
= x
;
491 hashed_process_data
->x
.under_used
= FALSE
;
492 hashed_process_data
->x
.under_marked
= FALSE
;
493 hashed_process_data
->next_good_time
= ltt_time_zero
;
498 void drawing_data_request_begin(EventsRequest
*events_request
, LttvTracesetState
*tss
)
502 g_debug("Begin of data request");
503 ControlFlowData
*cfd
= events_request
->viewer_data
;
504 LttvTracesetContext
*tsc
= LTTV_TRACESET_CONTEXT(tss
);
505 TimeWindow time_window
=
506 lttvwindow_get_time_window(cfd
->tab
);
508 guint width
= cfd
->drawing
->width
;
511 cfd
->drawing
->last_start
= events_request
->start_time
;
513 convert_time_to_pixels(
515 events_request
->start_time
,
519 for(i
=0; i
<RV_RESOURCE_COUNT
; i
++) {
520 g_hash_table_foreach(cfd
->process_list
->restypes
[i
].hash_table
, set_last_start
,
526 void drawing_chunk_begin(EventsRequest
*events_request
, LttvTracesetState
*tss
)
528 g_debug("Begin of chunk");
529 ControlFlowData
*cfd
= events_request
->viewer_data
;
530 LttvTracesetContext
*tsc
= &tss
->parent
;
531 //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
533 LttvTraceset
*traceset
= tsc
->ts
;
534 guint nb_trace
= lttv_traceset_number(traceset
);
536 if(!cfd
->process_list
->current_hash_data
) {
537 cfd
->process_list
->current_hash_data
= g_new(HashedResourceData
**,nb_trace
);
538 for(i
= 0 ; i
< nb_trace
; i
++) {
539 guint num_cpu
= ltt_trace_get_num_cpu(tss
->parent
.traces
[i
]->t
);
540 cfd
->process_list
->current_hash_data
[i
] = g_new(HashedResourceData
*,num_cpu
);
541 memset(cfd
->process_list
->current_hash_data
[i
], 0,
542 sizeof(HashedResourceData
*)*num_cpu
);
545 //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
546 // events_request->end_time);
550 void drawing_request_expose(EventsRequest
*events_request
,
551 LttvTracesetState
*tss
,
557 ControlFlowData
*cfd
= events_request
->viewer_data
;
558 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)tss
;
559 Drawing_t
*drawing
= cfd
->drawing
;
561 TimeWindow time_window
=
562 lttvwindow_get_time_window(cfd
->tab
);
564 g_debug("request expose");
566 convert_time_to_pixels(
571 x
= drawing
->damage_begin
;
575 drawing
->damage_begin
= x
+width
;
578 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
580 width
, drawing
->drawing_area
->allocation
.height
);
582 /* Update directly when scrolling */
583 gdk_window_process_updates(drawing
->drawing_area
->window
,
591 /* Create a new backing pixmap of the appropriate size */
592 /* As the scaling will always change, it's of no use to copy old
595 * Only change the size if width changes. The height is specified and changed
596 * when process ID are added or removed from the process list.
599 configure_event( GtkWidget
*widget
, GdkEventConfigure
*event
,
602 Drawing_t
*drawing
= (Drawing_t
*)user_data
;
605 /* First, get the new time interval of the main window */
606 /* we assume (see documentation) that the main window
607 * has updated the time interval before this configure gets
610 //lttvwindow_get_time_window(drawing->control_flow_data->mw,
611 // &drawing->control_flow_data->time_window);
613 /* New pixmap, size of the configure event */
614 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
615 // widget->allocation.width + SAFETY,
616 // widget->allocation.height + SAFETY,
619 if(widget
->allocation
.width
!= drawing
->width
) {
620 g_debug("drawing configure event");
621 g_debug("New alloc draw size : %i by %i",widget
->allocation
.width
,
622 widget
->allocation
.height
);
624 drawing
->width
= widget
->allocation
.width
;
626 if(drawing
->alloc_width
< widget
->allocation
.width
) {
627 //if(drawing->pixmap)
628 // gdk_pixmap_unref(drawing->pixmap);
630 //drawing->pixmap = gdk_pixmap_new(widget->window,
631 // drawing->width + SAFETY + EXTRA_ALLOC,
632 // drawing->height + EXTRA_ALLOC,
634 drawing
->alloc_width
= drawing
->width
+ SAFETY
+ EXTRA_ALLOC
;
635 drawing
->alloc_height
= drawing
->height
+ EXTRA_ALLOC
;
636 update_pixmap_size(drawing
->control_flow_data
->process_list
,
637 drawing
->alloc_width
);
638 update_index_to_pixmap(drawing
->control_flow_data
->process_list
);
640 //drawing->height = widget->allocation.height;
642 //ProcessList_get_height
643 // (GuiControlFlow_get_process_list(drawing->control_flow_data)),
647 //gdk_draw_rectangle (drawing->pixmap,
648 // widget->style->black_gc,
651 // drawing->width+SAFETY,
654 //g_info("init data request");
657 /* Initial data request */
658 /* no, do initial data request in the expose event */
659 // Do not need to ask for data of 1 pixel : not synchronized with
660 // main window time at this moment.
661 //drawing_data_request(drawing, &drawing->pixmap, 0, 0,
662 // widget->allocation.width,
663 // widget->allocation.height);
665 //drawing->width = widget->allocation.width;
666 //drawing->height = widget->allocation.height;
668 drawing
->damage_begin
= 0;
669 drawing
->damage_end
= widget
->allocation
.width
;
671 if((widget
->allocation
.width
!= 1 &&
672 widget
->allocation
.height
!= 1)
673 && drawing
->damage_begin
< drawing
->damage_end
)
676 rectangle_pixmap (drawing
->control_flow_data
->process_list
,
677 drawing
->drawing_area
->style
->black_gc
,
680 drawing
->alloc_width
, // do not overlap
684 drawing_data_request(drawing
,
685 drawing
->damage_begin
,
687 drawing
->damage_end
- drawing
->damage_begin
,
695 /* Redraw the screen from the backing pixmap */
697 expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
699 Drawing_t
*drawing
= (Drawing_t
*)user_data
;
701 ControlFlowData
*control_flow_data
=
702 (ControlFlowData
*)g_object_get_data(
704 "resourceview_data");
706 if(unlikely(drawing
->gc
== NULL
)) {
707 drawing
->gc
= gdk_gc_new(drawing
->drawing_area
->window
);
708 gdk_gc_copy(drawing
->gc
, drawing
->drawing_area
->style
->black_gc
);
711 TimeWindow time_window
=
712 lttvwindow_get_time_window(control_flow_data
->tab
);
713 LttTime current_time
=
714 lttvwindow_get_current_time(control_flow_data
->tab
);
718 LttTime window_end
= time_window
.end_time
;
720 /* update the screen from the pixmap buffer */
722 gdk_draw_pixmap(widget
->window
,
723 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
725 event
->area
.x
, event
->area
.y
,
726 event
->area
.x
, event
->area
.y
,
727 event
->area
.width
, event
->area
.height
);
729 drawing
->height
= processlist_get_height(control_flow_data
->process_list
);
731 copy_pixmap_to_screen(control_flow_data
->process_list
,
733 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
734 event
->area
.x
, event
->area
.y
,
735 event
->area
.width
, event
->area
.height
);
737 copy_pixmap_to_screen(control_flow_data
->process_list
,
740 event
->area
.x
, event
->area
.y
,
741 event
->area
.width
, event
->area
.height
);
744 /* Erase the dotted lines left.. */
745 if(widget
->allocation
.height
> drawing
->height
)
747 gdk_draw_rectangle (widget
->window
,
748 drawing
->drawing_area
->style
->black_gc
,
750 event
->area
.x
, drawing
->height
,
751 event
->area
.width
, // do not overlap
752 widget
->allocation
.height
- drawing
->height
);
754 if(ltt_time_compare(time_window
.start_time
, current_time
) <= 0 &&
755 ltt_time_compare(window_end
, current_time
) >= 0)
757 /* Draw the dotted lines */
758 convert_time_to_pixels(
765 if(drawing
->dotted_gc
== NULL
) {
767 drawing
->dotted_gc
= gdk_gc_new(drawing
->drawing_area
->window
);
768 gdk_gc_copy(drawing
->dotted_gc
, widget
->style
->white_gc
);
770 gint8 dash_list
[] = { 1, 2 };
771 gdk_gc_set_line_attributes(drawing
->dotted_gc
,
773 GDK_LINE_ON_OFF_DASH
,
776 gdk_gc_set_dashes(drawing
->dotted_gc
,
782 gint height_tot
= MAX(widget
->allocation
.height
, drawing
->height
);
783 gdk_draw_line(widget
->window
,
786 cursor_x
, height_tot
);
792 after_expose_event( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
795 g_debug("AFTER EXPOSE");
804 tree_row_activated(GtkTreeModel
*treemodel
,
806 GtkTreeViewColumn
*arg2
,
809 ControlFlowData
*cfd
= (ControlFlowData
*)user_data
;
810 Drawing_t
*drawing
= cfd
->drawing
;
811 GtkTreeView
*treeview
= cfd
->process_list
->process_list_widget
;
815 path_indices
= gtk_tree_path_get_indices (arg1
);
817 height
= get_cell_height(cfd
->process_list
,
818 GTK_TREE_VIEW(treeview
));
819 drawing
->horizontal_sel
= height
* path_indices
[0];
820 g_critical("new hor sel : %i", drawing
->horizontal_sel
);
826 button_press_event( GtkWidget
*widget
, GdkEventButton
*event
, gpointer user_data
)
828 ControlFlowData
*control_flow_data
=
829 (ControlFlowData
*)g_object_get_data(
831 "resourceview_data");
832 Drawing_t
*drawing
= control_flow_data
->drawing
;
833 TimeWindow time_window
=
834 lttvwindow_get_time_window(control_flow_data
->tab
);
837 if(event
->button
== 1)
841 /* left mouse button click */
842 g_debug("x click is : %f", event
->x
);
844 convert_pixels_to_time(drawing
->width
, (guint
)event
->x
,
848 lttvwindow_report_current_time(control_flow_data
->tab
, time
);
856 scrollbar_size_allocate(GtkWidget
*widget
,
857 GtkAllocation
*allocation
,
860 Drawing_t
*drawing
= (Drawing_t
*)user_data
;
862 gtk_widget_set_size_request(drawing
->padding
, allocation
->width
, -1);
863 //gtk_widget_queue_resize(drawing->padding);
864 //gtk_widget_queue_resize(drawing->ruler);
865 gtk_container_check_resize(GTK_CONTAINER(drawing
->ruler_hbox
));
871 Drawing_t
*drawing_construct(ControlFlowData
*control_flow_data
)
873 Drawing_t
*drawing
= g_new(Drawing_t
, 1);
875 drawing
->control_flow_data
= control_flow_data
;
877 drawing
->vbox
= gtk_vbox_new(FALSE
, 1);
880 drawing
->ruler_hbox
= gtk_hbox_new(FALSE
, 1);
881 drawing
->ruler
= gtk_drawing_area_new ();
882 //gtk_widget_set_size_request(drawing->ruler, -1, 27);
884 drawing
->padding
= gtk_drawing_area_new ();
885 //gtk_widget_set_size_request(drawing->padding, -1, 27);
886 gtk_box_pack_start(GTK_BOX(drawing
->ruler_hbox
), drawing
->ruler
,
888 gtk_box_pack_end(GTK_BOX(drawing
->ruler_hbox
), drawing
->padding
,
893 drawing
->drawing_area
= gtk_drawing_area_new ();
897 drawing
->hbox
= gtk_hbox_new(FALSE
, 1);
898 drawing
->viewport
= gtk_viewport_new(NULL
, control_flow_data
->v_adjust
);
899 drawing
->scrollbar
= gtk_vscrollbar_new(control_flow_data
->v_adjust
);
900 gtk_box_pack_start(GTK_BOX(drawing
->hbox
), drawing
->viewport
,
902 gtk_box_pack_end(GTK_BOX(drawing
->hbox
), drawing
->scrollbar
,
905 //drawing->scrolled_window =
906 // gtk_scrolled_window_new (NULL,
907 // control_flow_data->v_adjust);
909 //gtk_scrolled_window_set_policy(
910 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
912 // GTK_POLICY_AUTOMATIC);
914 gtk_container_add(GTK_CONTAINER(drawing
->viewport
),
915 drawing
->drawing_area
);
916 //gtk_scrolled_window_add_with_viewport(
917 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
918 // drawing->drawing_area);
920 gtk_box_pack_start(GTK_BOX(drawing
->vbox
), drawing
->ruler_hbox
,
922 gtk_box_pack_end(GTK_BOX(drawing
->vbox
), drawing
->hbox
,
925 drawing
->pango_layout
=
926 gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
931 drawing
->alloc_height
= 1;
932 drawing
->alloc_width
= 1;
934 drawing
->damage_begin
= 0;
935 drawing
->damage_end
= 0;
936 drawing
->horizontal_sel
= -1;
938 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
939 g_object_set_data_full(
940 G_OBJECT(drawing
->drawing_area
),
943 (GDestroyNotify
)drawing_destroy
);
946 G_OBJECT(drawing
->ruler
),
951 //gtk_widget_modify_bg( drawing->drawing_area,
953 // &CF_Colors[BLACK]);
955 //gdk_window_get_geometry(drawing->drawing_area->window,
957 // &(drawing->width),
958 // &(drawing->height),
961 //drawing->pixmap = gdk_pixmap_new(
962 // drawing->drawing_area->window,
967 //drawing->pixmap = NULL;
969 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
970 // drawing->drawing_area->allocation.width,
971 // drawing->drawing_area->allocation.height,
974 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
976 G_CALLBACK (configure_event
),
979 g_signal_connect (G_OBJECT(drawing
->ruler
),
981 G_CALLBACK(expose_ruler
),
984 gtk_widget_add_events(drawing
->ruler
, GDK_POINTER_MOTION_MASK
);
986 g_signal_connect (G_OBJECT(drawing
->ruler
),
987 "motion-notify-event",
988 G_CALLBACK(motion_notify_ruler
),
992 g_signal_connect (G_OBJECT(drawing
->scrollbar
),
994 G_CALLBACK(scrollbar_size_allocate
),
999 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
1001 G_CALLBACK (expose_event
),
1004 g_signal_connect_after (G_OBJECT(drawing
->drawing_area
),
1006 G_CALLBACK (after_expose_event
),
1009 g_signal_connect (G_OBJECT(drawing
->drawing_area
),
1010 "button-press-event",
1011 G_CALLBACK (button_press_event
),
1015 gtk_widget_show(drawing
->ruler
);
1016 gtk_widget_show(drawing
->padding
);
1017 gtk_widget_show(drawing
->ruler_hbox
);
1019 gtk_widget_show(drawing
->drawing_area
);
1020 //gtk_widget_show(drawing->scrolled_window);
1021 gtk_widget_show(drawing
->viewport
);
1022 gtk_widget_show(drawing
->scrollbar
);
1023 gtk_widget_show(drawing
->hbox
);
1025 /* Allocate the colors */
1026 GdkColormap
* colormap
= gdk_colormap_get_system();
1027 gboolean success
[NUM_COLORS
];
1028 gdk_colormap_alloc_colors(colormap
, drawing_colors
, NUM_COLORS
, FALSE
,
1030 gdk_colormap_alloc_colors(colormap
, drawing_colors_cpu
, NUM_COLORS_CPU
, FALSE
,
1032 gdk_colormap_alloc_colors(colormap
, drawing_colors_irq
, NUM_COLORS_IRQ
, FALSE
,
1034 gdk_colormap_alloc_colors(colormap
, drawing_colors_soft_irq
, NUM_COLORS_SOFT_IRQ
, FALSE
,
1036 gdk_colormap_alloc_colors(colormap
, drawing_colors_trap
, NUM_COLORS_TRAP
, FALSE
,
1038 gdk_colormap_alloc_colors(colormap
, drawing_colors_bdev
, NUM_COLORS_BDEV
, FALSE
,
1042 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data
->tab
)->window
));
1043 drawing
->dotted_gc
=
1044 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data
->tab
)->window
));
1046 gdk_gc_copy(drawing
->gc
,
1047 main_window_get_widget(control_flow_data
->tab
)->style
->black_gc
);
1048 gdk_gc_copy(drawing
->dotted_gc
,
1049 main_window_get_widget(control_flow_data
->tab
)->style
->white_gc
);
1051 gint8 dash_list
[] = { 1, 2 };
1052 gdk_gc_set_line_attributes(drawing
->dotted_gc
,
1054 GDK_LINE_ON_OFF_DASH
,
1057 gdk_gc_set_dashes(drawing
->dotted_gc
,
1062 drawing
->ruler_gc_butt
=
1063 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data
->tab
)->window
));
1064 gdk_gc_copy(drawing
->ruler_gc_butt
,
1065 main_window_get_widget(control_flow_data
->tab
)->style
->black_gc
);
1066 drawing
->ruler_gc_round
=
1067 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data
->tab
)->window
));
1068 gdk_gc_copy(drawing
->ruler_gc_round
,
1069 main_window_get_widget(control_flow_data
->tab
)->style
->black_gc
);
1072 gdk_gc_set_line_attributes(drawing
->ruler_gc_butt
,
1078 gdk_gc_set_line_attributes(drawing
->ruler_gc_round
,
1088 void drawing_destroy(Drawing_t
*drawing
)
1090 g_info("drawing_destroy %p", drawing
);
1092 /* Free the colors */
1093 GdkColormap
* colormap
= gdk_colormap_get_system();
1095 gdk_colormap_free_colors(colormap
, drawing_colors
, NUM_COLORS
);
1096 gdk_colormap_free_colors(colormap
, drawing_colors_cpu
, NUM_COLORS_CPU
);
1097 gdk_colormap_free_colors(colormap
, drawing_colors_irq
, NUM_COLORS_IRQ
);
1098 gdk_colormap_free_colors(colormap
, drawing_colors_soft_irq
, NUM_COLORS_IRQ
);
1099 gdk_colormap_free_colors(colormap
, drawing_colors_trap
, NUM_COLORS_TRAP
);
1100 gdk_colormap_free_colors(colormap
, drawing_colors_bdev
, NUM_COLORS_BDEV
);
1102 // Do not unref here, Drawing_t destroyed by it's widget.
1103 //g_object_unref( G_OBJECT(drawing->drawing_area));
1104 if(drawing
->gc
!= NULL
)
1105 gdk_gc_unref(drawing
->gc
);
1107 g_object_unref(drawing
->pango_layout
);
1108 if(drawing
->dotted_gc
!= NULL
) gdk_gc_unref(drawing
->dotted_gc
);
1109 if(drawing
->ruler_gc_butt
!= NULL
) gdk_gc_unref(drawing
->ruler_gc_butt
);
1110 if(drawing
->ruler_gc_round
!= NULL
) gdk_gc_unref(drawing
->ruler_gc_round
);
1113 g_info("drawing_destroy end");
1116 GtkWidget
*drawing_get_drawing_area(Drawing_t
*drawing
)
1118 return drawing
->drawing_area
;
1121 GtkWidget
*drawing_get_widget(Drawing_t
*drawing
)
1123 return drawing
->vbox
;
1126 void drawing_draw_line( Drawing_t
*drawing
,
1132 gdk_draw_line (pixmap
,
1137 void drawing_clear(Drawing_t
*drawing
)
1139 //if (drawing->pixmap)
1140 // gdk_pixmap_unref(drawing->pixmap);
1141 ControlFlowData
*cfd
= drawing
->control_flow_data
;
1144 rectangle_pixmap(cfd
->process_list
,
1145 drawing
->drawing_area
->style
->black_gc
,
1148 drawing
->alloc_width
, // do not overlap
1151 //drawing->height = 1;
1152 /* Allocate a new pixmap with new height */
1153 //drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1154 // drawing->width + SAFETY + EXTRA_ALLOC,
1155 // drawing->height + EXTRA_ALLOC,
1157 //drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1158 //drawing->alloc_height = drawing->height + EXTRA_ALLOC;
1160 //gtk_widget_set_size_request(drawing->drawing_area,
1162 // drawing->height);
1163 //gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1165 /* ask for the buffer to be redrawn */
1166 gtk_widget_queue_draw ( drawing
->drawing_area
);
1170 /* Insert a square corresponding to a new process in the list */
1171 /* Applies to whole drawing->width */
1172 void drawing_insert_square(Drawing_t
*drawing
,
1176 //GdkRectangle update_rect;
1177 gboolean reallocate
= FALSE
;
1178 GdkPixmap
*new_pixmap
;
1180 /* Allocate a new pixmap with new height */
1181 if(drawing
->alloc_height
< drawing
->height
+ height
) {
1183 new_pixmap
= gdk_pixmap_new(drawing
->drawing_area
->window
,
1184 drawing
->width
+ SAFETY
+ EXTRA_ALLOC
,
1185 drawing
->height
+ height
+ EXTRA_ALLOC
,
1187 drawing
->alloc_width
= drawing
->width
+ SAFETY
+ EXTRA_ALLOC
;
1188 drawing
->alloc_height
= drawing
->height
+ height
+ EXTRA_ALLOC
;
1191 /* Copy the high region */
1192 gdk_draw_pixmap (new_pixmap
,
1193 drawing
->drawing_area
->style
->black_gc
,
1197 drawing
->width
+ SAFETY
, y
);
1200 new_pixmap
= drawing
->pixmap
;
1203 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1204 // drawing->width + SAFETY,
1205 // drawing->height + height,
1208 /* add an empty square */
1209 gdk_draw_rectangle (new_pixmap
,
1210 drawing
->drawing_area
->style
->black_gc
,
1213 drawing
->width
+ SAFETY
, // do not overlap
1216 /* copy the bottom of the region */
1217 gdk_draw_pixmap (new_pixmap
,
1218 drawing
->drawing_area
->style
->black_gc
,
1222 drawing
->width
+SAFETY
, drawing
->height
- y
);
1225 if(reallocate
&& likely(drawing
->pixmap
)) {
1226 gdk_pixmap_unref(drawing
->pixmap
);
1227 drawing
->pixmap
= new_pixmap
;
1230 if(unlikely(drawing
->height
==1)) drawing
->height
= height
;
1231 else drawing
->height
+= height
;
1233 gtk_widget_set_size_request(drawing
->drawing_area
,
1236 gtk_widget_queue_resize_no_redraw(drawing
->drawing_area
);
1238 /* ask for the buffer to be redrawn */
1239 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
1241 drawing
->width
, drawing
->height
-y
);
1245 /* Remove a square corresponding to a removed process in the list */
1246 void drawing_remove_square(Drawing_t
*drawing
,
1252 if(unlikely((guint
)drawing
->height
== height
)) {
1253 //pixmap = gdk_pixmap_new(
1254 // drawing->drawing_area->window,
1255 // drawing->width + SAFETY,
1258 pixmap
= drawing
->pixmap
;
1261 /* Allocate a new pixmap with new height */
1262 //pixmap = gdk_pixmap_new(
1263 // drawing->drawing_area->window,
1264 // drawing->width + SAFETY,
1265 // drawing->height - height,
1267 /* Keep the same preallocated pixmap */
1268 pixmap
= drawing
->pixmap
;
1270 /* Copy the high region */
1271 gdk_draw_pixmap (pixmap
,
1272 drawing
->drawing_area
->style
->black_gc
,
1276 drawing
->width
+ SAFETY
, y
);
1278 /* Copy up the bottom of the region */
1279 gdk_draw_pixmap (pixmap
,
1280 drawing
->drawing_area
->style
->black_gc
,
1284 drawing
->width
, drawing
->height
- y
- height
);
1286 drawing
->height
-=height
;
1289 //if(likely(drawing->pixmap))
1290 // gdk_pixmap_unref(drawing->pixmap);
1292 //drawing->pixmap = pixmap;
1294 gtk_widget_set_size_request(drawing
->drawing_area
,
1297 gtk_widget_queue_resize_no_redraw(drawing
->drawing_area
);
1298 /* ask for the buffer to be redrawn */
1299 gtk_widget_queue_draw_area ( drawing
->drawing_area
,
1301 drawing
->width
, MAX(drawing
->height
-y
, 1));
1305 void drawing_update_ruler(Drawing_t
*drawing
, TimeWindow
*time_window
)
1310 req
.width
= drawing
->ruler
->allocation
.width
;
1311 req
.height
= drawing
->ruler
->allocation
.height
;
1316 rect
.width
= req
.width
;
1317 rect
.height
= req
.height
;
1319 gtk_widget_queue_draw(drawing
->ruler
);
1320 //gtk_widget_draw( drawing->ruler, &rect);
1323 /* Redraw the ruler */
1325 expose_ruler( GtkWidget
*widget
, GdkEventExpose
*event
, gpointer user_data
)
1327 Drawing_t
*drawing
= (Drawing_t
*)user_data
;
1328 TimeWindow time_window
= lttvwindow_get_time_window(drawing
->control_flow_data
->tab
);
1331 PangoContext
*context
;
1332 PangoLayout
*layout
;
1333 PangoFontDescription
*FontDesc
;
1334 PangoRectangle ink_rect
;
1335 gint global_width
=0;
1336 GdkColor foreground
= { 0, 0, 0, 0 };
1337 GdkColor background
= { 0, 0xffff, 0xffff, 0xffff };
1339 LttTime window_end
= time_window
.end_time
;
1340 LttTime half_width
=
1341 ltt_time_div(time_window
.time_width
,2.0);
1342 LttTime window_middle
=
1343 ltt_time_add(half_width
,
1344 time_window
.start_time
);
1345 g_debug("ruler expose event");
1347 gdk_draw_rectangle (drawing
->ruler
->window
,
1348 drawing
->ruler
->style
->white_gc
,
1350 event
->area
.x
, event
->area
.y
,
1352 event
->area
.height
);
1354 gdk_draw_line (drawing
->ruler
->window
,
1355 drawing
->ruler_gc_butt
,
1357 event
->area
.x
+ event
->area
.width
, 1);
1360 snprintf(text
, 255, "%lus\n%luns",
1361 time_window
.start_time
.tv_sec
,
1362 time_window
.start_time
.tv_nsec
);
1364 layout
= gtk_widget_create_pango_layout(drawing
->drawing_area
, NULL
);
1366 context
= pango_layout_get_context(layout
);
1367 FontDesc
= pango_context_get_font_description(context
);
1369 pango_font_description_set_size(FontDesc
, 6*PANGO_SCALE
);
1370 pango_layout_context_changed(layout
);
1372 pango_layout_set_text(layout
, text
, -1);
1373 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1374 global_width
+= ink_rect
.width
;
1376 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1377 drawing
->ruler_gc_butt
,
1380 layout
, &foreground
, &background
);
1382 gdk_draw_line (drawing
->ruler
->window
,
1383 drawing
->ruler_gc_round
,
1388 snprintf(text
, 255, "%lus\n%luns", window_end
.tv_sec
,
1389 window_end
.tv_nsec
);
1391 pango_layout_set_text(layout
, text
, -1);
1392 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1393 global_width
+= ink_rect
.width
;
1395 if(global_width
<= drawing
->ruler
->allocation
.width
)
1397 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1398 drawing
->ruler_gc_butt
,
1399 drawing
->ruler
->allocation
.width
- ink_rect
.width
,
1401 layout
, &foreground
, &background
);
1403 gdk_draw_line (drawing
->ruler
->window
,
1404 drawing
->ruler_gc_butt
,
1405 drawing
->ruler
->allocation
.width
-1, 1,
1406 drawing
->ruler
->allocation
.width
-1, 7);
1410 snprintf(text
, 255, "%lus\n%luns", window_middle
.tv_sec
,
1411 window_middle
.tv_nsec
);
1413 pango_layout_set_text(layout
, text
, -1);
1414 pango_layout_get_pixel_extents(layout
, &ink_rect
, NULL
);
1415 global_width
+= ink_rect
.width
;
1417 if(global_width
<= drawing
->ruler
->allocation
.width
)
1419 gdk_draw_layout_with_colors(drawing
->ruler
->window
,
1420 drawing
->ruler_gc_butt
,
1421 (drawing
->ruler
->allocation
.width
- ink_rect
.width
)/2,
1423 layout
, &foreground
, &background
);
1425 gdk_draw_line (drawing
->ruler
->window
,
1426 drawing
->ruler_gc_butt
,
1427 drawing
->ruler
->allocation
.width
/2, 1,
1428 drawing
->ruler
->allocation
.width
/2, 7);
1435 g_object_unref(layout
);
1441 /* notify mouse on ruler */
1443 motion_notify_ruler(GtkWidget
*widget
, GdkEventMotion
*event
, gpointer user_data
)
1445 //g_debug("motion");
1446 //eventually follow mouse and show time here