update compat
[lttv.git] / tags / lttv-0.11.3-23102008 / lttv / modules / gui / resourceview / drawing.c
CommitLineData
13ab9fcb 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 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 "drawing.h"
36#include "eventhooks.h"
37#include "cfv.h"
38
39//#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
40
41//FIXME
42// fixed #define TRACE_NUMBER 0
43#define EXTRA_ALLOC 1024 // pixels
44
45
46#if 0 /* colors for two lines representation */
47GdkColor 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 */
62
63};
64#endif //0
65
66
67GdkColor 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 */
83
84};
85
86GdkColor 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 */
94};
95
96GdkColor 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 */
101};
102
103GdkColor 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 */
109};
110
111GdkColor 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 */
116};
117
118GdkColor 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 */
124};
125
126/*****************************************************************************
127 * drawing functions *
128 *****************************************************************************/
129
130static gboolean
131expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
132
133static gboolean
134motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
135
136
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).
141 */
142void drawing_data_request(Drawing_t *drawing,
143 gint x, gint y,
144 gint width,
145 gint height)
146{
147 if(width < 0) return ;
148 if(height < 0) return ;
149
150
151 Tab *tab = drawing->control_flow_data->tab;
152 TimeWindow time_window =
153 lttvwindow_get_time_window(tab);
154
155 ControlFlowData *control_flow_data = drawing->control_flow_data;
156 // (ControlFlowData*)g_object_get_data(
157 // G_OBJECT(drawing->drawing_area), "resourceview_data");
158
159 LttTime start, time_end;
160 LttTime window_end = time_window.end_time;
161
162 g_debug("req : window start_time : %lu, %lu", time_window.start_time.tv_sec,
163 time_window.start_time.tv_nsec);
164
165 g_debug("req : window time width : %lu, %lu", time_window.time_width.tv_sec,
166 time_window.time_width.tv_nsec);
167
168 g_debug("req : window_end : %lu, %lu", window_end.tv_sec,
169 window_end.tv_nsec);
170
171 g_debug("x is : %i, x+width is : %i", x, x+width);
172
173 convert_pixels_to_time(drawing->width, x,
174 time_window,
175 &start);
176
177 convert_pixels_to_time(drawing->width, x+width,
178 time_window,
179 &time_end);
180 time_end = ltt_time_add(time_end, ltt_time_one); // because main window
181 // doesn't deliver end time.
182
183 lttvwindow_events_request_remove_all(tab,
184 control_flow_data);
185
186 {
187 /* find the tracehooks */
188 LttvTracesetContext *tsc = lttvwindow_get_traceset_context(tab);
189
190 LttvTraceset *traceset = tsc->ts;
191
192 guint i, k, l, nb_trace;
193
194 LttvTraceState *ts;
195
196 LttvTracefileState *tfs;
197
198 GArray *hooks;
199
200 LttvTraceHook *hook;
201
202 LttvTraceHook *th;
203
204 guint ret;
205 guint first_after;
206
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);
211 // Create the hooks
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();
218
219 lttv_hooks_add(before_chunk_traceset,
220 before_chunk,
221 events_request,
222 LTTV_PRIO_DEFAULT);
223
224 lttv_hooks_add(after_chunk_traceset,
225 after_chunk,
226 events_request,
227 LTTV_PRIO_DEFAULT);
228
229 lttv_hooks_add(before_request_hook,
230 before_request,
231 events_request,
232 LTTV_PRIO_DEFAULT);
233
234 lttv_hooks_add(after_request_hook,
235 after_request,
236 events_request,
237 LTTV_PRIO_DEFAULT);
238
239
240 ts = (LttvTraceState *)tsc->traces[i];
241
242 /* Find the eventtype id for the following events and register the
243 associated by id hooks. */
244
245 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 18);
246
247 /* before hooks */
248
249// lttv_trace_find_hook(ts->parent.t,
250// LTT_FACILITY_ARCH,
251// LTT_EVENT_SYSCALL_ENTRY,
252// FIELD_ARRAY(LTT_FIELD_SYSCALL_ID),
253// before_execmode_hook,
254// events_request,
255// &hooks);
256//
257// lttv_trace_find_hook(ts->parent.t,
258// LTT_FACILITY_ARCH,
259// LTT_EVENT_SYSCALL_EXIT,
260// NULL,
261// before_execmode_hook,
262// events_request,
263// &hooks);
264//
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,
270 events_request,
271 &hooks);
272
273 lttv_trace_find_hook(ts->parent.t,
274 LTT_FACILITY_KERNEL_ARCH,
275 LTT_EVENT_TRAP_EXIT,
276 NULL,
277 before_execmode_hook,
278 events_request,
279 &hooks);
280
281 lttv_trace_find_hook(ts->parent.t,
282 LTT_FACILITY_KERNEL,
283 LTT_EVENT_IRQ_ENTRY,
284 FIELD_ARRAY(LTT_FIELD_IRQ_ID),
285 before_execmode_hook,
286 events_request,
287 &hooks);
288
289 lttv_trace_find_hook(ts->parent.t,
290 LTT_FACILITY_KERNEL,
291 LTT_EVENT_IRQ_EXIT,
292 NULL,
293 before_execmode_hook,
294 events_request,
295 &hooks);
296
297 lttv_trace_find_hook(ts->parent.t,
298 LTT_FACILITY_KERNEL,
299 LTT_EVENT_SOFT_IRQ_RAISE,
300 FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID),
301 before_execmode_hook,
302 events_request,
303 &hooks);
304
305 lttv_trace_find_hook(ts->parent.t,
306 LTT_FACILITY_KERNEL,
307 LTT_EVENT_SOFT_IRQ_ENTRY,
308 FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID),
309 before_execmode_hook,
310 events_request,
311 &hooks);
312
313 lttv_trace_find_hook(ts->parent.t,
314 LTT_FACILITY_KERNEL,
315 LTT_EVENT_SOFT_IRQ_EXIT,
316 NULL,
317 before_execmode_hook,
318 events_request,
319 &hooks);
320
321
322 lttv_trace_find_hook(ts->parent.t,
323 LTT_FACILITY_KERNEL,
324 LTT_EVENT_SCHED_SCHEDULE,
325 FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE),
326 before_schedchange_hook,
327 events_request,
328 &hooks);
329
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,
335// events_request,
336// &hooks);
337//
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,
343// events_request,
344// &hooks);
345//
346// lttv_trace_find_hook(ts->parent.t,
347// LTT_FACILITY_LIST,
348// LTT_EVENT_STATEDUMP_END,
349// NULL,
350// before_statedump_end,
351// events_request,
352// &hooks);
353
354 lttv_trace_find_hook(ts->parent.t,
355 LTT_FACILITY_KERNEL,
356 LTT_EVENT_REQUEST_ISSUE,
357 FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION),
358 before_bdev_event_hook,
359 events_request,
360 &hooks);
361
362 lttv_trace_find_hook(ts->parent.t,
363 LTT_FACILITY_KERNEL,
364 LTT_EVENT_REQUEST_COMPLETE,
365 FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION),
366 before_bdev_event_hook,
367 events_request,
368 &hooks);
369
370 /* After hooks */
371 first_after = hooks->len;
372
373 lttv_trace_find_hook(ts->parent.t,
374 LTT_FACILITY_KERNEL,
375 LTT_EVENT_SCHED_SCHEDULE,
376 FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE),
377 after_schedchange_hook,
378 events_request,
379 &hooks);
380
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,
386// events_request,
387// &hooks);
388//
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,
394// events_request,
395// &hooks);
396//
397// lttv_trace_find_hook(ts->parent.t,
398// LTT_FACILITY_KERNEL,
399// LTT_EVENT_EXEC,
400// NULL,
401// after_fs_exec_hook,
402// events_request,
403// &hooks);
404//
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,
410// events_request,
411// &hooks);
412//
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,
418// events_request,
419// &hooks);
420
421
422 /* Add these hooks to each event_by_id hooks list */
423 /* add before */
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),
427 th->h,
428 th,
429 LTTV_PRIO_STATE-5);
430 }
431
432 /* add after */
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),
436 th->h,
437 th,
438 LTTV_PRIO_STATE+5);
439 }
440
441 events_request->hooks = hooks;
442
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;
464
465 g_debug("req : start : %lu, %lu", start.tv_sec,
466 start.tv_nsec);
467
468 g_debug("req : end : %lu, %lu", time_end.tv_sec,
469 time_end.tv_nsec);
470
471 lttvwindow_events_request(tab, events_request);
472
473 }
474 }
475}
476
477
478static void set_last_start(gpointer key, gpointer value, gpointer user_data)
479{
480 //ResourceInfo *process_info = (ResourceInfo*)key;
481 HashedResourceData *hashed_process_data = (HashedResourceData*)value;
482 guint x = (guint)user_data;
483
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;
494
495 return;
496}
497
498void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss)
499{
500 int i;
501
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);
507
508 guint width = cfd->drawing->width;
509 guint x=0;
510
511 cfd->drawing->last_start = events_request->start_time;
512
513 convert_time_to_pixels(
514 time_window,
515 events_request->start_time,
516 width,
517 &x);
518
519 for(i=0; i<RV_RESOURCE_COUNT; i++) {
520 g_hash_table_foreach(cfd->process_list->restypes[i].hash_table, set_last_start,
521 (gpointer)x);
522 }
523
524}
525
526void drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss)
527{
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;
532 guint i;
533 LttvTraceset *traceset = tsc->ts;
534 guint nb_trace = lttv_traceset_number(traceset);
535
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);
543 }
544 }
545 //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
546 // events_request->end_time);
547}
548
549
550void drawing_request_expose(EventsRequest *events_request,
551 LttvTracesetState *tss,
552 LttTime end_time)
553{
554 gint x, width;
555 guint x_end;
556
557 ControlFlowData *cfd = events_request->viewer_data;
558 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
559 Drawing_t *drawing = cfd->drawing;
560
561 TimeWindow time_window =
562 lttvwindow_get_time_window(cfd->tab);
563
564 g_debug("request expose");
565
566 convert_time_to_pixels(
567 time_window,
568 end_time,
569 drawing->width,
570 &x_end);
571 x = drawing->damage_begin;
572
573 width = x_end - x;
574
575 drawing->damage_begin = x+width;
576
577 // FIXME ?
578 gtk_widget_queue_draw_area ( drawing->drawing_area,
579 x, 0,
580 width, drawing->drawing_area->allocation.height);
581
582 /* Update directly when scrolling */
583 gdk_window_process_updates(drawing->drawing_area->window,
584 TRUE);
585}
586
587
588/* Callbacks */
589
590
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
593 * pixmap.
594 *
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.
597 */
598static gboolean
599configure_event( GtkWidget *widget, GdkEventConfigure *event,
600 gpointer user_data)
601{
602 Drawing_t *drawing = (Drawing_t*)user_data;
603
604
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
608 * executed.
609 */
610 //lttvwindow_get_time_window(drawing->control_flow_data->mw,
611 // &drawing->control_flow_data->time_window);
612
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,
617 // -1);
618
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);
623
624 drawing->width = widget->allocation.width;
625
626 if(drawing->alloc_width < widget->allocation.width) {
627 //if(drawing->pixmap)
628 // gdk_pixmap_unref(drawing->pixmap);
629
630 //drawing->pixmap = gdk_pixmap_new(widget->window,
631 // drawing->width + SAFETY + EXTRA_ALLOC,
632 // drawing->height + EXTRA_ALLOC,
633 // -1);
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);
639 }
640 //drawing->height = widget->allocation.height;
641
642 //ProcessList_get_height
643 // (GuiControlFlow_get_process_list(drawing->control_flow_data)),
644
645
646 // Clear the image
647 //gdk_draw_rectangle (drawing->pixmap,
648 // widget->style->black_gc,
649 // TRUE,
650 // 0, 0,
651 // drawing->width+SAFETY,
652 // drawing->height);
653
654 //g_info("init data request");
655
656
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);
664
665 //drawing->width = widget->allocation.width;
666 //drawing->height = widget->allocation.height;
667
668 drawing->damage_begin = 0;
669 drawing->damage_end = widget->allocation.width;
670
671 if((widget->allocation.width != 1 &&
672 widget->allocation.height != 1)
673 && drawing->damage_begin < drawing->damage_end)
674 {
675
676 rectangle_pixmap (drawing->control_flow_data->process_list,
677 drawing->drawing_area->style->black_gc,
678 TRUE,
679 0, 0,
680 drawing->alloc_width, // do not overlap
681 -1);
682
683
684 drawing_data_request(drawing,
685 drawing->damage_begin,
686 0,
687 drawing->damage_end - drawing->damage_begin,
688 drawing->height);
689 }
690 }
691 return TRUE;
692}
693
694
695/* Redraw the screen from the backing pixmap */
696static gboolean
697expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
698{
699 Drawing_t *drawing = (Drawing_t*)user_data;
700
701 ControlFlowData *control_flow_data =
702 (ControlFlowData*)g_object_get_data(
703 G_OBJECT(widget),
704 "resourceview_data");
705#if 0
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);
709 }
710#endif //0
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);
715
716 guint cursor_x=0;
717
718 LttTime window_end = time_window.end_time;
719
720 /* update the screen from the pixmap buffer */
721#if 0
722 gdk_draw_pixmap(widget->window,
723 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
724 drawing->pixmap,
725 event->area.x, event->area.y,
726 event->area.x, event->area.y,
727 event->area.width, event->area.height);
728#endif //0
729 drawing->height = processlist_get_height(control_flow_data->process_list);
730#if 0
731 copy_pixmap_to_screen(control_flow_data->process_list,
732 widget->window,
733 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
734 event->area.x, event->area.y,
735 event->area.width, event->area.height);
736#endif //0
737 copy_pixmap_to_screen(control_flow_data->process_list,
738 widget->window,
739 drawing->gc,
740 event->area.x, event->area.y,
741 event->area.width, event->area.height);
742
743
744 /* Erase the dotted lines left.. */
745 if(widget->allocation.height > drawing->height)
746 {
747 gdk_draw_rectangle (widget->window,
748 drawing->drawing_area->style->black_gc,
749 TRUE,
750 event->area.x, drawing->height,
751 event->area.width, // do not overlap
752 widget->allocation.height - drawing->height);
753 }
754 if(ltt_time_compare(time_window.start_time, current_time) <= 0 &&
755 ltt_time_compare(window_end, current_time) >= 0)
756 {
757 /* Draw the dotted lines */
758 convert_time_to_pixels(
759 time_window,
760 current_time,
761 drawing->width,
762 &cursor_x);
763
764#if 0
765 if(drawing->dotted_gc == NULL) {
766
767 drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window);
768 gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc);
769
770 gint8 dash_list[] = { 1, 2 };
771 gdk_gc_set_line_attributes(drawing->dotted_gc,
772 1,
773 GDK_LINE_ON_OFF_DASH,
774 GDK_CAP_BUTT,
775 GDK_JOIN_MITER);
776 gdk_gc_set_dashes(drawing->dotted_gc,
777 0,
778 dash_list,
779 2);
780 }
781#endif //0
782 gint height_tot = MAX(widget->allocation.height, drawing->height);
783 gdk_draw_line(widget->window,
784 drawing->dotted_gc,
785 cursor_x, 0,
786 cursor_x, height_tot);
787 }
788 return FALSE;
789}
790
791static gboolean
792after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
793{
794 //g_assert(0);
795 g_debug("AFTER EXPOSE");
796
797 return FALSE;
798
799
800}
801
802#if 0
803void
804tree_row_activated(GtkTreeModel *treemodel,
805 GtkTreePath *arg1,
806 GtkTreeViewColumn *arg2,
807 gpointer user_data)
808{
809 ControlFlowData *cfd = (ControlFlowData*)user_data;
810 Drawing_t *drawing = cfd->drawing;
811 GtkTreeView *treeview = cfd->process_list->process_list_widget;
812 gint *path_indices;
813 gint height;
814
815 path_indices = gtk_tree_path_get_indices (arg1);
816
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);
821}
822#endif //0
823
824/* mouse click */
825static gboolean
826button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
827{
828 ControlFlowData *control_flow_data =
829 (ControlFlowData*)g_object_get_data(
830 G_OBJECT(widget),
831 "resourceview_data");
832 Drawing_t *drawing = control_flow_data->drawing;
833 TimeWindow time_window =
834 lttvwindow_get_time_window(control_flow_data->tab);
835
836 g_debug("click");
837 if(event->button == 1)
838 {
839 LttTime time;
840
841 /* left mouse button click */
842 g_debug("x click is : %f", event->x);
843
844 convert_pixels_to_time(drawing->width, (guint)event->x,
845 time_window,
846 &time);
847
848 lttvwindow_report_current_time(control_flow_data->tab, time);
849
850 }
851
852 return FALSE;
853}
854
855static gboolean
856scrollbar_size_allocate(GtkWidget *widget,
857 GtkAllocation *allocation,
858 gpointer user_data)
859{
860 Drawing_t *drawing = (Drawing_t*)user_data;
861
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));
866 return 0;
867}
868
869
870
871Drawing_t *drawing_construct(ControlFlowData *control_flow_data)
872{
873 Drawing_t *drawing = g_new(Drawing_t, 1);
874
875 drawing->control_flow_data = control_flow_data;
876
877 drawing->vbox = gtk_vbox_new(FALSE, 1);
878
879
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);
883
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,
887 TRUE, TRUE, 0);
888 gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->padding,
889 FALSE, FALSE, 0);
890
891
892
893 drawing->drawing_area = gtk_drawing_area_new ();
894
895 drawing->gc = NULL;
896
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,
901 TRUE, TRUE, 0);
902 gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar,
903 FALSE, FALSE, 0);
904
905 //drawing->scrolled_window =
906 // gtk_scrolled_window_new (NULL,
907 // control_flow_data->v_adjust);
908
909 //gtk_scrolled_window_set_policy(
910 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
911 // GTK_POLICY_NEVER,
912 // GTK_POLICY_AUTOMATIC);
913
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);
919
920 gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox,
921 FALSE, FALSE, 0);
922 gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->hbox,
923 TRUE, TRUE, 0);
924
925 drawing->pango_layout =
926 gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
927
928 drawing->height = 1;
929 drawing->width = 1;
930 drawing->depth = 0;
931 drawing->alloc_height = 1;
932 drawing->alloc_width = 1;
933
934 drawing->damage_begin = 0;
935 drawing->damage_end = 0;
936 drawing->horizontal_sel = -1;
937
938 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
939 g_object_set_data_full(
940 G_OBJECT(drawing->drawing_area),
941 "Link_drawing_Data",
942 drawing,
943 (GDestroyNotify)drawing_destroy);
944
945 g_object_set_data(
946 G_OBJECT(drawing->ruler),
947 "drawing",
948 drawing);
949
950
951 //gtk_widget_modify_bg( drawing->drawing_area,
952 // GTK_STATE_NORMAL,
953 // &CF_Colors[BLACK]);
954
955 //gdk_window_get_geometry(drawing->drawing_area->window,
956 // NULL, NULL,
957 // &(drawing->width),
958 // &(drawing->height),
959 // -1);
960
961 //drawing->pixmap = gdk_pixmap_new(
962 // drawing->drawing_area->window,
963 // drawing->width,
964 // drawing->height,
965 // drawing->depth);
966
967 //drawing->pixmap = NULL;
968
969// drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
970// drawing->drawing_area->allocation.width,
971// drawing->drawing_area->allocation.height,
972// -1);
973
974 g_signal_connect (G_OBJECT(drawing->drawing_area),
975 "configure_event",
976 G_CALLBACK (configure_event),
977 (gpointer)drawing);
978
979 g_signal_connect (G_OBJECT(drawing->ruler),
980 "expose_event",
981 G_CALLBACK(expose_ruler),
982 (gpointer)drawing);
983
984 gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK);
985
986 g_signal_connect (G_OBJECT(drawing->ruler),
987 "motion-notify-event",
988 G_CALLBACK(motion_notify_ruler),
989 (gpointer)drawing);
990
991
992 g_signal_connect (G_OBJECT(drawing->scrollbar),
993 "size-allocate",
994 G_CALLBACK(scrollbar_size_allocate),
995 (gpointer)drawing);
996
997
998
999 g_signal_connect (G_OBJECT(drawing->drawing_area),
1000 "expose_event",
1001 G_CALLBACK (expose_event),
1002 (gpointer)drawing);
1003
1004 g_signal_connect_after (G_OBJECT(drawing->drawing_area),
1005 "expose_event",
1006 G_CALLBACK (after_expose_event),
1007 (gpointer)drawing);
1008
1009 g_signal_connect (G_OBJECT(drawing->drawing_area),
1010 "button-press-event",
1011 G_CALLBACK (button_press_event),
1012 (gpointer)drawing);
1013
1014
1015 gtk_widget_show(drawing->ruler);
1016 gtk_widget_show(drawing->padding);
1017 gtk_widget_show(drawing->ruler_hbox);
1018
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);
1024
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,
1029 TRUE, success);
1030 gdk_colormap_alloc_colors(colormap, drawing_colors_cpu, NUM_COLORS_CPU, FALSE,
1031 TRUE, success);
1032 gdk_colormap_alloc_colors(colormap, drawing_colors_irq, NUM_COLORS_IRQ, FALSE,
1033 TRUE, success);
1034 gdk_colormap_alloc_colors(colormap, drawing_colors_soft_irq, NUM_COLORS_SOFT_IRQ, FALSE,
1035 TRUE, success);
1036 gdk_colormap_alloc_colors(colormap, drawing_colors_trap, NUM_COLORS_TRAP, FALSE,
1037 TRUE, success);
1038 gdk_colormap_alloc_colors(colormap, drawing_colors_bdev, NUM_COLORS_BDEV, FALSE,
1039 TRUE, success);
1040
1041 drawing->gc =
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));
1045
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);
1050
1051 gint8 dash_list[] = { 1, 2 };
1052 gdk_gc_set_line_attributes(drawing->dotted_gc,
1053 1,
1054 GDK_LINE_ON_OFF_DASH,
1055 GDK_CAP_BUTT,
1056 GDK_JOIN_MITER);
1057 gdk_gc_set_dashes(drawing->dotted_gc,
1058 0,
1059 dash_list,
1060 2);
1061
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);
1070
1071
1072 gdk_gc_set_line_attributes(drawing->ruler_gc_butt,
1073 2,
1074 GDK_LINE_SOLID,
1075 GDK_CAP_BUTT,
1076 GDK_JOIN_MITER);
1077
1078 gdk_gc_set_line_attributes(drawing->ruler_gc_round,
1079 2,
1080 GDK_LINE_SOLID,
1081 GDK_CAP_ROUND,
1082 GDK_JOIN_ROUND);
1083
1084
1085 return drawing;
1086}
1087
1088void drawing_destroy(Drawing_t *drawing)
1089{
1090 g_info("drawing_destroy %p", drawing);
1091
1092 /* Free the colors */
1093 GdkColormap* colormap = gdk_colormap_get_system();
1094
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);
1101
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);
1106
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);
1111
1112 g_free(drawing);
1113 g_info("drawing_destroy end");
1114}
1115
1116GtkWidget *drawing_get_drawing_area(Drawing_t *drawing)
1117{
1118 return drawing->drawing_area;
1119}
1120
1121GtkWidget *drawing_get_widget(Drawing_t *drawing)
1122{
1123 return drawing->vbox;
1124}
1125
1126void drawing_draw_line( Drawing_t *drawing,
1127 GdkPixmap *pixmap,
1128 guint x1, guint y1,
1129 guint x2, guint y2,
1130 GdkGC *GC)
1131{
1132 gdk_draw_line (pixmap,
1133 GC,
1134 x1, y1, x2, y2);
1135}
1136
1137void drawing_clear(Drawing_t *drawing)
1138{
1139 //if (drawing->pixmap)
1140 // gdk_pixmap_unref(drawing->pixmap);
1141 ControlFlowData *cfd = drawing->control_flow_data;
1142
1143
1144 rectangle_pixmap(cfd->process_list,
1145 drawing->drawing_area->style->black_gc,
1146 TRUE,
1147 0, 0,
1148 drawing->alloc_width, // do not overlap
1149 -1);
1150
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,
1156 // -1);
1157 //drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1158 //drawing->alloc_height = drawing->height + EXTRA_ALLOC;
1159
1160 //gtk_widget_set_size_request(drawing->drawing_area,
1161 // -1,
1162 // drawing->height);
1163 //gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1164
1165 /* ask for the buffer to be redrawn */
1166 gtk_widget_queue_draw ( drawing->drawing_area);
1167}
1168
1169#if 0
1170/* Insert a square corresponding to a new process in the list */
1171/* Applies to whole drawing->width */
1172void drawing_insert_square(Drawing_t *drawing,
1173 guint y,
1174 guint height)
1175{
1176 //GdkRectangle update_rect;
1177 gboolean reallocate = FALSE;
1178 GdkPixmap *new_pixmap;
1179
1180 /* Allocate a new pixmap with new height */
1181 if(drawing->alloc_height < drawing->height + height) {
1182
1183 new_pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1184 drawing->width + SAFETY + EXTRA_ALLOC,
1185 drawing->height + height + EXTRA_ALLOC,
1186 -1);
1187 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1188 drawing->alloc_height = drawing->height + height + EXTRA_ALLOC;
1189 reallocate = TRUE;
1190
1191 /* Copy the high region */
1192 gdk_draw_pixmap (new_pixmap,
1193 drawing->drawing_area->style->black_gc,
1194 drawing->pixmap,
1195 0, 0,
1196 0, 0,
1197 drawing->width + SAFETY, y);
1198
1199 } else {
1200 new_pixmap = drawing->pixmap;
1201 }
1202
1203 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1204 // drawing->width + SAFETY,
1205 // drawing->height + height,
1206 // -1);
1207
1208 /* add an empty square */
1209 gdk_draw_rectangle (new_pixmap,
1210 drawing->drawing_area->style->black_gc,
1211 TRUE,
1212 0, y,
1213 drawing->width + SAFETY, // do not overlap
1214 height);
1215
1216 /* copy the bottom of the region */
1217 gdk_draw_pixmap (new_pixmap,
1218 drawing->drawing_area->style->black_gc,
1219 drawing->pixmap,
1220 0, y,
1221 0, y + height,
1222 drawing->width+SAFETY, drawing->height - y);
1223
1224
1225 if(reallocate && likely(drawing->pixmap)) {
1226 gdk_pixmap_unref(drawing->pixmap);
1227 drawing->pixmap = new_pixmap;
1228 }
1229
1230 if(unlikely(drawing->height==1)) drawing->height = height;
1231 else drawing->height += height;
1232
1233 gtk_widget_set_size_request(drawing->drawing_area,
1234 -1,
1235 drawing->height);
1236 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1237
1238 /* ask for the buffer to be redrawn */
1239 gtk_widget_queue_draw_area ( drawing->drawing_area,
1240 0, y,
1241 drawing->width, drawing->height-y);
1242}
1243
1244
1245/* Remove a square corresponding to a removed process in the list */
1246void drawing_remove_square(Drawing_t *drawing,
1247 guint y,
1248 guint height)
1249{
1250 GdkPixmap *pixmap;
1251
1252 if(unlikely((guint)drawing->height == height)) {
1253 //pixmap = gdk_pixmap_new(
1254 // drawing->drawing_area->window,
1255 // drawing->width + SAFETY,
1256 // 1,
1257 // -1);
1258 pixmap = drawing->pixmap;
1259 drawing->height=1;
1260 } else {
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,
1266 // -1);
1267 /* Keep the same preallocated pixmap */
1268 pixmap = drawing->pixmap;
1269
1270 /* Copy the high region */
1271 gdk_draw_pixmap (pixmap,
1272 drawing->drawing_area->style->black_gc,
1273 drawing->pixmap,
1274 0, 0,
1275 0, 0,
1276 drawing->width + SAFETY, y);
1277
1278 /* Copy up the bottom of the region */
1279 gdk_draw_pixmap (pixmap,
1280 drawing->drawing_area->style->black_gc,
1281 drawing->pixmap,
1282 0, y + height,
1283 0, y,
1284 drawing->width, drawing->height - y - height);
1285
1286 drawing->height-=height;
1287 }
1288
1289 //if(likely(drawing->pixmap))
1290 // gdk_pixmap_unref(drawing->pixmap);
1291
1292 //drawing->pixmap = pixmap;
1293
1294 gtk_widget_set_size_request(drawing->drawing_area,
1295 -1,
1296 drawing->height);
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,
1300 0, y,
1301 drawing->width, MAX(drawing->height-y, 1));
1302}
1303#endif //0
1304
1305void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window)
1306{
1307 GtkRequisition req;
1308 GdkRectangle rect;
1309
1310 req.width = drawing->ruler->allocation.width;
1311 req.height = drawing->ruler->allocation.height;
1312
1313
1314 rect.x = 0;
1315 rect.y = 0;
1316 rect.width = req.width;
1317 rect.height = req.height;
1318
1319 gtk_widget_queue_draw(drawing->ruler);
1320 //gtk_widget_draw( drawing->ruler, &rect);
1321}
1322
1323/* Redraw the ruler */
1324static gboolean
1325expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
1326{
1327 Drawing_t *drawing = (Drawing_t*)user_data;
1328 TimeWindow time_window = lttvwindow_get_time_window(drawing->control_flow_data->tab);
1329 gchar text[255];
1330
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 };
1338
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");
1346
1347 gdk_draw_rectangle (drawing->ruler->window,
1348 drawing->ruler->style->white_gc,
1349 TRUE,
1350 event->area.x, event->area.y,
1351 event->area.width,
1352 event->area.height);
1353
1354 gdk_draw_line (drawing->ruler->window,
1355 drawing->ruler_gc_butt,
1356 event->area.x, 1,
1357 event->area.x + event->area.width, 1);
1358
1359
1360 snprintf(text, 255, "%lus\n%luns",
1361 time_window.start_time.tv_sec,
1362 time_window.start_time.tv_nsec);
1363
1364 layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
1365
1366 context = pango_layout_get_context(layout);
1367 FontDesc = pango_context_get_font_description(context);
1368
1369 pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
1370 pango_layout_context_changed(layout);
1371
1372 pango_layout_set_text(layout, text, -1);
1373 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1374 global_width += ink_rect.width;
1375
1376 gdk_draw_layout_with_colors(drawing->ruler->window,
1377 drawing->ruler_gc_butt,
1378 0,
1379 6,
1380 layout, &foreground, &background);
1381
1382 gdk_draw_line (drawing->ruler->window,
1383 drawing->ruler_gc_round,
1384 1, 1,
1385 1, 7);
1386
1387
1388 snprintf(text, 255, "%lus\n%luns", window_end.tv_sec,
1389 window_end.tv_nsec);
1390
1391 pango_layout_set_text(layout, text, -1);
1392 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1393 global_width += ink_rect.width;
1394
1395 if(global_width <= drawing->ruler->allocation.width)
1396 {
1397 gdk_draw_layout_with_colors(drawing->ruler->window,
1398 drawing->ruler_gc_butt,
1399 drawing->ruler->allocation.width - ink_rect.width,
1400 6,
1401 layout, &foreground, &background);
1402
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);
1407 }
1408
1409
1410 snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec,
1411 window_middle.tv_nsec);
1412
1413 pango_layout_set_text(layout, text, -1);
1414 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1415 global_width += ink_rect.width;
1416
1417 if(global_width <= drawing->ruler->allocation.width)
1418 {
1419 gdk_draw_layout_with_colors(drawing->ruler->window,
1420 drawing->ruler_gc_butt,
1421 (drawing->ruler->allocation.width - ink_rect.width)/2,
1422 6,
1423 layout, &foreground, &background);
1424
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);
1429
1430
1431
1432
1433 }
1434
1435 g_object_unref(layout);
1436
1437 return FALSE;
1438}
1439
1440
1441/* notify mouse on ruler */
1442static gboolean
1443motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
1444{
1445 //g_debug("motion");
1446 //eventually follow mouse and show time here
1447 return 0;
1448}
This page took 0.075004 seconds and 4 git commands to generate.