add softirq mode
[lttv.git] / ltt / branches / poly / lttv / modules / gui / controlflow / drawing.c
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 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
41
42 //FIXME
43 #define TRACE_NUMBER 0
44 #define EXTRA_ALLOC 1024 // pixels
45
46
47 #if 0 /* colors for two lines representation */
48 GdkColor drawing_colors[NUM_COLORS] =
49 { /* Pixel, R, G, B */
50 { 0, 0, 0, 0 }, /* COL_BLACK */
51 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
52 { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */
53 { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */
54 { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */
55 { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */
56 { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */
57 { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */
58 { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */
59 { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */
60 { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */
61 { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */
62 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_MODE_UNKNOWN : white */
63
64 };
65 #endif //0
66
67
68 GdkColor drawing_colors[NUM_COLORS] =
69 { /* Pixel, R, G, B */
70 { 0, 0, 0, 0 }, /* COL_BLACK */
71 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */
72 { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */
73 { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */
74 { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */
75 { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : orange */
76 { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_RUN_SOFT_IRQ : pink */
77 { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */
78 { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */
79 { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */
80 { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */
81 { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */
82 { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */
83 { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_UNNAMED : white */
84
85 };
86
87 /*
88 RUN+USER MODE green
89 RUN+SYSCALL
90 RUN+TRAP
91 RUN+IRQ
92 WAIT+foncé
93 WAIT CPU + WAIT FORK vert foncé ou jaune
94 IRQ rouge
95 TRAP: orange
96 SYSCALL: bleu pâle
97
98 ZOMBIE + WAIT EXIT
99 */
100
101
102 /*****************************************************************************
103 * drawing functions *
104 *****************************************************************************/
105
106 static gboolean
107 expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data );
108
109 static gboolean
110 motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
111
112
113 /* Function responsible for updating the exposed area.
114 * It must do an events request to the lttvwindow API to ask for this update.
115 * Note : this function cannot clear the background, because it may
116 * erase drawing already present (SAFETY).
117 */
118 void drawing_data_request(Drawing_t *drawing,
119 gint x, gint y,
120 gint width,
121 gint height)
122 {
123 if(width < 0) return ;
124 if(height < 0) return ;
125
126
127 Tab *tab = drawing->control_flow_data->tab;
128 TimeWindow time_window =
129 lttvwindow_get_time_window(tab);
130
131 ControlFlowData *control_flow_data = drawing->control_flow_data;
132 // (ControlFlowData*)g_object_get_data(
133 // G_OBJECT(drawing->drawing_area), "control_flow_data");
134
135 LttTime start, time_end;
136 LttTime window_end = time_window.end_time;
137
138 g_debug("req : window start_time : %lu, %lu", time_window.start_time.tv_sec,
139 time_window.start_time.tv_nsec);
140
141 g_debug("req : window time width : %lu, %lu", time_window.time_width.tv_sec,
142 time_window.time_width.tv_nsec);
143
144 g_debug("req : window_end : %lu, %lu", window_end.tv_sec,
145 window_end.tv_nsec);
146
147 g_debug("x is : %i, x+width is : %i", x, x+width);
148
149 convert_pixels_to_time(drawing->width, x,
150 time_window,
151 &start);
152
153 convert_pixels_to_time(drawing->width, x+width,
154 time_window,
155 &time_end);
156 time_end = ltt_time_add(time_end, ltt_time_one); // because main window
157 // doesn't deliver end time.
158
159 lttvwindow_events_request_remove_all(tab,
160 control_flow_data);
161
162 {
163 /* find the tracehooks */
164 LttvTracesetContext *tsc = lttvwindow_get_traceset_context(tab);
165
166 LttvTraceset *traceset = tsc->ts;
167
168 guint i, k, l, nb_trace;
169
170 LttvTraceState *ts;
171
172 LttvTracefileState *tfs;
173
174 GArray *hooks;
175
176 LttvTraceHook *hook;
177
178 LttvTraceHookByFacility *thf;
179
180 guint ret;
181
182 nb_trace = lttv_traceset_number(traceset);
183 // FIXME : eventually request for more traces
184 // for(i = 0 ; i < nb_trace ; i++) {
185 for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++)
186 {
187 EventsRequest *events_request = g_new(EventsRequest, 1);
188 // Create the hooks
189 //LttvHooks *event = lttv_hooks_new();
190 LttvHooksById *event_by_id = lttv_hooks_by_id_new();
191 LttvHooks *before_chunk_traceset = lttv_hooks_new();
192 LttvHooks *after_chunk_traceset = lttv_hooks_new();
193 LttvHooks *before_request_hook = lttv_hooks_new();
194 LttvHooks *after_request_hook = lttv_hooks_new();
195
196 lttv_hooks_add(before_chunk_traceset,
197 before_chunk,
198 events_request,
199 LTTV_PRIO_DEFAULT);
200
201 lttv_hooks_add(after_chunk_traceset,
202 after_chunk,
203 events_request,
204 LTTV_PRIO_DEFAULT);
205
206 lttv_hooks_add(before_request_hook,
207 before_request,
208 events_request,
209 LTTV_PRIO_DEFAULT);
210
211 lttv_hooks_add(after_request_hook,
212 after_request,
213 events_request,
214 LTTV_PRIO_DEFAULT);
215
216
217 ts = (LttvTraceState *)tsc->traces[i];
218
219 /* Find the eventtype id for the following events and register the
220 associated by id hooks. */
221
222 hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
223 hooks = g_array_set_size(hooks, 15);
224
225 /* before hooks */
226
227 ret = lttv_trace_find_hook(ts->parent.t,
228 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
229 LTT_FIELD_SYSCALL_ID, 0, 0,
230 before_execmode_hook,
231 events_request,
232 &g_array_index(hooks, LttvTraceHook, 0));
233 g_assert(!ret);
234
235 ret = lttv_trace_find_hook(ts->parent.t,
236 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
237 0, 0, 0,
238 before_execmode_hook,
239 events_request,
240 &g_array_index(hooks, LttvTraceHook, 1));
241 g_assert(!ret);
242
243 ret = lttv_trace_find_hook(ts->parent.t,
244 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
245 LTT_FIELD_TRAP_ID, 0, 0,
246 before_execmode_hook,
247 events_request,
248 &g_array_index(hooks, LttvTraceHook, 2));
249 g_assert(!ret);
250
251 ret = lttv_trace_find_hook(ts->parent.t,
252 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
253 0, 0, 0,
254 before_execmode_hook,
255 events_request,
256 &g_array_index(hooks, LttvTraceHook, 3));
257 g_assert(!ret);
258
259 ret = lttv_trace_find_hook(ts->parent.t,
260 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
261 LTT_FIELD_IRQ_ID, 0, 0,
262 before_execmode_hook,
263 events_request,
264 &g_array_index(hooks, LttvTraceHook, 4));
265 g_assert(!ret);
266
267 ret = lttv_trace_find_hook(ts->parent.t,
268 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
269 0, 0, 0,
270 before_execmode_hook,
271 events_request,
272 &g_array_index(hooks, LttvTraceHook, 5));
273 g_assert(!ret);
274
275 ret = lttv_trace_find_hook(ts->parent.t,
276 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
277 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
278 before_execmode_hook,
279 events_request,
280 &g_array_index(hooks, LttvTraceHook, 6));
281 g_assert(!ret);
282
283 ret = lttv_trace_find_hook(ts->parent.t,
284 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
285 0, 0, 0,
286 before_execmode_hook,
287 events_request,
288 &g_array_index(hooks, LttvTraceHook, 7));
289 g_assert(!ret);
290
291
292 ret = lttv_trace_find_hook(ts->parent.t,
293 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
294 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
295 before_schedchange_hook,
296 events_request,
297 &g_array_index(hooks, LttvTraceHook, 8));
298 g_assert(!ret);
299
300 ret = lttv_trace_find_hook(ts->parent.t,
301 LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
302 LTT_FIELD_PID, 0, 0,
303 before_process_exit_hook,
304 events_request,
305 &g_array_index(hooks, LttvTraceHook, 9));
306 g_assert(!ret);
307
308 ret = lttv_trace_find_hook(ts->parent.t,
309 LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
310 LTT_FIELD_PID, 0, 0,
311 before_process_release_hook,
312 events_request,
313 &g_array_index(hooks, LttvTraceHook, 10));
314 g_assert(!ret);
315
316
317 #if 0
318 lttv_trace_find_hook(ts->parent.t,
319 "core", "process", "event_sub_id",
320 "event_data1", "event_data2", before_process_hook,
321 &g_array_index(hooks, LttvTraceHook, 7));
322 #endif //0
323 #if 0
324 lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid",
325 NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
326
327 lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL,
328 NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
329 #endif //0
330
331 /* after hooks */
332
333 #if 0
334 /**** DESACTIVATED ****/
335 lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id",
336 NULL, NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 8));
337 /**** DESACTIVATED ****/
338 lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL,
339 NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 9));
340
341 /**** DESACTIVATED ****/
342 lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
343 NULL, NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 10));
344
345 /**** DESACTIVATED ****/
346 lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL,
347 after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 11));
348
349 /**** DESACTIVATED ****/
350 lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL,
351 NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 12));
352
353 /**** DESACTIVATED ****/
354 lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL,
355 after_execmode_hook, &g_array_index(hooks, LttvTraceHook, 13));
356 #endif //0
357 #if 0
358 lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out",
359 "out_state", after_schedchange_hook,
360 &g_array_index(hooks, LttvTraceHook, 8));
361
362 lttv_trace_find_hook(ts->parent.t, "core", "process", "event_sub_id",
363 "event_data1", "event_data2", after_process_hook,
364 &g_array_index(hooks, LttvTraceHook, 9));
365 #endif //0
366 ret = lttv_trace_find_hook(ts->parent.t,
367 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
368 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
369 after_schedchange_hook,
370 events_request,
371 &g_array_index(hooks, LttvTraceHook, 11));
372 g_assert(!ret);
373
374 ret = lttv_trace_find_hook(ts->parent.t,
375 LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
376 LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
377 after_process_fork_hook,
378 events_request,
379 &g_array_index(hooks, LttvTraceHook, 12));
380 g_assert(!ret);
381
382 ret = lttv_trace_find_hook(ts->parent.t,
383 LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
384 LTT_FIELD_PID, 0, 0,
385 after_process_exit_hook,
386 events_request,
387 &g_array_index(hooks, LttvTraceHook, 13));
388 g_assert(!ret);
389
390 ret = lttv_trace_find_hook(ts->parent.t,
391 LTT_FACILITY_FS, LTT_EVENT_EXEC,
392 0, 0, 0,
393 after_fs_exec_hook,
394 events_request,
395 &g_array_index(hooks, LttvTraceHook, 14));
396 g_assert(!ret);
397
398
399
400 #if 0
401 lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid",
402 NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
403
404 lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL,
405 NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
406 #endif //0
407
408
409
410 /* Add these hooks to each event_by_id hooks list */
411 /* add before */
412 for(k = 0 ; k < 11 ; k++) {
413 hook = &g_array_index(hooks, LttvTraceHook, k);
414 for(l=0;l<hook->fac_list->len;l++) {
415 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
416 lttv_hooks_add(lttv_hooks_by_id_find(event_by_id, thf->id),
417 thf->h,
418 thf,
419 LTTV_PRIO_STATE-5);
420 }
421 }
422
423 /* add after */
424 for(k = 11 ; k < 15 ; k++) {
425 hook = &g_array_index(hooks, LttvTraceHook, k);
426 for(l=0;l<hook->fac_list->len;l++) {
427 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
428 lttv_hooks_add(lttv_hooks_by_id_find(event_by_id, thf->id),
429 thf->h,
430 thf,
431 LTTV_PRIO_STATE+5);
432 }
433 }
434
435 events_request->hooks = hooks;
436
437 // Fill the events request
438 events_request->owner = control_flow_data;
439 events_request->viewer_data = control_flow_data;
440 events_request->servicing = FALSE;
441 events_request->start_time = start;
442 events_request->start_position = NULL;
443 events_request->stop_flag = FALSE;
444 events_request->end_time = time_end;
445 events_request->num_events = G_MAXUINT;
446 events_request->end_position = NULL;
447 events_request->trace = i; /* FIXME */
448 events_request->before_chunk_traceset = before_chunk_traceset;
449 events_request->before_chunk_trace = NULL;
450 events_request->before_chunk_tracefile = NULL;
451 events_request->event = NULL;
452 events_request->event_by_id = event_by_id;
453 events_request->after_chunk_tracefile = NULL;
454 events_request->after_chunk_trace = NULL;
455 events_request->after_chunk_traceset = after_chunk_traceset;
456 events_request->before_request = before_request_hook;
457 events_request->after_request = after_request_hook;
458
459 g_debug("req : start : %lu, %lu", start.tv_sec,
460 start.tv_nsec);
461
462 g_debug("req : end : %lu, %lu", time_end.tv_sec,
463 time_end.tv_nsec);
464
465 lttvwindow_events_request(tab, events_request);
466
467 }
468
469 }
470
471 #if 0
472 lttv_hooks_add(event,
473 before_schedchange_hook,
474 events_request,
475 LTTV_PRIO_STATE-5);
476 lttv_hooks_add(event,
477 after_schedchange_hook,
478 events_request,
479 LTTV_PRIO_STATE+5);
480 lttv_hooks_add(event,
481 before_execmode_hook,
482 events_request,
483 LTTV_PRIO_STATE-5);
484 lttv_hooks_add(event,
485 after_execmode_hook,
486 events_request,
487 LTTV_PRIO_STATE+5);
488 lttv_hooks_add(event,
489 before_process_hook,
490 events_request,
491 LTTV_PRIO_STATE-5);
492 lttv_hooks_add(event,
493 after_process_hook,
494 events_request,
495 LTTV_PRIO_STATE+5);
496 #endif //0
497
498 }
499
500
501 static void set_last_start(gpointer key, gpointer value, gpointer user_data)
502 {
503 ProcessInfo *process_info = (ProcessInfo*)key;
504 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
505 guint x = (guint)user_data;
506
507 hashed_process_data->x.over = x;
508 hashed_process_data->x.over_used = FALSE;
509 hashed_process_data->x.over_marked = FALSE;
510 hashed_process_data->x.middle = x;
511 hashed_process_data->x.middle_used = FALSE;
512 hashed_process_data->x.middle_marked = FALSE;
513 hashed_process_data->x.under = x;
514 hashed_process_data->x.under_used = FALSE;
515 hashed_process_data->x.under_marked = FALSE;
516 hashed_process_data->next_good_time = ltt_time_zero;
517
518 return;
519 }
520
521 void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss)
522 {
523 g_debug("Begin of data request");
524 ControlFlowData *cfd = events_request->viewer_data;
525 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
526 TimeWindow time_window =
527 lttvwindow_get_time_window(cfd->tab);
528
529 guint width = cfd->drawing->width;
530 guint x=0;
531
532 cfd->drawing->last_start = events_request->start_time;
533
534 convert_time_to_pixels(
535 time_window,
536 events_request->start_time,
537 width,
538 &x);
539
540 g_hash_table_foreach(cfd->process_list->process_hash, set_last_start,
541 (gpointer)x);
542
543 }
544
545 void drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss)
546 {
547 g_debug("Begin of chunk");
548 ControlFlowData *cfd = events_request->viewer_data;
549 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
550 //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
551 guint num_cpu =
552 ltt_trace_get_num_cpu(tss->parent.traces[TRACE_NUMBER]->t);
553
554 cfd->process_list->current_hash_data = g_new(HashedProcessData*,num_cpu);
555 memset(cfd->process_list->current_hash_data, 0,
556 sizeof(HashedProcessData*)*num_cpu);
557 //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
558 // events_request->end_time);
559 }
560
561
562 void drawing_request_expose(EventsRequest *events_request,
563 LttvTracesetState *tss,
564 LttTime end_time)
565 {
566 gint x, x_end, width;
567
568 ControlFlowData *cfd = events_request->viewer_data;
569 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
570 Drawing_t *drawing = cfd->drawing;
571
572 TimeWindow time_window =
573 lttvwindow_get_time_window(cfd->tab);
574
575 g_debug("request expose");
576
577 convert_time_to_pixels(
578 time_window,
579 end_time,
580 drawing->width,
581 &x_end);
582 x = drawing->damage_begin;
583
584 width = x_end - x;
585
586 drawing->damage_begin = x+width;
587
588 // FIXME ?
589 gtk_widget_queue_draw_area ( drawing->drawing_area,
590 x, 0,
591 width, drawing->drawing_area->allocation.height);
592
593 /* Update directly when scrolling */
594 gdk_window_process_updates(drawing->drawing_area->window,
595 TRUE);
596 }
597
598
599 /* Callbacks */
600
601
602 /* Create a new backing pixmap of the appropriate size */
603 /* As the scaling will always change, it's of no use to copy old
604 * pixmap.
605 *
606 * Only change the size if width changes. The height is specified and changed
607 * when process ID are added or removed from the process list.
608 */
609 static gboolean
610 configure_event( GtkWidget *widget, GdkEventConfigure *event,
611 gpointer user_data)
612 {
613 Drawing_t *drawing = (Drawing_t*)user_data;
614
615
616 /* First, get the new time interval of the main window */
617 /* we assume (see documentation) that the main window
618 * has updated the time interval before this configure gets
619 * executed.
620 */
621 //lttvwindow_get_time_window(drawing->control_flow_data->mw,
622 // &drawing->control_flow_data->time_window);
623
624 /* New pixmap, size of the configure event */
625 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
626 // widget->allocation.width + SAFETY,
627 // widget->allocation.height + SAFETY,
628 // -1);
629
630 if(widget->allocation.width != drawing->width) {
631 g_debug("drawing configure event");
632 g_debug("New alloc draw size : %i by %i",widget->allocation.width,
633 widget->allocation.height);
634
635 drawing->width = widget->allocation.width;
636
637 if(drawing->alloc_width < widget->allocation.width) {
638 //if(drawing->pixmap)
639 // gdk_pixmap_unref(drawing->pixmap);
640
641 //drawing->pixmap = gdk_pixmap_new(widget->window,
642 // drawing->width + SAFETY + EXTRA_ALLOC,
643 // drawing->height + EXTRA_ALLOC,
644 // -1);
645 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
646 drawing->alloc_height = drawing->height + EXTRA_ALLOC;
647 update_pixmap_size(drawing->control_flow_data->process_list,
648 drawing->alloc_width);
649 update_index_to_pixmap(drawing->control_flow_data->process_list);
650 }
651 //drawing->height = widget->allocation.height;
652
653 //ProcessList_get_height
654 // (GuiControlFlow_get_process_list(drawing->control_flow_data)),
655
656
657 // Clear the image
658 //gdk_draw_rectangle (drawing->pixmap,
659 // widget->style->black_gc,
660 // TRUE,
661 // 0, 0,
662 // drawing->width+SAFETY,
663 // drawing->height);
664
665 //g_info("init data request");
666
667
668 /* Initial data request */
669 /* no, do initial data request in the expose event */
670 // Do not need to ask for data of 1 pixel : not synchronized with
671 // main window time at this moment.
672 //drawing_data_request(drawing, &drawing->pixmap, 0, 0,
673 // widget->allocation.width,
674 // widget->allocation.height);
675
676 //drawing->width = widget->allocation.width;
677 //drawing->height = widget->allocation.height;
678
679 drawing->damage_begin = 0;
680 drawing->damage_end = widget->allocation.width;
681
682 if((widget->allocation.width != 1 &&
683 widget->allocation.height != 1)
684 && drawing->damage_begin < drawing->damage_end)
685 {
686
687 rectangle_pixmap (drawing->control_flow_data->process_list,
688 drawing->drawing_area->style->black_gc,
689 TRUE,
690 0, 0,
691 drawing->alloc_width, // do not overlap
692 -1);
693
694
695 drawing_data_request(drawing,
696 drawing->damage_begin,
697 0,
698 drawing->damage_end - drawing->damage_begin,
699 drawing->height);
700 }
701 }
702 return TRUE;
703 }
704
705
706 /* Redraw the screen from the backing pixmap */
707 static gboolean
708 expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
709 {
710 Drawing_t *drawing = (Drawing_t*)user_data;
711
712 ControlFlowData *control_flow_data =
713 (ControlFlowData*)g_object_get_data(
714 G_OBJECT(widget),
715 "control_flow_data");
716 #if 0
717 if(unlikely(drawing->gc == NULL)) {
718 drawing->gc = gdk_gc_new(drawing->drawing_area->window);
719 gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc);
720 }
721 #endif //0
722 TimeWindow time_window =
723 lttvwindow_get_time_window(control_flow_data->tab);
724 LttTime current_time =
725 lttvwindow_get_current_time(control_flow_data->tab);
726
727 guint cursor_x=0;
728
729 LttTime window_end = time_window.end_time;
730
731 /* update the screen from the pixmap buffer */
732 #if 0
733 gdk_draw_pixmap(widget->window,
734 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
735 drawing->pixmap,
736 event->area.x, event->area.y,
737 event->area.x, event->area.y,
738 event->area.width, event->area.height);
739 #endif //0
740 drawing->height = processlist_get_height(control_flow_data->process_list);
741 #if 0
742 copy_pixmap_to_screen(control_flow_data->process_list,
743 widget->window,
744 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
745 event->area.x, event->area.y,
746 event->area.width, event->area.height);
747 #endif //0
748 copy_pixmap_to_screen(control_flow_data->process_list,
749 widget->window,
750 drawing->gc,
751 event->area.x, event->area.y,
752 event->area.width, event->area.height);
753
754
755 /* Erase the dotted lines left.. */
756 if(widget->allocation.height > drawing->height)
757 {
758 gdk_draw_rectangle (widget->window,
759 drawing->drawing_area->style->black_gc,
760 TRUE,
761 event->area.x, drawing->height,
762 event->area.width, // do not overlap
763 widget->allocation.height - drawing->height);
764 }
765 if(ltt_time_compare(time_window.start_time, current_time) <= 0 &&
766 ltt_time_compare(window_end, current_time) >= 0)
767 {
768 /* Draw the dotted lines */
769 convert_time_to_pixels(
770 time_window,
771 current_time,
772 drawing->width,
773 &cursor_x);
774
775 #if 0
776 if(drawing->dotted_gc == NULL) {
777
778 drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window);
779 gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc);
780
781 gint8 dash_list[] = { 1, 2 };
782 gdk_gc_set_line_attributes(drawing->dotted_gc,
783 1,
784 GDK_LINE_ON_OFF_DASH,
785 GDK_CAP_BUTT,
786 GDK_JOIN_MITER);
787 gdk_gc_set_dashes(drawing->dotted_gc,
788 0,
789 dash_list,
790 2);
791 }
792 #endif //0
793 gint height_tot = MAX(widget->allocation.height, drawing->height);
794 gdk_draw_line(widget->window,
795 drawing->dotted_gc,
796 cursor_x, 0,
797 cursor_x, height_tot);
798 }
799 return FALSE;
800 }
801
802 static gboolean
803 after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
804 {
805 //g_assert(0);
806 g_debug("AFTER EXPOSE");
807
808 return FALSE;
809
810
811 }
812
813 #if 0
814 void
815 tree_row_activated(GtkTreeModel *treemodel,
816 GtkTreePath *arg1,
817 GtkTreeViewColumn *arg2,
818 gpointer user_data)
819 {
820 ControlFlowData *cfd = (ControlFlowData*)user_data;
821 Drawing_t *drawing = cfd->drawing;
822 GtkTreeView *treeview = cfd->process_list->process_list_widget;
823 gint *path_indices;
824 gint height;
825
826 path_indices = gtk_tree_path_get_indices (arg1);
827
828 height = get_cell_height(cfd->process_list,
829 GTK_TREE_VIEW(treeview));
830 drawing->horizontal_sel = height * path_indices[0];
831 g_critical("new hor sel : %i", drawing->horizontal_sel);
832 }
833 #endif //0
834
835 /* mouse click */
836 static gboolean
837 button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
838 {
839 ControlFlowData *control_flow_data =
840 (ControlFlowData*)g_object_get_data(
841 G_OBJECT(widget),
842 "control_flow_data");
843 Drawing_t *drawing = control_flow_data->drawing;
844 TimeWindow time_window =
845 lttvwindow_get_time_window(control_flow_data->tab);
846
847 g_debug("click");
848 if(event->button == 1)
849 {
850 LttTime time;
851
852 /* left mouse button click */
853 g_debug("x click is : %f", event->x);
854
855 convert_pixels_to_time(drawing->width, (guint)event->x,
856 time_window,
857 &time);
858
859 lttvwindow_report_current_time(control_flow_data->tab, time);
860
861 }
862
863 return FALSE;
864 }
865
866 static gboolean
867 scrollbar_size_allocate(GtkWidget *widget,
868 GtkAllocation *allocation,
869 gpointer user_data)
870 {
871 Drawing_t *drawing = (Drawing_t*)user_data;
872
873 gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
874 //gtk_widget_queue_resize(drawing->padding);
875 //gtk_widget_queue_resize(drawing->ruler);
876 gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
877 return 0;
878 }
879
880
881
882 Drawing_t *drawing_construct(ControlFlowData *control_flow_data)
883 {
884 Drawing_t *drawing = g_new(Drawing_t, 1);
885
886 drawing->control_flow_data = control_flow_data;
887
888 drawing->vbox = gtk_vbox_new(FALSE, 1);
889
890
891 drawing->ruler_hbox = gtk_hbox_new(FALSE, 1);
892 drawing->ruler = gtk_drawing_area_new ();
893 //gtk_widget_set_size_request(drawing->ruler, -1, 27);
894
895 drawing->padding = gtk_drawing_area_new ();
896 //gtk_widget_set_size_request(drawing->padding, -1, 27);
897 gtk_box_pack_start(GTK_BOX(drawing->ruler_hbox), drawing->ruler,
898 TRUE, TRUE, 0);
899 gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->padding,
900 FALSE, FALSE, 0);
901
902
903
904 drawing->drawing_area = gtk_drawing_area_new ();
905
906 drawing->gc = NULL;
907
908 drawing->hbox = gtk_hbox_new(FALSE, 1);
909 drawing->viewport = gtk_viewport_new(NULL, control_flow_data->v_adjust);
910 drawing->scrollbar = gtk_vscrollbar_new(control_flow_data->v_adjust);
911 gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport,
912 TRUE, TRUE, 0);
913 gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar,
914 FALSE, FALSE, 0);
915
916 //drawing->scrolled_window =
917 // gtk_scrolled_window_new (NULL,
918 // control_flow_data->v_adjust);
919
920 //gtk_scrolled_window_set_policy(
921 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
922 // GTK_POLICY_NEVER,
923 // GTK_POLICY_AUTOMATIC);
924
925 gtk_container_add(GTK_CONTAINER(drawing->viewport),
926 drawing->drawing_area);
927 //gtk_scrolled_window_add_with_viewport(
928 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
929 // drawing->drawing_area);
930
931 gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox,
932 FALSE, FALSE, 0);
933 gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->hbox,
934 TRUE, TRUE, 0);
935
936 drawing->pango_layout =
937 gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
938
939 drawing->height = 1;
940 drawing->width = 1;
941 drawing->depth = 0;
942 drawing->alloc_height = 1;
943 drawing->alloc_width = 1;
944
945 drawing->damage_begin = 0;
946 drawing->damage_end = 0;
947 drawing->horizontal_sel = -1;
948
949 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
950 g_object_set_data_full(
951 G_OBJECT(drawing->drawing_area),
952 "Link_drawing_Data",
953 drawing,
954 (GDestroyNotify)drawing_destroy);
955
956 g_object_set_data(
957 G_OBJECT(drawing->ruler),
958 "drawing",
959 drawing);
960
961
962 //gtk_widget_modify_bg( drawing->drawing_area,
963 // GTK_STATE_NORMAL,
964 // &CF_Colors[BLACK]);
965
966 //gdk_window_get_geometry(drawing->drawing_area->window,
967 // NULL, NULL,
968 // &(drawing->width),
969 // &(drawing->height),
970 // -1);
971
972 //drawing->pixmap = gdk_pixmap_new(
973 // drawing->drawing_area->window,
974 // drawing->width,
975 // drawing->height,
976 // drawing->depth);
977
978 //drawing->pixmap = NULL;
979
980 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
981 // drawing->drawing_area->allocation.width,
982 // drawing->drawing_area->allocation.height,
983 // -1);
984
985 g_signal_connect (G_OBJECT(drawing->drawing_area),
986 "configure_event",
987 G_CALLBACK (configure_event),
988 (gpointer)drawing);
989
990 g_signal_connect (G_OBJECT(drawing->ruler),
991 "expose_event",
992 G_CALLBACK(expose_ruler),
993 (gpointer)drawing);
994
995 gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK);
996
997 g_signal_connect (G_OBJECT(drawing->ruler),
998 "motion-notify-event",
999 G_CALLBACK(motion_notify_ruler),
1000 (gpointer)drawing);
1001
1002
1003 g_signal_connect (G_OBJECT(drawing->scrollbar),
1004 "size-allocate",
1005 G_CALLBACK(scrollbar_size_allocate),
1006 (gpointer)drawing);
1007
1008
1009
1010 g_signal_connect (G_OBJECT(drawing->drawing_area),
1011 "expose_event",
1012 G_CALLBACK (expose_event),
1013 (gpointer)drawing);
1014
1015 g_signal_connect_after (G_OBJECT(drawing->drawing_area),
1016 "expose_event",
1017 G_CALLBACK (after_expose_event),
1018 (gpointer)drawing);
1019
1020 g_signal_connect (G_OBJECT(drawing->drawing_area),
1021 "button-press-event",
1022 G_CALLBACK (button_press_event),
1023 (gpointer)drawing);
1024
1025 gtk_widget_show(drawing->ruler);
1026 gtk_widget_show(drawing->padding);
1027 gtk_widget_show(drawing->ruler_hbox);
1028
1029 gtk_widget_show(drawing->drawing_area);
1030 //gtk_widget_show(drawing->scrolled_window);
1031 gtk_widget_show(drawing->viewport);
1032 gtk_widget_show(drawing->scrollbar);
1033 gtk_widget_show(drawing->hbox);
1034
1035 /* Allocate the colors */
1036 GdkColormap* colormap = gdk_colormap_get_system();
1037 gboolean success[NUM_COLORS];
1038 gdk_colormap_alloc_colors(colormap, drawing_colors, NUM_COLORS, 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
1088 void 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
1097
1098
1099 // Do not unref here, Drawing_t destroyed by it's widget.
1100 //g_object_unref( G_OBJECT(drawing->drawing_area));
1101 if(drawing->gc != NULL)
1102 gdk_gc_unref(drawing->gc);
1103
1104 g_free(drawing->pango_layout);
1105 if(drawing->dotted_gc != NULL) gdk_gc_unref(drawing->dotted_gc);
1106 if(drawing->ruler_gc_butt != NULL) gdk_gc_unref(drawing->ruler_gc_butt);
1107 if(drawing->ruler_gc_round != NULL) gdk_gc_unref(drawing->ruler_gc_round);
1108
1109 g_free(drawing);
1110 g_info("drawing_destroy end");
1111 }
1112
1113 GtkWidget *drawing_get_drawing_area(Drawing_t *drawing)
1114 {
1115 return drawing->drawing_area;
1116 }
1117
1118 GtkWidget *drawing_get_widget(Drawing_t *drawing)
1119 {
1120 return drawing->vbox;
1121 }
1122
1123 void drawing_draw_line( Drawing_t *drawing,
1124 GdkPixmap *pixmap,
1125 guint x1, guint y1,
1126 guint x2, guint y2,
1127 GdkGC *GC)
1128 {
1129 gdk_draw_line (pixmap,
1130 GC,
1131 x1, y1, x2, y2);
1132 }
1133
1134 void drawing_clear(Drawing_t *drawing)
1135 {
1136 //if (drawing->pixmap)
1137 // gdk_pixmap_unref(drawing->pixmap);
1138 ControlFlowData *cfd = drawing->control_flow_data;
1139
1140
1141 rectangle_pixmap(cfd->process_list,
1142 drawing->drawing_area->style->black_gc,
1143 TRUE,
1144 0, 0,
1145 drawing->alloc_width, // do not overlap
1146 -1);
1147
1148 //drawing->height = 1;
1149 /* Allocate a new pixmap with new height */
1150 //drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1151 // drawing->width + SAFETY + EXTRA_ALLOC,
1152 // drawing->height + EXTRA_ALLOC,
1153 // -1);
1154 //drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1155 //drawing->alloc_height = drawing->height + EXTRA_ALLOC;
1156
1157 //gtk_widget_set_size_request(drawing->drawing_area,
1158 // -1,
1159 // drawing->height);
1160 //gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1161
1162 /* ask for the buffer to be redrawn */
1163 gtk_widget_queue_draw ( drawing->drawing_area);
1164 }
1165
1166 #if 0
1167 /* Insert a square corresponding to a new process in the list */
1168 /* Applies to whole drawing->width */
1169 void drawing_insert_square(Drawing_t *drawing,
1170 guint y,
1171 guint height)
1172 {
1173 //GdkRectangle update_rect;
1174 gboolean reallocate = FALSE;
1175 GdkPixmap *new_pixmap;
1176
1177 /* Allocate a new pixmap with new height */
1178 if(drawing->alloc_height < drawing->height + height) {
1179
1180 new_pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1181 drawing->width + SAFETY + EXTRA_ALLOC,
1182 drawing->height + height + EXTRA_ALLOC,
1183 -1);
1184 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1185 drawing->alloc_height = drawing->height + height + EXTRA_ALLOC;
1186 reallocate = TRUE;
1187
1188 /* Copy the high region */
1189 gdk_draw_pixmap (new_pixmap,
1190 drawing->drawing_area->style->black_gc,
1191 drawing->pixmap,
1192 0, 0,
1193 0, 0,
1194 drawing->width + SAFETY, y);
1195
1196 } else {
1197 new_pixmap = drawing->pixmap;
1198 }
1199
1200 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1201 // drawing->width + SAFETY,
1202 // drawing->height + height,
1203 // -1);
1204
1205 /* add an empty square */
1206 gdk_draw_rectangle (new_pixmap,
1207 drawing->drawing_area->style->black_gc,
1208 TRUE,
1209 0, y,
1210 drawing->width + SAFETY, // do not overlap
1211 height);
1212
1213 /* copy the bottom of the region */
1214 gdk_draw_pixmap (new_pixmap,
1215 drawing->drawing_area->style->black_gc,
1216 drawing->pixmap,
1217 0, y,
1218 0, y + height,
1219 drawing->width+SAFETY, drawing->height - y);
1220
1221
1222 if(reallocate && likely(drawing->pixmap)) {
1223 gdk_pixmap_unref(drawing->pixmap);
1224 drawing->pixmap = new_pixmap;
1225 }
1226
1227 if(unlikely(drawing->height==1)) drawing->height = height;
1228 else drawing->height += height;
1229
1230 gtk_widget_set_size_request(drawing->drawing_area,
1231 -1,
1232 drawing->height);
1233 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1234
1235 /* ask for the buffer to be redrawn */
1236 gtk_widget_queue_draw_area ( drawing->drawing_area,
1237 0, y,
1238 drawing->width, drawing->height-y);
1239 }
1240
1241
1242 /* Remove a square corresponding to a removed process in the list */
1243 void drawing_remove_square(Drawing_t *drawing,
1244 guint y,
1245 guint height)
1246 {
1247 GdkPixmap *pixmap;
1248
1249 if(unlikely((guint)drawing->height == height)) {
1250 //pixmap = gdk_pixmap_new(
1251 // drawing->drawing_area->window,
1252 // drawing->width + SAFETY,
1253 // 1,
1254 // -1);
1255 pixmap = drawing->pixmap;
1256 drawing->height=1;
1257 } else {
1258 /* Allocate a new pixmap with new height */
1259 //pixmap = gdk_pixmap_new(
1260 // drawing->drawing_area->window,
1261 // drawing->width + SAFETY,
1262 // drawing->height - height,
1263 // -1);
1264 /* Keep the same preallocated pixmap */
1265 pixmap = drawing->pixmap;
1266
1267 /* Copy the high region */
1268 gdk_draw_pixmap (pixmap,
1269 drawing->drawing_area->style->black_gc,
1270 drawing->pixmap,
1271 0, 0,
1272 0, 0,
1273 drawing->width + SAFETY, y);
1274
1275 /* Copy up the bottom of the region */
1276 gdk_draw_pixmap (pixmap,
1277 drawing->drawing_area->style->black_gc,
1278 drawing->pixmap,
1279 0, y + height,
1280 0, y,
1281 drawing->width, drawing->height - y - height);
1282
1283 drawing->height-=height;
1284 }
1285
1286 //if(likely(drawing->pixmap))
1287 // gdk_pixmap_unref(drawing->pixmap);
1288
1289 //drawing->pixmap = pixmap;
1290
1291 gtk_widget_set_size_request(drawing->drawing_area,
1292 -1,
1293 drawing->height);
1294 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1295 /* ask for the buffer to be redrawn */
1296 gtk_widget_queue_draw_area ( drawing->drawing_area,
1297 0, y,
1298 drawing->width, MAX(drawing->height-y, 1));
1299 }
1300 #endif //0
1301
1302 void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window)
1303 {
1304 GtkRequisition req;
1305 GdkRectangle rect;
1306
1307 req.width = drawing->ruler->allocation.width;
1308 req.height = drawing->ruler->allocation.height;
1309
1310
1311 rect.x = 0;
1312 rect.y = 0;
1313 rect.width = req.width;
1314 rect.height = req.height;
1315
1316 gtk_widget_queue_draw(drawing->ruler);
1317 //gtk_widget_draw( drawing->ruler, &rect);
1318 }
1319
1320 /* Redraw the ruler */
1321 static gboolean
1322 expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
1323 {
1324 Drawing_t *drawing = (Drawing_t*)user_data;
1325 TimeWindow time_window = lttvwindow_get_time_window(drawing->control_flow_data->tab);
1326 gchar text[255];
1327
1328 PangoContext *context;
1329 PangoLayout *layout;
1330 PangoFontDescription *FontDesc;
1331 PangoRectangle ink_rect;
1332 gint global_width=0;
1333 GdkColor foreground = { 0, 0, 0, 0 };
1334 GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
1335
1336 LttTime window_end = time_window.end_time;
1337 LttTime half_width =
1338 ltt_time_div(time_window.time_width,2.0);
1339 LttTime window_middle =
1340 ltt_time_add(half_width,
1341 time_window.start_time);
1342 g_debug("ruler expose event");
1343
1344 gdk_draw_rectangle (drawing->ruler->window,
1345 drawing->ruler->style->white_gc,
1346 TRUE,
1347 event->area.x, event->area.y,
1348 event->area.width,
1349 event->area.height);
1350
1351 gdk_draw_line (drawing->ruler->window,
1352 drawing->ruler_gc_butt,
1353 event->area.x, 1,
1354 event->area.x + event->area.width, 1);
1355
1356
1357 snprintf(text, 255, "%lus\n%luns",
1358 time_window.start_time.tv_sec,
1359 time_window.start_time.tv_nsec);
1360
1361 layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
1362
1363 context = pango_layout_get_context(layout);
1364 FontDesc = pango_context_get_font_description(context);
1365
1366 pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
1367 pango_layout_context_changed(layout);
1368
1369 pango_layout_set_text(layout, text, -1);
1370 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1371 global_width += ink_rect.width;
1372
1373 gdk_draw_layout_with_colors(drawing->ruler->window,
1374 drawing->ruler_gc_butt,
1375 0,
1376 6,
1377 layout, &foreground, &background);
1378
1379 gdk_draw_line (drawing->ruler->window,
1380 drawing->ruler_gc_round,
1381 1, 1,
1382 1, 7);
1383
1384
1385 snprintf(text, 255, "%lus\n%luns", window_end.tv_sec,
1386 window_end.tv_nsec);
1387
1388 pango_layout_set_text(layout, text, -1);
1389 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1390 global_width += ink_rect.width;
1391
1392 if(global_width <= drawing->ruler->allocation.width)
1393 {
1394 gdk_draw_layout_with_colors(drawing->ruler->window,
1395 drawing->ruler_gc_butt,
1396 drawing->ruler->allocation.width - ink_rect.width,
1397 6,
1398 layout, &foreground, &background);
1399
1400 gdk_draw_line (drawing->ruler->window,
1401 drawing->ruler_gc_butt,
1402 drawing->ruler->allocation.width-1, 1,
1403 drawing->ruler->allocation.width-1, 7);
1404 }
1405
1406
1407 snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec,
1408 window_middle.tv_nsec);
1409
1410 pango_layout_set_text(layout, text, -1);
1411 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1412 global_width += ink_rect.width;
1413
1414 if(global_width <= drawing->ruler->allocation.width)
1415 {
1416 gdk_draw_layout_with_colors(drawing->ruler->window,
1417 drawing->ruler_gc_butt,
1418 (drawing->ruler->allocation.width - ink_rect.width)/2,
1419 6,
1420 layout, &foreground, &background);
1421
1422 gdk_draw_line (drawing->ruler->window,
1423 drawing->ruler_gc_butt,
1424 drawing->ruler->allocation.width/2, 1,
1425 drawing->ruler->allocation.width/2, 7);
1426
1427
1428
1429
1430 }
1431
1432 g_object_unref(layout);
1433
1434 return FALSE;
1435 }
1436
1437
1438 /* notify mouse on ruler */
1439 static gboolean
1440 motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
1441 {
1442 //g_debug("motion");
1443 //eventually follow mouse and show time here
1444 }
This page took 0.06113 seconds and 4 git commands to generate.