unfinished conversion of gui modules
[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 // fixed #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 LttvTraceHook *th;
179
180 guint ret;
181 gint before_hn, after_hn;
182
183 nb_trace = lttv_traceset_number(traceset);
184 // FIXME (fixed) : eventually request for more traces
185 for(i = 0 ; i < nb_trace ; i++) {
186 //for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++) {
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, 18);
224 before_hn = after_hn = 0;
225
226 /* before hooks */
227
228 ret = lttv_trace_find_hook(ts->parent.t,
229 LTT_EVENT_SYSCALL_ENTRY,
230 LTT_FIELD_SYSCALL_ID, 0, 0,
231 before_execmode_hook,
232 events_request,
233 &g_array_index(hooks, LttvTraceHook, before_hn++));
234 if(ret) before_hn--;
235
236 ret = lttv_trace_find_hook(ts->parent.t,
237 LTT_EVENT_SYSCALL_EXIT,
238 0, 0, 0,
239 before_execmode_hook,
240 events_request,
241 &g_array_index(hooks, LttvTraceHook, before_hn++));
242 if(ret) before_hn--;
243
244 ret = lttv_trace_find_hook(ts->parent.t,
245 LTT_EVENT_TRAP_ENTRY,
246 LTT_FIELD_TRAP_ID, 0, 0,
247 before_execmode_hook,
248 events_request,
249 &g_array_index(hooks, LttvTraceHook, before_hn++));
250 if(ret) before_hn--;
251
252 ret = lttv_trace_find_hook(ts->parent.t,
253 LTT_EVENT_TRAP_EXIT,
254 0, 0, 0,
255 before_execmode_hook,
256 events_request,
257 &g_array_index(hooks, LttvTraceHook, before_hn++));
258 if(ret) before_hn--;
259
260 ret = lttv_trace_find_hook(ts->parent.t,
261 LTT_EVENT_IRQ_ENTRY,
262 LTT_FIELD_IRQ_ID, 0, 0,
263 before_execmode_hook,
264 events_request,
265 &g_array_index(hooks, LttvTraceHook, before_hn++));
266 if(ret) before_hn--;
267
268 ret = lttv_trace_find_hook(ts->parent.t,
269 LTT_EVENT_IRQ_EXIT,
270 0, 0, 0,
271 before_execmode_hook,
272 events_request,
273 &g_array_index(hooks, LttvTraceHook, before_hn++));
274 if(ret) before_hn--;
275
276 ret = lttv_trace_find_hook(ts->parent.t,
277 LTT_EVENT_SOFT_IRQ_ENTRY,
278 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
279 before_execmode_hook,
280 events_request,
281 &g_array_index(hooks, LttvTraceHook, before_hn++));
282 if(ret) before_hn--;
283
284 ret = lttv_trace_find_hook(ts->parent.t,
285 LTT_EVENT_SOFT_IRQ_EXIT,
286 0, 0, 0,
287 before_execmode_hook,
288 events_request,
289 &g_array_index(hooks, LttvTraceHook, before_hn++));
290 if(ret) before_hn--;
291
292
293 ret = lttv_trace_find_hook(ts->parent.t,
294 LTT_EVENT_SCHED_SCHEDULE,
295 LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE,
296 before_schedchange_hook,
297 events_request,
298 &g_array_index(hooks, LttvTraceHook, before_hn++));
299 if(ret) before_hn--;
300
301 ret = lttv_trace_find_hook(ts->parent.t,
302 LTT_EVENT_PROCESS_EXIT,
303 LTT_FIELD_PID, 0, 0,
304 before_process_exit_hook,
305 events_request,
306 &g_array_index(hooks, LttvTraceHook, before_hn++));
307 if(ret) before_hn--;
308
309 ret = lttv_trace_find_hook(ts->parent.t,
310 LTT_EVENT_PROCESS_FREE,
311 LTT_FIELD_PID, 0, 0,
312 before_process_release_hook,
313 events_request,
314 &g_array_index(hooks, LttvTraceHook, before_hn++));
315 if(ret) before_hn--;
316
317 ret = lttv_trace_find_hook(ts->parent.t,
318 LTT_EVENT_STATEDUMP_END,
319 0, 0, 0,
320 before_statedump_end,
321 events_request,
322 &g_array_index(hooks, LttvTraceHook, before_hn++));
323 if(ret) before_hn--;
324
325 #if 0
326 lttv_trace_find_hook(ts->parent.t,
327 "core", "process", "event_sub_id",
328 "event_data1", "event_data2", before_process_hook,
329 &g_array_index(hooks, LttvTraceHook, hn++));
330 #endif //0
331 #if 0
332 lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid",
333 NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, hn++));
334
335 lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL,
336 NULL, process_exit, &g_array_index(hooks, LttvTraceHook, hn++));
337 #endif //0
338
339 /* after hooks */
340
341 #if 0
342 /**** DESACTIVATED ****/
343 lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id",
344 NULL, NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, hn++));
345 /**** DESACTIVATED ****/
346 lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL,
347 NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, hn++));
348
349 /**** DESACTIVATED ****/
350 lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
351 NULL, NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, hn++));
352
353 /**** DESACTIVATED ****/
354 lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL,
355 after_execmode_hook, &g_array_index(hooks, LttvTraceHook, hn++));
356
357 /**** DESACTIVATED ****/
358 lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL,
359 NULL, after_execmode_hook, &g_array_index(hooks, LttvTraceHook, hn++));
360
361 /**** DESACTIVATED ****/
362 lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL,
363 after_execmode_hook, &g_array_index(hooks, LttvTraceHook, hn++));
364 #endif //0
365 #if 0
366 lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out",
367 "out_state", after_schedchange_hook,
368 &g_array_index(hooks, LttvTraceHook, hn++));
369
370 lttv_trace_find_hook(ts->parent.t, "core", "process", "event_sub_id",
371 "event_data1", "event_data2", after_process_hook,
372 &g_array_index(hooks, LttvTraceHook, hn++));
373 #endif //0
374 after_hn = before_hn;
375
376 ret = lttv_trace_find_hook(ts->parent.t,
377 LTT_EVENT_SCHED_SCHEDULE,
378 LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE,
379 after_schedchange_hook,
380 events_request,
381 &g_array_index(hooks, LttvTraceHook, after_hn++));
382 if(ret) after_hn--;
383
384 ret = lttv_trace_find_hook(ts->parent.t,
385 LTT_EVENT_PROCESS_FORK,
386 LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
387 after_process_fork_hook,
388 events_request,
389 &g_array_index(hooks, LttvTraceHook, after_hn++));
390 if(ret) after_hn--;
391
392 ret = lttv_trace_find_hook(ts->parent.t,
393 LTT_EVENT_PROCESS_EXIT,
394 LTT_FIELD_PID, 0, 0,
395 after_process_exit_hook,
396 events_request,
397 &g_array_index(hooks, LttvTraceHook, after_hn++));
398 if(ret) after_hn--;
399
400 ret = lttv_trace_find_hook(ts->parent.t,
401 LTT_EVENT_EXEC,
402 0, 0, 0,
403 after_fs_exec_hook,
404 events_request,
405 &g_array_index(hooks, LttvTraceHook, after_hn++));
406 if(ret) after_hn--;
407
408 ret = lttv_trace_find_hook(ts->parent.t,
409 LTT_EVENT_THREAD_BRAND,
410 LTT_FIELD_NAME, 0, 0,
411 after_user_generic_thread_brand_hook,
412 events_request,
413 &g_array_index(hooks, LttvTraceHook, after_hn++));
414 if(ret) after_hn--;
415
416 ret = lttv_trace_find_hook(ts->parent.t,
417 LTT_EVENT_PROCESS_STATE,
418 LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
419 after_event_enum_process_hook,
420 events_request,
421 &g_array_index(hooks, LttvTraceHook, after_hn++));
422 if(ret) after_hn--;
423
424 hooks = g_array_set_size(hooks, after_hn);
425
426 #if 0
427 lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid",
428 NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, hn++));
429
430 lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL,
431 NULL, process_exit, &g_array_index(hooks, LttvTraceHook, hn++));
432 #endif //0
433
434
435
436 /* Add these hooks to each event_by_id hooks list */
437 /* add before */
438 for(k = 0 ; k < before_hn ; k++) {
439 lttv_hooks_add(lttv_hooks_by_id_find(event_by_id, th->id),
440 th->h,
441 th,
442 LTTV_PRIO_STATE-5);
443 }
444
445 /* add after */
446 for(k = before_hn ; k < after_hn ; k++) {
447 lttv_hooks_add(lttv_hooks_by_id_find(event_by_id, th->id),
448 th->h,
449 th,
450 LTTV_PRIO_STATE+5);
451 }
452
453 events_request->hooks = hooks;
454
455 // Fill the events request
456 events_request->owner = control_flow_data;
457 events_request->viewer_data = control_flow_data;
458 events_request->servicing = FALSE;
459 events_request->start_time = start;
460 events_request->start_position = NULL;
461 events_request->stop_flag = FALSE;
462 events_request->end_time = time_end;
463 events_request->num_events = G_MAXUINT;
464 events_request->end_position = NULL;
465 events_request->trace = i; //fixed /* FIXME */
466 events_request->before_chunk_traceset = before_chunk_traceset;
467 events_request->before_chunk_trace = NULL;
468 events_request->before_chunk_tracefile = NULL;
469 events_request->event = NULL;
470 events_request->event_by_id = event_by_id;
471 events_request->after_chunk_tracefile = NULL;
472 events_request->after_chunk_trace = NULL;
473 events_request->after_chunk_traceset = after_chunk_traceset;
474 events_request->before_request = before_request_hook;
475 events_request->after_request = after_request_hook;
476
477 g_debug("req : start : %lu, %lu", start.tv_sec,
478 start.tv_nsec);
479
480 g_debug("req : end : %lu, %lu", time_end.tv_sec,
481 time_end.tv_nsec);
482
483 lttvwindow_events_request(tab, events_request);
484
485 }
486
487 }
488
489 #if 0
490 lttv_hooks_add(event,
491 before_schedchange_hook,
492 events_request,
493 LTTV_PRIO_STATE-5);
494 lttv_hooks_add(event,
495 after_schedchange_hook,
496 events_request,
497 LTTV_PRIO_STATE+5);
498 lttv_hooks_add(event,
499 before_execmode_hook,
500 events_request,
501 LTTV_PRIO_STATE-5);
502 lttv_hooks_add(event,
503 after_execmode_hook,
504 events_request,
505 LTTV_PRIO_STATE+5);
506 lttv_hooks_add(event,
507 before_process_hook,
508 events_request,
509 LTTV_PRIO_STATE-5);
510 lttv_hooks_add(event,
511 after_process_hook,
512 events_request,
513 LTTV_PRIO_STATE+5);
514 #endif //0
515
516 }
517
518
519 static void set_last_start(gpointer key, gpointer value, gpointer user_data)
520 {
521 ProcessInfo *process_info = (ProcessInfo*)key;
522 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
523 guint x = (guint)user_data;
524
525 hashed_process_data->x.over = x;
526 hashed_process_data->x.over_used = FALSE;
527 hashed_process_data->x.over_marked = FALSE;
528 hashed_process_data->x.middle = x;
529 hashed_process_data->x.middle_used = FALSE;
530 hashed_process_data->x.middle_marked = FALSE;
531 hashed_process_data->x.under = x;
532 hashed_process_data->x.under_used = FALSE;
533 hashed_process_data->x.under_marked = FALSE;
534 hashed_process_data->next_good_time = ltt_time_zero;
535
536 return;
537 }
538
539 void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss)
540 {
541 g_debug("Begin of data request");
542 ControlFlowData *cfd = events_request->viewer_data;
543 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss);
544 TimeWindow time_window =
545 lttvwindow_get_time_window(cfd->tab);
546
547 guint width = cfd->drawing->width;
548 guint x=0;
549
550 cfd->drawing->last_start = events_request->start_time;
551
552 convert_time_to_pixels(
553 time_window,
554 events_request->start_time,
555 width,
556 &x);
557
558 g_hash_table_foreach(cfd->process_list->process_hash, set_last_start,
559 (gpointer)x);
560
561 }
562
563 void drawing_chunk_begin(EventsRequest *events_request, LttvTracesetState *tss)
564 {
565 g_debug("Begin of chunk");
566 ControlFlowData *cfd = events_request->viewer_data;
567 LttvTracesetContext *tsc = &tss->parent.parent;
568 //LttTime current_time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
569 guint i;
570 LttvTraceset *traceset = tsc->ts;
571 guint nb_trace = lttv_traceset_number(traceset);
572
573 if(!cfd->process_list->current_hash_data) {
574 cfd->process_list->current_hash_data = g_new(HashedProcessData**,nb_trace);
575 for(i = 0 ; i < nb_trace ; i++) {
576 guint num_cpu = ltt_trace_get_num_cpu(tss->parent.traces[i]->t);
577 cfd->process_list->current_hash_data[i] = g_new(HashedProcessData*,num_cpu);
578 memset(cfd->process_list->current_hash_data[i], 0,
579 sizeof(HashedProcessData*)*num_cpu);
580 }
581 }
582 //cfd->drawing->last_start = LTT_TIME_MIN(current_time,
583 // events_request->end_time);
584 }
585
586
587 void drawing_request_expose(EventsRequest *events_request,
588 LttvTracesetState *tss,
589 LttTime end_time)
590 {
591 gint x, width;
592 guint x_end;
593
594 ControlFlowData *cfd = events_request->viewer_data;
595 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
596 Drawing_t *drawing = cfd->drawing;
597
598 TimeWindow time_window =
599 lttvwindow_get_time_window(cfd->tab);
600
601 g_debug("request expose");
602
603 convert_time_to_pixels(
604 time_window,
605 end_time,
606 drawing->width,
607 &x_end);
608 x = drawing->damage_begin;
609
610 width = x_end - x;
611
612 drawing->damage_begin = x+width;
613
614 // FIXME ?
615 gtk_widget_queue_draw_area ( drawing->drawing_area,
616 x, 0,
617 width, drawing->drawing_area->allocation.height);
618
619 /* Update directly when scrolling */
620 gdk_window_process_updates(drawing->drawing_area->window,
621 TRUE);
622 }
623
624
625 /* Callbacks */
626
627
628 /* Create a new backing pixmap of the appropriate size */
629 /* As the scaling will always change, it's of no use to copy old
630 * pixmap.
631 *
632 * Only change the size if width changes. The height is specified and changed
633 * when process ID are added or removed from the process list.
634 */
635 static gboolean
636 configure_event( GtkWidget *widget, GdkEventConfigure *event,
637 gpointer user_data)
638 {
639 Drawing_t *drawing = (Drawing_t*)user_data;
640
641
642 /* First, get the new time interval of the main window */
643 /* we assume (see documentation) that the main window
644 * has updated the time interval before this configure gets
645 * executed.
646 */
647 //lttvwindow_get_time_window(drawing->control_flow_data->mw,
648 // &drawing->control_flow_data->time_window);
649
650 /* New pixmap, size of the configure event */
651 //GdkPixmap *pixmap = gdk_pixmap_new(widget->window,
652 // widget->allocation.width + SAFETY,
653 // widget->allocation.height + SAFETY,
654 // -1);
655
656 if(widget->allocation.width != drawing->width) {
657 g_debug("drawing configure event");
658 g_debug("New alloc draw size : %i by %i",widget->allocation.width,
659 widget->allocation.height);
660
661 drawing->width = widget->allocation.width;
662
663 if(drawing->alloc_width < widget->allocation.width) {
664 //if(drawing->pixmap)
665 // gdk_pixmap_unref(drawing->pixmap);
666
667 //drawing->pixmap = gdk_pixmap_new(widget->window,
668 // drawing->width + SAFETY + EXTRA_ALLOC,
669 // drawing->height + EXTRA_ALLOC,
670 // -1);
671 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
672 drawing->alloc_height = drawing->height + EXTRA_ALLOC;
673 update_pixmap_size(drawing->control_flow_data->process_list,
674 drawing->alloc_width);
675 update_index_to_pixmap(drawing->control_flow_data->process_list);
676 }
677 //drawing->height = widget->allocation.height;
678
679 //ProcessList_get_height
680 // (GuiControlFlow_get_process_list(drawing->control_flow_data)),
681
682
683 // Clear the image
684 //gdk_draw_rectangle (drawing->pixmap,
685 // widget->style->black_gc,
686 // TRUE,
687 // 0, 0,
688 // drawing->width+SAFETY,
689 // drawing->height);
690
691 //g_info("init data request");
692
693
694 /* Initial data request */
695 /* no, do initial data request in the expose event */
696 // Do not need to ask for data of 1 pixel : not synchronized with
697 // main window time at this moment.
698 //drawing_data_request(drawing, &drawing->pixmap, 0, 0,
699 // widget->allocation.width,
700 // widget->allocation.height);
701
702 //drawing->width = widget->allocation.width;
703 //drawing->height = widget->allocation.height;
704
705 drawing->damage_begin = 0;
706 drawing->damage_end = widget->allocation.width;
707
708 if((widget->allocation.width != 1 &&
709 widget->allocation.height != 1)
710 && drawing->damage_begin < drawing->damage_end)
711 {
712
713 rectangle_pixmap (drawing->control_flow_data->process_list,
714 drawing->drawing_area->style->black_gc,
715 TRUE,
716 0, 0,
717 drawing->alloc_width, // do not overlap
718 -1);
719
720
721 drawing_data_request(drawing,
722 drawing->damage_begin,
723 0,
724 drawing->damage_end - drawing->damage_begin,
725 drawing->height);
726 }
727 }
728 return TRUE;
729 }
730
731
732 /* Redraw the screen from the backing pixmap */
733 static gboolean
734 expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
735 {
736 Drawing_t *drawing = (Drawing_t*)user_data;
737
738 ControlFlowData *control_flow_data =
739 (ControlFlowData*)g_object_get_data(
740 G_OBJECT(widget),
741 "control_flow_data");
742 #if 0
743 if(unlikely(drawing->gc == NULL)) {
744 drawing->gc = gdk_gc_new(drawing->drawing_area->window);
745 gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc);
746 }
747 #endif //0
748 TimeWindow time_window =
749 lttvwindow_get_time_window(control_flow_data->tab);
750 LttTime current_time =
751 lttvwindow_get_current_time(control_flow_data->tab);
752
753 guint cursor_x=0;
754
755 LttTime window_end = time_window.end_time;
756
757 /* update the screen from the pixmap buffer */
758 #if 0
759 gdk_draw_pixmap(widget->window,
760 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
761 drawing->pixmap,
762 event->area.x, event->area.y,
763 event->area.x, event->area.y,
764 event->area.width, event->area.height);
765 #endif //0
766 drawing->height = processlist_get_height(control_flow_data->process_list);
767 #if 0
768 copy_pixmap_to_screen(control_flow_data->process_list,
769 widget->window,
770 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
771 event->area.x, event->area.y,
772 event->area.width, event->area.height);
773 #endif //0
774 copy_pixmap_to_screen(control_flow_data->process_list,
775 widget->window,
776 drawing->gc,
777 event->area.x, event->area.y,
778 event->area.width, event->area.height);
779
780
781 /* Erase the dotted lines left.. */
782 if(widget->allocation.height > drawing->height)
783 {
784 gdk_draw_rectangle (widget->window,
785 drawing->drawing_area->style->black_gc,
786 TRUE,
787 event->area.x, drawing->height,
788 event->area.width, // do not overlap
789 widget->allocation.height - drawing->height);
790 }
791 if(ltt_time_compare(time_window.start_time, current_time) <= 0 &&
792 ltt_time_compare(window_end, current_time) >= 0)
793 {
794 /* Draw the dotted lines */
795 convert_time_to_pixels(
796 time_window,
797 current_time,
798 drawing->width,
799 &cursor_x);
800
801 #if 0
802 if(drawing->dotted_gc == NULL) {
803
804 drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window);
805 gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc);
806
807 gint8 dash_list[] = { 1, 2 };
808 gdk_gc_set_line_attributes(drawing->dotted_gc,
809 1,
810 GDK_LINE_ON_OFF_DASH,
811 GDK_CAP_BUTT,
812 GDK_JOIN_MITER);
813 gdk_gc_set_dashes(drawing->dotted_gc,
814 0,
815 dash_list,
816 2);
817 }
818 #endif //0
819 gint height_tot = MAX(widget->allocation.height, drawing->height);
820 gdk_draw_line(widget->window,
821 drawing->dotted_gc,
822 cursor_x, 0,
823 cursor_x, height_tot);
824 }
825 return FALSE;
826 }
827
828 static gboolean
829 after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
830 {
831 //g_assert(0);
832 g_debug("AFTER EXPOSE");
833
834 return FALSE;
835
836
837 }
838
839 #if 0
840 void
841 tree_row_activated(GtkTreeModel *treemodel,
842 GtkTreePath *arg1,
843 GtkTreeViewColumn *arg2,
844 gpointer user_data)
845 {
846 ControlFlowData *cfd = (ControlFlowData*)user_data;
847 Drawing_t *drawing = cfd->drawing;
848 GtkTreeView *treeview = cfd->process_list->process_list_widget;
849 gint *path_indices;
850 gint height;
851
852 path_indices = gtk_tree_path_get_indices (arg1);
853
854 height = get_cell_height(cfd->process_list,
855 GTK_TREE_VIEW(treeview));
856 drawing->horizontal_sel = height * path_indices[0];
857 g_critical("new hor sel : %i", drawing->horizontal_sel);
858 }
859 #endif //0
860
861 /* mouse click */
862 static gboolean
863 button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
864 {
865 ControlFlowData *control_flow_data =
866 (ControlFlowData*)g_object_get_data(
867 G_OBJECT(widget),
868 "control_flow_data");
869 Drawing_t *drawing = control_flow_data->drawing;
870 TimeWindow time_window =
871 lttvwindow_get_time_window(control_flow_data->tab);
872
873 g_debug("click");
874 if(event->button == 1)
875 {
876 LttTime time;
877
878 /* left mouse button click */
879 g_debug("x click is : %f", event->x);
880
881 convert_pixels_to_time(drawing->width, (guint)event->x,
882 time_window,
883 &time);
884
885 lttvwindow_report_current_time(control_flow_data->tab, time);
886
887 }
888
889 return FALSE;
890 }
891
892 static gboolean
893 scrollbar_size_allocate(GtkWidget *widget,
894 GtkAllocation *allocation,
895 gpointer user_data)
896 {
897 Drawing_t *drawing = (Drawing_t*)user_data;
898
899 gtk_widget_set_size_request(drawing->padding, allocation->width, -1);
900 //gtk_widget_queue_resize(drawing->padding);
901 //gtk_widget_queue_resize(drawing->ruler);
902 gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox));
903 return 0;
904 }
905
906
907
908 Drawing_t *drawing_construct(ControlFlowData *control_flow_data)
909 {
910 Drawing_t *drawing = g_new(Drawing_t, 1);
911
912 drawing->control_flow_data = control_flow_data;
913
914 drawing->vbox = gtk_vbox_new(FALSE, 1);
915
916
917 drawing->ruler_hbox = gtk_hbox_new(FALSE, 1);
918 drawing->ruler = gtk_drawing_area_new ();
919 //gtk_widget_set_size_request(drawing->ruler, -1, 27);
920
921 drawing->padding = gtk_drawing_area_new ();
922 //gtk_widget_set_size_request(drawing->padding, -1, 27);
923 gtk_box_pack_start(GTK_BOX(drawing->ruler_hbox), drawing->ruler,
924 TRUE, TRUE, 0);
925 gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->padding,
926 FALSE, FALSE, 0);
927
928
929
930 drawing->drawing_area = gtk_drawing_area_new ();
931
932 drawing->gc = NULL;
933
934 drawing->hbox = gtk_hbox_new(FALSE, 1);
935 drawing->viewport = gtk_viewport_new(NULL, control_flow_data->v_adjust);
936 drawing->scrollbar = gtk_vscrollbar_new(control_flow_data->v_adjust);
937 gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport,
938 TRUE, TRUE, 0);
939 gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar,
940 FALSE, FALSE, 0);
941
942 //drawing->scrolled_window =
943 // gtk_scrolled_window_new (NULL,
944 // control_flow_data->v_adjust);
945
946 //gtk_scrolled_window_set_policy(
947 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
948 // GTK_POLICY_NEVER,
949 // GTK_POLICY_AUTOMATIC);
950
951 gtk_container_add(GTK_CONTAINER(drawing->viewport),
952 drawing->drawing_area);
953 //gtk_scrolled_window_add_with_viewport(
954 // GTK_SCROLLED_WINDOW(drawing->scrolled_window),
955 // drawing->drawing_area);
956
957 gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox,
958 FALSE, FALSE, 0);
959 gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->hbox,
960 TRUE, TRUE, 0);
961
962 drawing->pango_layout =
963 gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
964
965 drawing->height = 1;
966 drawing->width = 1;
967 drawing->depth = 0;
968 drawing->alloc_height = 1;
969 drawing->alloc_width = 1;
970
971 drawing->damage_begin = 0;
972 drawing->damage_end = 0;
973 drawing->horizontal_sel = -1;
974
975 //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50);
976 g_object_set_data_full(
977 G_OBJECT(drawing->drawing_area),
978 "Link_drawing_Data",
979 drawing,
980 (GDestroyNotify)drawing_destroy);
981
982 g_object_set_data(
983 G_OBJECT(drawing->ruler),
984 "drawing",
985 drawing);
986
987
988 //gtk_widget_modify_bg( drawing->drawing_area,
989 // GTK_STATE_NORMAL,
990 // &CF_Colors[BLACK]);
991
992 //gdk_window_get_geometry(drawing->drawing_area->window,
993 // NULL, NULL,
994 // &(drawing->width),
995 // &(drawing->height),
996 // -1);
997
998 //drawing->pixmap = gdk_pixmap_new(
999 // drawing->drawing_area->window,
1000 // drawing->width,
1001 // drawing->height,
1002 // drawing->depth);
1003
1004 //drawing->pixmap = NULL;
1005
1006 // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1007 // drawing->drawing_area->allocation.width,
1008 // drawing->drawing_area->allocation.height,
1009 // -1);
1010
1011 g_signal_connect (G_OBJECT(drawing->drawing_area),
1012 "configure_event",
1013 G_CALLBACK (configure_event),
1014 (gpointer)drawing);
1015
1016 g_signal_connect (G_OBJECT(drawing->ruler),
1017 "expose_event",
1018 G_CALLBACK(expose_ruler),
1019 (gpointer)drawing);
1020
1021 gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK);
1022
1023 g_signal_connect (G_OBJECT(drawing->ruler),
1024 "motion-notify-event",
1025 G_CALLBACK(motion_notify_ruler),
1026 (gpointer)drawing);
1027
1028
1029 g_signal_connect (G_OBJECT(drawing->scrollbar),
1030 "size-allocate",
1031 G_CALLBACK(scrollbar_size_allocate),
1032 (gpointer)drawing);
1033
1034
1035
1036 g_signal_connect (G_OBJECT(drawing->drawing_area),
1037 "expose_event",
1038 G_CALLBACK (expose_event),
1039 (gpointer)drawing);
1040
1041 g_signal_connect_after (G_OBJECT(drawing->drawing_area),
1042 "expose_event",
1043 G_CALLBACK (after_expose_event),
1044 (gpointer)drawing);
1045
1046 g_signal_connect (G_OBJECT(drawing->drawing_area),
1047 "button-press-event",
1048 G_CALLBACK (button_press_event),
1049 (gpointer)drawing);
1050
1051
1052 gtk_widget_show(drawing->ruler);
1053 gtk_widget_show(drawing->padding);
1054 gtk_widget_show(drawing->ruler_hbox);
1055
1056 gtk_widget_show(drawing->drawing_area);
1057 //gtk_widget_show(drawing->scrolled_window);
1058 gtk_widget_show(drawing->viewport);
1059 gtk_widget_show(drawing->scrollbar);
1060 gtk_widget_show(drawing->hbox);
1061
1062 /* Allocate the colors */
1063 GdkColormap* colormap = gdk_colormap_get_system();
1064 gboolean success[NUM_COLORS];
1065 gdk_colormap_alloc_colors(colormap, drawing_colors, NUM_COLORS, FALSE,
1066 TRUE, success);
1067
1068 drawing->gc =
1069 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
1070 drawing->dotted_gc =
1071 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
1072
1073 gdk_gc_copy(drawing->gc,
1074 main_window_get_widget(control_flow_data->tab)->style->black_gc);
1075 gdk_gc_copy(drawing->dotted_gc,
1076 main_window_get_widget(control_flow_data->tab)->style->white_gc);
1077
1078 gint8 dash_list[] = { 1, 2 };
1079 gdk_gc_set_line_attributes(drawing->dotted_gc,
1080 1,
1081 GDK_LINE_ON_OFF_DASH,
1082 GDK_CAP_BUTT,
1083 GDK_JOIN_MITER);
1084 gdk_gc_set_dashes(drawing->dotted_gc,
1085 0,
1086 dash_list,
1087 2);
1088
1089 drawing->ruler_gc_butt =
1090 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
1091 gdk_gc_copy(drawing->ruler_gc_butt,
1092 main_window_get_widget(control_flow_data->tab)->style->black_gc);
1093 drawing->ruler_gc_round =
1094 gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window));
1095 gdk_gc_copy(drawing->ruler_gc_round,
1096 main_window_get_widget(control_flow_data->tab)->style->black_gc);
1097
1098
1099 gdk_gc_set_line_attributes(drawing->ruler_gc_butt,
1100 2,
1101 GDK_LINE_SOLID,
1102 GDK_CAP_BUTT,
1103 GDK_JOIN_MITER);
1104
1105 gdk_gc_set_line_attributes(drawing->ruler_gc_round,
1106 2,
1107 GDK_LINE_SOLID,
1108 GDK_CAP_ROUND,
1109 GDK_JOIN_ROUND);
1110
1111
1112 return drawing;
1113 }
1114
1115 void drawing_destroy(Drawing_t *drawing)
1116 {
1117 g_info("drawing_destroy %p", drawing);
1118
1119 /* Free the colors */
1120 GdkColormap* colormap = gdk_colormap_get_system();
1121
1122 gdk_colormap_free_colors(colormap, drawing_colors, NUM_COLORS);
1123
1124
1125
1126 // Do not unref here, Drawing_t destroyed by it's widget.
1127 //g_object_unref( G_OBJECT(drawing->drawing_area));
1128 if(drawing->gc != NULL)
1129 gdk_gc_unref(drawing->gc);
1130
1131 g_object_unref(drawing->pango_layout);
1132 if(drawing->dotted_gc != NULL) gdk_gc_unref(drawing->dotted_gc);
1133 if(drawing->ruler_gc_butt != NULL) gdk_gc_unref(drawing->ruler_gc_butt);
1134 if(drawing->ruler_gc_round != NULL) gdk_gc_unref(drawing->ruler_gc_round);
1135
1136 g_free(drawing);
1137 g_info("drawing_destroy end");
1138 }
1139
1140 GtkWidget *drawing_get_drawing_area(Drawing_t *drawing)
1141 {
1142 return drawing->drawing_area;
1143 }
1144
1145 GtkWidget *drawing_get_widget(Drawing_t *drawing)
1146 {
1147 return drawing->vbox;
1148 }
1149
1150 void drawing_draw_line( Drawing_t *drawing,
1151 GdkPixmap *pixmap,
1152 guint x1, guint y1,
1153 guint x2, guint y2,
1154 GdkGC *GC)
1155 {
1156 gdk_draw_line (pixmap,
1157 GC,
1158 x1, y1, x2, y2);
1159 }
1160
1161 void drawing_clear(Drawing_t *drawing)
1162 {
1163 //if (drawing->pixmap)
1164 // gdk_pixmap_unref(drawing->pixmap);
1165 ControlFlowData *cfd = drawing->control_flow_data;
1166
1167
1168 rectangle_pixmap(cfd->process_list,
1169 drawing->drawing_area->style->black_gc,
1170 TRUE,
1171 0, 0,
1172 drawing->alloc_width, // do not overlap
1173 -1);
1174
1175 //drawing->height = 1;
1176 /* Allocate a new pixmap with new height */
1177 //drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1178 // drawing->width + SAFETY + EXTRA_ALLOC,
1179 // drawing->height + EXTRA_ALLOC,
1180 // -1);
1181 //drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1182 //drawing->alloc_height = drawing->height + EXTRA_ALLOC;
1183
1184 //gtk_widget_set_size_request(drawing->drawing_area,
1185 // -1,
1186 // drawing->height);
1187 //gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1188
1189 /* ask for the buffer to be redrawn */
1190 gtk_widget_queue_draw ( drawing->drawing_area);
1191 }
1192
1193 #if 0
1194 /* Insert a square corresponding to a new process in the list */
1195 /* Applies to whole drawing->width */
1196 void drawing_insert_square(Drawing_t *drawing,
1197 guint y,
1198 guint height)
1199 {
1200 //GdkRectangle update_rect;
1201 gboolean reallocate = FALSE;
1202 GdkPixmap *new_pixmap;
1203
1204 /* Allocate a new pixmap with new height */
1205 if(drawing->alloc_height < drawing->height + height) {
1206
1207 new_pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1208 drawing->width + SAFETY + EXTRA_ALLOC,
1209 drawing->height + height + EXTRA_ALLOC,
1210 -1);
1211 drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC;
1212 drawing->alloc_height = drawing->height + height + EXTRA_ALLOC;
1213 reallocate = TRUE;
1214
1215 /* Copy the high region */
1216 gdk_draw_pixmap (new_pixmap,
1217 drawing->drawing_area->style->black_gc,
1218 drawing->pixmap,
1219 0, 0,
1220 0, 0,
1221 drawing->width + SAFETY, y);
1222
1223 } else {
1224 new_pixmap = drawing->pixmap;
1225 }
1226
1227 //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window,
1228 // drawing->width + SAFETY,
1229 // drawing->height + height,
1230 // -1);
1231
1232 /* add an empty square */
1233 gdk_draw_rectangle (new_pixmap,
1234 drawing->drawing_area->style->black_gc,
1235 TRUE,
1236 0, y,
1237 drawing->width + SAFETY, // do not overlap
1238 height);
1239
1240 /* copy the bottom of the region */
1241 gdk_draw_pixmap (new_pixmap,
1242 drawing->drawing_area->style->black_gc,
1243 drawing->pixmap,
1244 0, y,
1245 0, y + height,
1246 drawing->width+SAFETY, drawing->height - y);
1247
1248
1249 if(reallocate && likely(drawing->pixmap)) {
1250 gdk_pixmap_unref(drawing->pixmap);
1251 drawing->pixmap = new_pixmap;
1252 }
1253
1254 if(unlikely(drawing->height==1)) drawing->height = height;
1255 else drawing->height += height;
1256
1257 gtk_widget_set_size_request(drawing->drawing_area,
1258 -1,
1259 drawing->height);
1260 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1261
1262 /* ask for the buffer to be redrawn */
1263 gtk_widget_queue_draw_area ( drawing->drawing_area,
1264 0, y,
1265 drawing->width, drawing->height-y);
1266 }
1267
1268
1269 /* Remove a square corresponding to a removed process in the list */
1270 void drawing_remove_square(Drawing_t *drawing,
1271 guint y,
1272 guint height)
1273 {
1274 GdkPixmap *pixmap;
1275
1276 if(unlikely((guint)drawing->height == height)) {
1277 //pixmap = gdk_pixmap_new(
1278 // drawing->drawing_area->window,
1279 // drawing->width + SAFETY,
1280 // 1,
1281 // -1);
1282 pixmap = drawing->pixmap;
1283 drawing->height=1;
1284 } else {
1285 /* Allocate a new pixmap with new height */
1286 //pixmap = gdk_pixmap_new(
1287 // drawing->drawing_area->window,
1288 // drawing->width + SAFETY,
1289 // drawing->height - height,
1290 // -1);
1291 /* Keep the same preallocated pixmap */
1292 pixmap = drawing->pixmap;
1293
1294 /* Copy the high region */
1295 gdk_draw_pixmap (pixmap,
1296 drawing->drawing_area->style->black_gc,
1297 drawing->pixmap,
1298 0, 0,
1299 0, 0,
1300 drawing->width + SAFETY, y);
1301
1302 /* Copy up the bottom of the region */
1303 gdk_draw_pixmap (pixmap,
1304 drawing->drawing_area->style->black_gc,
1305 drawing->pixmap,
1306 0, y + height,
1307 0, y,
1308 drawing->width, drawing->height - y - height);
1309
1310 drawing->height-=height;
1311 }
1312
1313 //if(likely(drawing->pixmap))
1314 // gdk_pixmap_unref(drawing->pixmap);
1315
1316 //drawing->pixmap = pixmap;
1317
1318 gtk_widget_set_size_request(drawing->drawing_area,
1319 -1,
1320 drawing->height);
1321 gtk_widget_queue_resize_no_redraw(drawing->drawing_area);
1322 /* ask for the buffer to be redrawn */
1323 gtk_widget_queue_draw_area ( drawing->drawing_area,
1324 0, y,
1325 drawing->width, MAX(drawing->height-y, 1));
1326 }
1327 #endif //0
1328
1329 void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window)
1330 {
1331 GtkRequisition req;
1332 GdkRectangle rect;
1333
1334 req.width = drawing->ruler->allocation.width;
1335 req.height = drawing->ruler->allocation.height;
1336
1337
1338 rect.x = 0;
1339 rect.y = 0;
1340 rect.width = req.width;
1341 rect.height = req.height;
1342
1343 gtk_widget_queue_draw(drawing->ruler);
1344 //gtk_widget_draw( drawing->ruler, &rect);
1345 }
1346
1347 /* Redraw the ruler */
1348 static gboolean
1349 expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data )
1350 {
1351 Drawing_t *drawing = (Drawing_t*)user_data;
1352 TimeWindow time_window = lttvwindow_get_time_window(drawing->control_flow_data->tab);
1353 gchar text[255];
1354
1355 PangoContext *context;
1356 PangoLayout *layout;
1357 PangoFontDescription *FontDesc;
1358 PangoRectangle ink_rect;
1359 gint global_width=0;
1360 GdkColor foreground = { 0, 0, 0, 0 };
1361 GdkColor background = { 0, 0xffff, 0xffff, 0xffff };
1362
1363 LttTime window_end = time_window.end_time;
1364 LttTime half_width =
1365 ltt_time_div(time_window.time_width,2.0);
1366 LttTime window_middle =
1367 ltt_time_add(half_width,
1368 time_window.start_time);
1369 g_debug("ruler expose event");
1370
1371 gdk_draw_rectangle (drawing->ruler->window,
1372 drawing->ruler->style->white_gc,
1373 TRUE,
1374 event->area.x, event->area.y,
1375 event->area.width,
1376 event->area.height);
1377
1378 gdk_draw_line (drawing->ruler->window,
1379 drawing->ruler_gc_butt,
1380 event->area.x, 1,
1381 event->area.x + event->area.width, 1);
1382
1383
1384 snprintf(text, 255, "%lus\n%luns",
1385 time_window.start_time.tv_sec,
1386 time_window.start_time.tv_nsec);
1387
1388 layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL);
1389
1390 context = pango_layout_get_context(layout);
1391 FontDesc = pango_context_get_font_description(context);
1392
1393 pango_font_description_set_size(FontDesc, 6*PANGO_SCALE);
1394 pango_layout_context_changed(layout);
1395
1396 pango_layout_set_text(layout, text, -1);
1397 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1398 global_width += ink_rect.width;
1399
1400 gdk_draw_layout_with_colors(drawing->ruler->window,
1401 drawing->ruler_gc_butt,
1402 0,
1403 6,
1404 layout, &foreground, &background);
1405
1406 gdk_draw_line (drawing->ruler->window,
1407 drawing->ruler_gc_round,
1408 1, 1,
1409 1, 7);
1410
1411
1412 snprintf(text, 255, "%lus\n%luns", window_end.tv_sec,
1413 window_end.tv_nsec);
1414
1415 pango_layout_set_text(layout, text, -1);
1416 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1417 global_width += ink_rect.width;
1418
1419 if(global_width <= drawing->ruler->allocation.width)
1420 {
1421 gdk_draw_layout_with_colors(drawing->ruler->window,
1422 drawing->ruler_gc_butt,
1423 drawing->ruler->allocation.width - ink_rect.width,
1424 6,
1425 layout, &foreground, &background);
1426
1427 gdk_draw_line (drawing->ruler->window,
1428 drawing->ruler_gc_butt,
1429 drawing->ruler->allocation.width-1, 1,
1430 drawing->ruler->allocation.width-1, 7);
1431 }
1432
1433
1434 snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec,
1435 window_middle.tv_nsec);
1436
1437 pango_layout_set_text(layout, text, -1);
1438 pango_layout_get_pixel_extents(layout, &ink_rect, NULL);
1439 global_width += ink_rect.width;
1440
1441 if(global_width <= drawing->ruler->allocation.width)
1442 {
1443 gdk_draw_layout_with_colors(drawing->ruler->window,
1444 drawing->ruler_gc_butt,
1445 (drawing->ruler->allocation.width - ink_rect.width)/2,
1446 6,
1447 layout, &foreground, &background);
1448
1449 gdk_draw_line (drawing->ruler->window,
1450 drawing->ruler_gc_butt,
1451 drawing->ruler->allocation.width/2, 1,
1452 drawing->ruler->allocation.width/2, 7);
1453
1454
1455
1456
1457 }
1458
1459 g_object_unref(layout);
1460
1461 return FALSE;
1462 }
1463
1464
1465 /* notify mouse on ruler */
1466 static gboolean
1467 motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
1468 {
1469 //g_debug("motion");
1470 //eventually follow mouse and show time here
1471 return 0;
1472 }
This page took 0.061715 seconds and 4 git commands to generate.