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