Commit | Line | Data |
---|---|---|
9e01e6d4 | 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 | |
b9ce0bad YB |
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
16 | * MA 02110-1301, USA. | |
9e01e6d4 | 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 | ||
9e01e6d4 | 27 | #include <lttv/lttv.h> |
9e01e6d4 | 28 | #include <lttvwindow/lttvwindow.h> |
29 | #include <lttv/state.h> | |
30 | #include <lttv/hook.h> | |
31 | ||
32 | #include "drawing.h" | |
33 | #include "eventhooks.h" | |
34 | #include "cfv.h" | |
35 | ||
58a9b31b | 36 | //#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format) |
9e01e6d4 | 37 | |
38 | //FIXME | |
39 | // fixed #define TRACE_NUMBER 0 | |
40 | #define EXTRA_ALLOC 1024 // pixels | |
41 | ||
42 | ||
43 | #if 0 /* colors for two lines representation */ | |
44 | GdkColor drawing_colors[NUM_COLORS] = | |
45 | { /* Pixel, R, G, B */ | |
46 | { 0, 0, 0, 0 }, /* COL_BLACK */ | |
47 | { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */ | |
48 | { 0, 0x0FFF, 0xFFFF, 0xFFFF }, /* COL_WAIT_FORK : pale blue */ | |
49 | { 0, 0xFFFF, 0xFFFF, 0x0000 }, /* COL_WAIT_CPU : yellow */ | |
50 | { 0, 0xFFFF, 0xA000, 0xFCFF }, /* COL_EXIT : pale magenta */ | |
51 | { 0, 0xFFFF, 0x0000, 0xFFFF }, /* COL_ZOMBIE : purple */ | |
52 | { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_WAIT : red */ | |
53 | { 0, 0x0000, 0xFFFF, 0x0000 }, /* COL_RUN : green */ | |
54 | { 0, 0x8800, 0xFFFF, 0x8A00 }, /* COL_USER_MODE : pale green */ | |
55 | { 0, 0x09FF, 0x01FF, 0xFFFF }, /* COL_SYSCALL : blue */ | |
56 | { 0, 0xF900, 0x4200, 0xFF00 }, /* COL_TRAP : pale purple */ | |
57 | { 0, 0xFFFF, 0x5AFF, 0x01FF }, /* COL_IRQ : orange */ | |
58 | { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_MODE_UNKNOWN : white */ | |
59 | ||
60 | }; | |
61 | #endif //0 | |
62 | ||
63 | ||
64 | GdkColor drawing_colors[NUM_COLORS] = | |
65 | { /* Pixel, R, G, B */ | |
66 | { 0, 0, 0, 0 }, /* COL_BLACK */ | |
67 | { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_WHITE */ | |
68 | { 0, 0x0000, 0xFF00, 0x0000 }, /* COL_RUN_USER_MODE : green */ | |
69 | { 0, 0x0100, 0x9E00, 0xFFFF }, /* COL_RUN_SYSCALL : pale blue */ | |
70 | { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_RUN_TRAP : yellow */ | |
71 | { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_RUN_IRQ : orange */ | |
72 | { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_RUN_SOFT_IRQ : pink */ | |
73 | { 0, 0x6600, 0x0000, 0x0000 }, /* COL_WAIT : dark red */ | |
74 | { 0, 0x7700, 0x7700, 0x0000 }, /* COL_WAIT_CPU : dark yellow */ | |
75 | { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */ | |
76 | { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */ | |
77 | { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */ | |
78 | { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */ | |
79 | { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_UNNAMED : white */ | |
80 | ||
81 | }; | |
82 | ||
44ffb95f | 83 | GdkColor drawing_colors_cpu[NUM_COLORS_CPU] = |
84 | { /* Pixel, R, G, B */ | |
d3d99fde | 85 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_CPU_UNKNOWN */ |
598026ba | 86 | { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_CPU_IDLE */ |
87 | { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_CPU_BUSY */ | |
d3d99fde | 88 | { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_CPU_IRQ */ |
d34141ca | 89 | { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_CPU_SOFT_IRQ */ |
d3d99fde | 90 | { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_CPU_TRAP */ |
44ffb95f | 91 | }; |
9e01e6d4 | 92 | |
8743690d | 93 | GdkColor drawing_colors_irq[NUM_COLORS_IRQ] = |
94 | { /* Pixel, R, G, B */ | |
95 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_IRQ_UNKNOWN */ | |
96 | { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_IRQ_IDLE */ | |
885dc404 | 97 | { 0, 0xFFFF, 0x5E00, 0x0000 }, /* COL_IRQ_BUSY */ |
8743690d | 98 | }; |
9e01e6d4 | 99 | |
0305fe77 | 100 | GdkColor drawing_colors_soft_irq[NUM_COLORS_SOFT_IRQ] = |
101 | { /* Pixel, R, G, B */ | |
102 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_SOFT_IRQ_UNKNOWN */ | |
103 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_SOFT_IRQ_IDLE */ | |
67c73bb3 | 104 | { 0, 0xFFFF, 0xD400, 0xD400 }, /* COL_SOFT_IRQ_PENDING */ |
0305fe77 | 105 | { 0, 0xFFFF, 0x9400, 0x9600 }, /* COL_SOFT_IRQ_BUSY */ |
106 | }; | |
107 | ||
38726a78 | 108 | GdkColor drawing_colors_trap[NUM_COLORS_TRAP] = |
109 | { /* Pixel, R, G, B */ | |
110 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_TRAP_UNKNOWN */ | |
a81d2a59 | 111 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_TRAP_IDLE */ |
38726a78 | 112 | { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_TRAP_BUSY */ |
113 | }; | |
114 | ||
20d16f82 | 115 | GdkColor drawing_colors_bdev[NUM_COLORS_BDEV] = |
116 | { /* Pixel, R, G, B */ | |
117 | { 0, 0x0000, 0x0000, 0x0000 }, /* COL_BDEV_UNKNOWN */ | |
118 | { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_BDEV_IDLE */ | |
119 | { 0, 0x0000, 0x0000, 0xFFFF }, /* COL_BDEV_BUSY_READING */ | |
120 | { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_BDEV_BUSY_WRITING */ | |
121 | }; | |
122 | ||
9e01e6d4 | 123 | /***************************************************************************** |
124 | * drawing functions * | |
125 | *****************************************************************************/ | |
126 | ||
127 | static gboolean | |
128 | expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ); | |
129 | ||
130 | static gboolean | |
131 | motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data); | |
132 | ||
133 | ||
134 | /* Function responsible for updating the exposed area. | |
135 | * It must do an events request to the lttvwindow API to ask for this update. | |
136 | * Note : this function cannot clear the background, because it may | |
137 | * erase drawing already present (SAFETY). | |
138 | */ | |
139 | void drawing_data_request(Drawing_t *drawing, | |
140 | gint x, gint y, | |
141 | gint width, | |
142 | gint height) | |
143 | { | |
144 | if(width < 0) return ; | |
145 | if(height < 0) return ; | |
146 | ||
147 | ||
148 | Tab *tab = drawing->control_flow_data->tab; | |
149 | TimeWindow time_window = | |
150 | lttvwindow_get_time_window(tab); | |
dd47d0d8 | 151 | LttvTraceset *traceset = lttvwindow_get_traceset(tab); |
9e01e6d4 | 152 | |
153 | ControlFlowData *control_flow_data = drawing->control_flow_data; | |
154 | // (ControlFlowData*)g_object_get_data( | |
67f72973 | 155 | // G_OBJECT(drawing->drawing_area), "resourceview_data"); |
9e01e6d4 | 156 | |
157 | LttTime start, time_end; | |
158 | LttTime window_end = time_window.end_time; | |
159 | ||
160 | g_debug("req : window start_time : %lu, %lu", time_window.start_time.tv_sec, | |
161 | time_window.start_time.tv_nsec); | |
162 | ||
163 | g_debug("req : window time width : %lu, %lu", time_window.time_width.tv_sec, | |
164 | time_window.time_width.tv_nsec); | |
165 | ||
166 | g_debug("req : window_end : %lu, %lu", window_end.tv_sec, | |
167 | window_end.tv_nsec); | |
168 | ||
169 | g_debug("x is : %i, x+width is : %i", x, x+width); | |
170 | ||
171 | convert_pixels_to_time(drawing->width, x, | |
172 | time_window, | |
173 | &start); | |
174 | ||
175 | convert_pixels_to_time(drawing->width, x+width, | |
176 | time_window, | |
177 | &time_end); | |
178 | time_end = ltt_time_add(time_end, ltt_time_one); // because main window | |
179 | // doesn't deliver end time. | |
180 | ||
181 | lttvwindow_events_request_remove_all(tab, | |
182 | control_flow_data); | |
183 | ||
184 | { | |
dd47d0d8 YB |
185 | LttvHooks *event_hook = lttv_hooks_new(); |
186 | ||
187 | lttv_hooks_add(event_hook,before_schedchange_hook , control_flow_data, LTTV_PRIO_STATE-5); | |
188 | lttv_hooks_add(event_hook,before_execmode_hook , control_flow_data, LTTV_PRIO_STATE-5); | |
189 | lttv_hooks_add(event_hook, after_schedchange_hook, control_flow_data, LTTV_PRIO_STATE+5); | |
190 | ||
26ea84eb | 191 | guint i; |
9e01e6d4 | 192 | |
8d8c5ea7 | 193 | guint nb_trace = lttv_traceset_number(traceset); |
9e01e6d4 | 194 | // FIXME (fixed) : eventually request for more traces |
195 | for(i = 0 ; i < nb_trace ; i++) { | |
9e01e6d4 | 196 | EventsRequest *events_request = g_new(EventsRequest, 1); |
197 | // Create the hooks | |
198 | //LttvHooks *event = lttv_hooks_new(); | |
dd47d0d8 | 199 | |
9e01e6d4 | 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 | ||
9e01e6d4 | 225 | // Fill the events request |
226 | events_request->owner = control_flow_data; | |
227 | events_request->viewer_data = control_flow_data; | |
228 | events_request->servicing = FALSE; | |
229 | events_request->start_time = start; | |
230 | events_request->start_position = NULL; | |
231 | events_request->stop_flag = FALSE; | |
232 | events_request->end_time = time_end; | |
233 | events_request->num_events = G_MAXUINT; | |
234 | events_request->end_position = NULL; | |
235 | events_request->trace = i; //fixed /* FIXME */ | |
236 | events_request->before_chunk_traceset = before_chunk_traceset; | |
237 | events_request->before_chunk_trace = NULL; | |
238 | events_request->before_chunk_tracefile = NULL; | |
dd47d0d8 | 239 | events_request->event = event_hook; |
9e01e6d4 | 240 | events_request->after_chunk_tracefile = NULL; |
241 | events_request->after_chunk_trace = NULL; | |
242 | events_request->after_chunk_traceset = after_chunk_traceset; | |
243 | events_request->before_request = before_request_hook; | |
244 | events_request->after_request = after_request_hook; | |
245 | ||
246 | g_debug("req : start : %lu, %lu", start.tv_sec, | |
247 | start.tv_nsec); | |
248 | ||
249 | g_debug("req : end : %lu, %lu", time_end.tv_sec, | |
250 | time_end.tv_nsec); | |
251 | ||
252 | lttvwindow_events_request(tab, events_request); | |
253 | ||
254 | } | |
9e01e6d4 | 255 | } |
9e01e6d4 | 256 | } |
257 | ||
258 | ||
259 | static void set_last_start(gpointer key, gpointer value, gpointer user_data) | |
260 | { | |
67f72973 | 261 | //ResourceInfo *process_info = (ResourceInfo*)key; |
58a9b31b | 262 | HashedResourceData *hashed_process_data = (HashedResourceData*)value; |
43ed82b5 | 263 | guint x = GPOINTER_TO_UINT(user_data); |
9e01e6d4 | 264 | |
265 | hashed_process_data->x.over = x; | |
266 | hashed_process_data->x.over_used = FALSE; | |
267 | hashed_process_data->x.over_marked = FALSE; | |
268 | hashed_process_data->x.middle = x; | |
269 | hashed_process_data->x.middle_used = FALSE; | |
270 | hashed_process_data->x.middle_marked = FALSE; | |
271 | hashed_process_data->x.under = x; | |
272 | hashed_process_data->x.under_used = FALSE; | |
273 | hashed_process_data->x.under_marked = FALSE; | |
274 | hashed_process_data->next_good_time = ltt_time_zero; | |
275 | ||
276 | return; | |
277 | } | |
278 | ||
dd47d0d8 | 279 | void drawing_data_request_begin(EventsRequest *events_request) |
9e01e6d4 | 280 | { |
67f72973 | 281 | int i; |
282 | ||
9e01e6d4 | 283 | g_debug("Begin of data request"); |
284 | ControlFlowData *cfd = events_request->viewer_data; | |
9e01e6d4 | 285 | TimeWindow time_window = |
286 | lttvwindow_get_time_window(cfd->tab); | |
287 | ||
288 | guint width = cfd->drawing->width; | |
289 | guint x=0; | |
290 | ||
291 | cfd->drawing->last_start = events_request->start_time; | |
292 | ||
293 | convert_time_to_pixels( | |
294 | time_window, | |
295 | events_request->start_time, | |
296 | width, | |
297 | &x); | |
298 | ||
67f72973 | 299 | for(i=0; i<RV_RESOURCE_COUNT; i++) { |
300 | g_hash_table_foreach(cfd->process_list->restypes[i].hash_table, set_last_start, | |
43ed82b5 | 301 | GUINT_TO_POINTER(x)); |
67f72973 | 302 | } |
9e01e6d4 | 303 | |
304 | } | |
305 | ||
dd47d0d8 | 306 | void drawing_chunk_begin(EventsRequest *events_request, LttvTraceset *ts) |
9e01e6d4 | 307 | { |
308 | g_debug("Begin of chunk"); | |
309 | ControlFlowData *cfd = events_request->viewer_data; | |
9e01e6d4 | 310 | guint i; |
dd47d0d8 | 311 | guint nb_trace = lttv_traceset_number(ts); |
9e01e6d4 | 312 | |
313 | if(!cfd->process_list->current_hash_data) { | |
58a9b31b | 314 | cfd->process_list->current_hash_data = g_new(HashedResourceData**,nb_trace); |
9e01e6d4 | 315 | for(i = 0 ; i < nb_trace ; i++) { |
dd47d0d8 | 316 | guint num_cpu = lttv_trace_get_num_cpu(lttv_traceset_get(ts, i)); |
58a9b31b | 317 | cfd->process_list->current_hash_data[i] = g_new(HashedResourceData*,num_cpu); |
9e01e6d4 | 318 | memset(cfd->process_list->current_hash_data[i], 0, |
58a9b31b | 319 | sizeof(HashedResourceData*)*num_cpu); |
9e01e6d4 | 320 | } |
321 | } | |
322 | //cfd->drawing->last_start = LTT_TIME_MIN(current_time, | |
323 | // events_request->end_time); | |
324 | } | |
325 | ||
326 | ||
327 | void drawing_request_expose(EventsRequest *events_request, | |
9e01e6d4 | 328 | LttTime end_time) |
329 | { | |
330 | gint x, width; | |
331 | guint x_end; | |
332 | ||
333 | ControlFlowData *cfd = events_request->viewer_data; | |
9e01e6d4 | 334 | Drawing_t *drawing = cfd->drawing; |
335 | ||
336 | TimeWindow time_window = | |
337 | lttvwindow_get_time_window(cfd->tab); | |
338 | ||
339 | g_debug("request expose"); | |
340 | ||
341 | convert_time_to_pixels( | |
342 | time_window, | |
343 | end_time, | |
344 | drawing->width, | |
345 | &x_end); | |
346 | x = drawing->damage_begin; | |
347 | ||
348 | width = x_end - x; | |
349 | ||
350 | drawing->damage_begin = x+width; | |
351 | ||
352 | // FIXME ? | |
353 | gtk_widget_queue_draw_area ( drawing->drawing_area, | |
354 | x, 0, | |
355 | width, drawing->drawing_area->allocation.height); | |
356 | ||
357 | /* Update directly when scrolling */ | |
358 | gdk_window_process_updates(drawing->drawing_area->window, | |
359 | TRUE); | |
360 | } | |
361 | ||
362 | ||
363 | /* Callbacks */ | |
364 | ||
365 | ||
366 | /* Create a new backing pixmap of the appropriate size */ | |
367 | /* As the scaling will always change, it's of no use to copy old | |
368 | * pixmap. | |
369 | * | |
370 | * Only change the size if width changes. The height is specified and changed | |
371 | * when process ID are added or removed from the process list. | |
372 | */ | |
373 | static gboolean | |
374 | configure_event( GtkWidget *widget, GdkEventConfigure *event, | |
375 | gpointer user_data) | |
376 | { | |
377 | Drawing_t *drawing = (Drawing_t*)user_data; | |
378 | ||
379 | ||
380 | /* First, get the new time interval of the main window */ | |
381 | /* we assume (see documentation) that the main window | |
382 | * has updated the time interval before this configure gets | |
383 | * executed. | |
384 | */ | |
385 | //lttvwindow_get_time_window(drawing->control_flow_data->mw, | |
386 | // &drawing->control_flow_data->time_window); | |
387 | ||
388 | /* New pixmap, size of the configure event */ | |
389 | //GdkPixmap *pixmap = gdk_pixmap_new(widget->window, | |
390 | // widget->allocation.width + SAFETY, | |
391 | // widget->allocation.height + SAFETY, | |
392 | // -1); | |
393 | ||
394 | if(widget->allocation.width != drawing->width) { | |
395 | g_debug("drawing configure event"); | |
396 | g_debug("New alloc draw size : %i by %i",widget->allocation.width, | |
397 | widget->allocation.height); | |
398 | ||
399 | drawing->width = widget->allocation.width; | |
400 | ||
401 | if(drawing->alloc_width < widget->allocation.width) { | |
402 | //if(drawing->pixmap) | |
403 | // gdk_pixmap_unref(drawing->pixmap); | |
404 | ||
405 | //drawing->pixmap = gdk_pixmap_new(widget->window, | |
406 | // drawing->width + SAFETY + EXTRA_ALLOC, | |
407 | // drawing->height + EXTRA_ALLOC, | |
408 | // -1); | |
409 | drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC; | |
410 | drawing->alloc_height = drawing->height + EXTRA_ALLOC; | |
411 | update_pixmap_size(drawing->control_flow_data->process_list, | |
412 | drawing->alloc_width); | |
413 | update_index_to_pixmap(drawing->control_flow_data->process_list); | |
414 | } | |
415 | //drawing->height = widget->allocation.height; | |
416 | ||
417 | //ProcessList_get_height | |
418 | // (GuiControlFlow_get_process_list(drawing->control_flow_data)), | |
419 | ||
420 | ||
421 | // Clear the image | |
422 | //gdk_draw_rectangle (drawing->pixmap, | |
423 | // widget->style->black_gc, | |
424 | // TRUE, | |
425 | // 0, 0, | |
426 | // drawing->width+SAFETY, | |
427 | // drawing->height); | |
428 | ||
429 | //g_info("init data request"); | |
430 | ||
431 | ||
432 | /* Initial data request */ | |
433 | /* no, do initial data request in the expose event */ | |
434 | // Do not need to ask for data of 1 pixel : not synchronized with | |
435 | // main window time at this moment. | |
436 | //drawing_data_request(drawing, &drawing->pixmap, 0, 0, | |
437 | // widget->allocation.width, | |
438 | // widget->allocation.height); | |
439 | ||
440 | //drawing->width = widget->allocation.width; | |
441 | //drawing->height = widget->allocation.height; | |
442 | ||
443 | drawing->damage_begin = 0; | |
444 | drawing->damage_end = widget->allocation.width; | |
445 | ||
446 | if((widget->allocation.width != 1 && | |
447 | widget->allocation.height != 1) | |
448 | && drawing->damage_begin < drawing->damage_end) | |
449 | { | |
450 | ||
451 | rectangle_pixmap (drawing->control_flow_data->process_list, | |
452 | drawing->drawing_area->style->black_gc, | |
453 | TRUE, | |
454 | 0, 0, | |
455 | drawing->alloc_width, // do not overlap | |
456 | -1); | |
457 | ||
458 | ||
459 | drawing_data_request(drawing, | |
460 | drawing->damage_begin, | |
461 | 0, | |
462 | drawing->damage_end - drawing->damage_begin, | |
463 | drawing->height); | |
464 | } | |
465 | } | |
466 | return TRUE; | |
467 | } | |
468 | ||
469 | ||
470 | /* Redraw the screen from the backing pixmap */ | |
471 | static gboolean | |
472 | expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) | |
473 | { | |
474 | Drawing_t *drawing = (Drawing_t*)user_data; | |
475 | ||
476 | ControlFlowData *control_flow_data = | |
477 | (ControlFlowData*)g_object_get_data( | |
478 | G_OBJECT(widget), | |
67f72973 | 479 | "resourceview_data"); |
9e01e6d4 | 480 | #if 0 |
481 | if(unlikely(drawing->gc == NULL)) { | |
482 | drawing->gc = gdk_gc_new(drawing->drawing_area->window); | |
483 | gdk_gc_copy(drawing->gc, drawing->drawing_area->style->black_gc); | |
484 | } | |
485 | #endif //0 | |
486 | TimeWindow time_window = | |
487 | lttvwindow_get_time_window(control_flow_data->tab); | |
488 | LttTime current_time = | |
489 | lttvwindow_get_current_time(control_flow_data->tab); | |
490 | ||
491 | guint cursor_x=0; | |
492 | ||
493 | LttTime window_end = time_window.end_time; | |
494 | ||
495 | /* update the screen from the pixmap buffer */ | |
496 | #if 0 | |
497 | gdk_draw_pixmap(widget->window, | |
498 | widget->style->fg_gc[GTK_WIDGET_STATE (widget)], | |
499 | drawing->pixmap, | |
500 | event->area.x, event->area.y, | |
501 | event->area.x, event->area.y, | |
502 | event->area.width, event->area.height); | |
503 | #endif //0 | |
504 | drawing->height = processlist_get_height(control_flow_data->process_list); | |
505 | #if 0 | |
506 | copy_pixmap_to_screen(control_flow_data->process_list, | |
507 | widget->window, | |
508 | widget->style->fg_gc[GTK_WIDGET_STATE (widget)], | |
509 | event->area.x, event->area.y, | |
510 | event->area.width, event->area.height); | |
511 | #endif //0 | |
512 | copy_pixmap_to_screen(control_flow_data->process_list, | |
513 | widget->window, | |
514 | drawing->gc, | |
515 | event->area.x, event->area.y, | |
516 | event->area.width, event->area.height); | |
517 | ||
518 | ||
519 | /* Erase the dotted lines left.. */ | |
520 | if(widget->allocation.height > drawing->height) | |
521 | { | |
522 | gdk_draw_rectangle (widget->window, | |
523 | drawing->drawing_area->style->black_gc, | |
524 | TRUE, | |
525 | event->area.x, drawing->height, | |
526 | event->area.width, // do not overlap | |
527 | widget->allocation.height - drawing->height); | |
528 | } | |
529 | if(ltt_time_compare(time_window.start_time, current_time) <= 0 && | |
530 | ltt_time_compare(window_end, current_time) >= 0) | |
531 | { | |
532 | /* Draw the dotted lines */ | |
533 | convert_time_to_pixels( | |
534 | time_window, | |
535 | current_time, | |
536 | drawing->width, | |
537 | &cursor_x); | |
538 | ||
539 | #if 0 | |
540 | if(drawing->dotted_gc == NULL) { | |
541 | ||
542 | drawing->dotted_gc = gdk_gc_new(drawing->drawing_area->window); | |
543 | gdk_gc_copy(drawing->dotted_gc, widget->style->white_gc); | |
544 | ||
545 | gint8 dash_list[] = { 1, 2 }; | |
546 | gdk_gc_set_line_attributes(drawing->dotted_gc, | |
547 | 1, | |
548 | GDK_LINE_ON_OFF_DASH, | |
549 | GDK_CAP_BUTT, | |
550 | GDK_JOIN_MITER); | |
551 | gdk_gc_set_dashes(drawing->dotted_gc, | |
552 | 0, | |
553 | dash_list, | |
554 | 2); | |
555 | } | |
556 | #endif //0 | |
557 | gint height_tot = MAX(widget->allocation.height, drawing->height); | |
558 | gdk_draw_line(widget->window, | |
559 | drawing->dotted_gc, | |
560 | cursor_x, 0, | |
561 | cursor_x, height_tot); | |
562 | } | |
563 | return FALSE; | |
564 | } | |
565 | ||
566 | static gboolean | |
567 | after_expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) | |
568 | { | |
569 | //g_assert(0); | |
570 | g_debug("AFTER EXPOSE"); | |
571 | ||
572 | return FALSE; | |
573 | ||
574 | ||
575 | } | |
576 | ||
577 | #if 0 | |
578 | void | |
579 | tree_row_activated(GtkTreeModel *treemodel, | |
580 | GtkTreePath *arg1, | |
581 | GtkTreeViewColumn *arg2, | |
582 | gpointer user_data) | |
583 | { | |
584 | ControlFlowData *cfd = (ControlFlowData*)user_data; | |
585 | Drawing_t *drawing = cfd->drawing; | |
586 | GtkTreeView *treeview = cfd->process_list->process_list_widget; | |
587 | gint *path_indices; | |
588 | gint height; | |
589 | ||
590 | path_indices = gtk_tree_path_get_indices (arg1); | |
591 | ||
592 | height = get_cell_height(cfd->process_list, | |
593 | GTK_TREE_VIEW(treeview)); | |
594 | drawing->horizontal_sel = height * path_indices[0]; | |
595 | g_critical("new hor sel : %i", drawing->horizontal_sel); | |
596 | } | |
597 | #endif //0 | |
598 | ||
599 | /* mouse click */ | |
600 | static gboolean | |
601 | button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data ) | |
602 | { | |
603 | ControlFlowData *control_flow_data = | |
604 | (ControlFlowData*)g_object_get_data( | |
605 | G_OBJECT(widget), | |
67f72973 | 606 | "resourceview_data"); |
9e01e6d4 | 607 | Drawing_t *drawing = control_flow_data->drawing; |
608 | TimeWindow time_window = | |
609 | lttvwindow_get_time_window(control_flow_data->tab); | |
610 | ||
611 | g_debug("click"); | |
612 | if(event->button == 1) | |
613 | { | |
614 | LttTime time; | |
615 | ||
616 | /* left mouse button click */ | |
617 | g_debug("x click is : %f", event->x); | |
618 | ||
619 | convert_pixels_to_time(drawing->width, (guint)event->x, | |
620 | time_window, | |
621 | &time); | |
622 | ||
623 | lttvwindow_report_current_time(control_flow_data->tab, time); | |
624 | ||
625 | } | |
626 | ||
627 | return FALSE; | |
628 | } | |
629 | ||
630 | static gboolean | |
631 | scrollbar_size_allocate(GtkWidget *widget, | |
632 | GtkAllocation *allocation, | |
633 | gpointer user_data) | |
634 | { | |
635 | Drawing_t *drawing = (Drawing_t*)user_data; | |
636 | ||
637 | gtk_widget_set_size_request(drawing->padding, allocation->width, -1); | |
638 | //gtk_widget_queue_resize(drawing->padding); | |
639 | //gtk_widget_queue_resize(drawing->ruler); | |
640 | gtk_container_check_resize(GTK_CONTAINER(drawing->ruler_hbox)); | |
641 | return 0; | |
642 | } | |
643 | ||
644 | ||
645 | ||
646 | Drawing_t *drawing_construct(ControlFlowData *control_flow_data) | |
647 | { | |
648 | Drawing_t *drawing = g_new(Drawing_t, 1); | |
649 | ||
650 | drawing->control_flow_data = control_flow_data; | |
651 | ||
652 | drawing->vbox = gtk_vbox_new(FALSE, 1); | |
653 | ||
654 | ||
655 | drawing->ruler_hbox = gtk_hbox_new(FALSE, 1); | |
656 | drawing->ruler = gtk_drawing_area_new (); | |
657 | //gtk_widget_set_size_request(drawing->ruler, -1, 27); | |
658 | ||
659 | drawing->padding = gtk_drawing_area_new (); | |
660 | //gtk_widget_set_size_request(drawing->padding, -1, 27); | |
661 | gtk_box_pack_start(GTK_BOX(drawing->ruler_hbox), drawing->ruler, | |
662 | TRUE, TRUE, 0); | |
663 | gtk_box_pack_end(GTK_BOX(drawing->ruler_hbox), drawing->padding, | |
664 | FALSE, FALSE, 0); | |
665 | ||
666 | ||
667 | ||
668 | drawing->drawing_area = gtk_drawing_area_new (); | |
669 | ||
670 | drawing->gc = NULL; | |
671 | ||
672 | drawing->hbox = gtk_hbox_new(FALSE, 1); | |
673 | drawing->viewport = gtk_viewport_new(NULL, control_flow_data->v_adjust); | |
674 | drawing->scrollbar = gtk_vscrollbar_new(control_flow_data->v_adjust); | |
675 | gtk_box_pack_start(GTK_BOX(drawing->hbox), drawing->viewport, | |
676 | TRUE, TRUE, 0); | |
677 | gtk_box_pack_end(GTK_BOX(drawing->hbox), drawing->scrollbar, | |
678 | FALSE, FALSE, 0); | |
679 | ||
680 | //drawing->scrolled_window = | |
681 | // gtk_scrolled_window_new (NULL, | |
682 | // control_flow_data->v_adjust); | |
683 | ||
684 | //gtk_scrolled_window_set_policy( | |
685 | // GTK_SCROLLED_WINDOW(drawing->scrolled_window), | |
686 | // GTK_POLICY_NEVER, | |
687 | // GTK_POLICY_AUTOMATIC); | |
688 | ||
689 | gtk_container_add(GTK_CONTAINER(drawing->viewport), | |
690 | drawing->drawing_area); | |
691 | //gtk_scrolled_window_add_with_viewport( | |
692 | // GTK_SCROLLED_WINDOW(drawing->scrolled_window), | |
693 | // drawing->drawing_area); | |
694 | ||
695 | gtk_box_pack_start(GTK_BOX(drawing->vbox), drawing->ruler_hbox, | |
696 | FALSE, FALSE, 0); | |
697 | gtk_box_pack_end(GTK_BOX(drawing->vbox), drawing->hbox, | |
698 | TRUE, TRUE, 0); | |
699 | ||
700 | drawing->pango_layout = | |
701 | gtk_widget_create_pango_layout(drawing->drawing_area, NULL); | |
702 | ||
703 | drawing->height = 1; | |
704 | drawing->width = 1; | |
705 | drawing->depth = 0; | |
706 | drawing->alloc_height = 1; | |
707 | drawing->alloc_width = 1; | |
708 | ||
709 | drawing->damage_begin = 0; | |
710 | drawing->damage_end = 0; | |
711 | drawing->horizontal_sel = -1; | |
712 | ||
713 | //gtk_widget_set_size_request(drawing->drawing_area->window, 50, 50); | |
714 | g_object_set_data_full( | |
715 | G_OBJECT(drawing->drawing_area), | |
716 | "Link_drawing_Data", | |
717 | drawing, | |
718 | (GDestroyNotify)drawing_destroy); | |
719 | ||
720 | g_object_set_data( | |
721 | G_OBJECT(drawing->ruler), | |
722 | "drawing", | |
723 | drawing); | |
724 | ||
725 | ||
726 | //gtk_widget_modify_bg( drawing->drawing_area, | |
727 | // GTK_STATE_NORMAL, | |
728 | // &CF_Colors[BLACK]); | |
729 | ||
730 | //gdk_window_get_geometry(drawing->drawing_area->window, | |
731 | // NULL, NULL, | |
732 | // &(drawing->width), | |
733 | // &(drawing->height), | |
734 | // -1); | |
735 | ||
736 | //drawing->pixmap = gdk_pixmap_new( | |
737 | // drawing->drawing_area->window, | |
738 | // drawing->width, | |
739 | // drawing->height, | |
740 | // drawing->depth); | |
741 | ||
742 | //drawing->pixmap = NULL; | |
743 | ||
744 | // drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window, | |
745 | // drawing->drawing_area->allocation.width, | |
746 | // drawing->drawing_area->allocation.height, | |
747 | // -1); | |
748 | ||
749 | g_signal_connect (G_OBJECT(drawing->drawing_area), | |
750 | "configure_event", | |
751 | G_CALLBACK (configure_event), | |
752 | (gpointer)drawing); | |
753 | ||
754 | g_signal_connect (G_OBJECT(drawing->ruler), | |
755 | "expose_event", | |
756 | G_CALLBACK(expose_ruler), | |
757 | (gpointer)drawing); | |
758 | ||
759 | gtk_widget_add_events(drawing->ruler, GDK_POINTER_MOTION_MASK); | |
760 | ||
761 | g_signal_connect (G_OBJECT(drawing->ruler), | |
762 | "motion-notify-event", | |
763 | G_CALLBACK(motion_notify_ruler), | |
764 | (gpointer)drawing); | |
765 | ||
766 | ||
767 | g_signal_connect (G_OBJECT(drawing->scrollbar), | |
768 | "size-allocate", | |
769 | G_CALLBACK(scrollbar_size_allocate), | |
770 | (gpointer)drawing); | |
771 | ||
772 | ||
773 | ||
774 | g_signal_connect (G_OBJECT(drawing->drawing_area), | |
775 | "expose_event", | |
776 | G_CALLBACK (expose_event), | |
777 | (gpointer)drawing); | |
778 | ||
779 | g_signal_connect_after (G_OBJECT(drawing->drawing_area), | |
780 | "expose_event", | |
781 | G_CALLBACK (after_expose_event), | |
782 | (gpointer)drawing); | |
783 | ||
784 | g_signal_connect (G_OBJECT(drawing->drawing_area), | |
785 | "button-press-event", | |
786 | G_CALLBACK (button_press_event), | |
787 | (gpointer)drawing); | |
788 | ||
789 | ||
790 | gtk_widget_show(drawing->ruler); | |
791 | gtk_widget_show(drawing->padding); | |
792 | gtk_widget_show(drawing->ruler_hbox); | |
793 | ||
794 | gtk_widget_show(drawing->drawing_area); | |
795 | //gtk_widget_show(drawing->scrolled_window); | |
796 | gtk_widget_show(drawing->viewport); | |
797 | gtk_widget_show(drawing->scrollbar); | |
798 | gtk_widget_show(drawing->hbox); | |
799 | ||
800 | /* Allocate the colors */ | |
801 | GdkColormap* colormap = gdk_colormap_get_system(); | |
802 | gboolean success[NUM_COLORS]; | |
d3d99fde | 803 | gdk_colormap_alloc_colors(colormap, drawing_colors, NUM_COLORS, FALSE, |
804 | TRUE, success); | |
44ffb95f | 805 | gdk_colormap_alloc_colors(colormap, drawing_colors_cpu, NUM_COLORS_CPU, FALSE, |
9e01e6d4 | 806 | TRUE, success); |
885dc404 | 807 | gdk_colormap_alloc_colors(colormap, drawing_colors_irq, NUM_COLORS_IRQ, FALSE, |
808 | TRUE, success); | |
2410d45e | 809 | gdk_colormap_alloc_colors(colormap, drawing_colors_soft_irq, NUM_COLORS_SOFT_IRQ, FALSE, |
0305fe77 | 810 | TRUE, success); |
38726a78 | 811 | gdk_colormap_alloc_colors(colormap, drawing_colors_trap, NUM_COLORS_TRAP, FALSE, |
812 | TRUE, success); | |
20d16f82 | 813 | gdk_colormap_alloc_colors(colormap, drawing_colors_bdev, NUM_COLORS_BDEV, FALSE, |
814 | TRUE, success); | |
9e01e6d4 | 815 | |
816 | drawing->gc = | |
817 | gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window)); | |
818 | drawing->dotted_gc = | |
819 | gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window)); | |
820 | ||
821 | gdk_gc_copy(drawing->gc, | |
822 | main_window_get_widget(control_flow_data->tab)->style->black_gc); | |
823 | gdk_gc_copy(drawing->dotted_gc, | |
824 | main_window_get_widget(control_flow_data->tab)->style->white_gc); | |
825 | ||
826 | gint8 dash_list[] = { 1, 2 }; | |
827 | gdk_gc_set_line_attributes(drawing->dotted_gc, | |
828 | 1, | |
829 | GDK_LINE_ON_OFF_DASH, | |
830 | GDK_CAP_BUTT, | |
831 | GDK_JOIN_MITER); | |
832 | gdk_gc_set_dashes(drawing->dotted_gc, | |
833 | 0, | |
834 | dash_list, | |
835 | 2); | |
836 | ||
837 | drawing->ruler_gc_butt = | |
838 | gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window)); | |
839 | gdk_gc_copy(drawing->ruler_gc_butt, | |
840 | main_window_get_widget(control_flow_data->tab)->style->black_gc); | |
841 | drawing->ruler_gc_round = | |
842 | gdk_gc_new(GDK_DRAWABLE(main_window_get_widget(control_flow_data->tab)->window)); | |
843 | gdk_gc_copy(drawing->ruler_gc_round, | |
844 | main_window_get_widget(control_flow_data->tab)->style->black_gc); | |
845 | ||
846 | ||
847 | gdk_gc_set_line_attributes(drawing->ruler_gc_butt, | |
848 | 2, | |
849 | GDK_LINE_SOLID, | |
850 | GDK_CAP_BUTT, | |
851 | GDK_JOIN_MITER); | |
852 | ||
853 | gdk_gc_set_line_attributes(drawing->ruler_gc_round, | |
854 | 2, | |
855 | GDK_LINE_SOLID, | |
856 | GDK_CAP_ROUND, | |
857 | GDK_JOIN_ROUND); | |
858 | ||
859 | ||
860 | return drawing; | |
861 | } | |
862 | ||
863 | void drawing_destroy(Drawing_t *drawing) | |
864 | { | |
865 | g_info("drawing_destroy %p", drawing); | |
866 | ||
867 | /* Free the colors */ | |
868 | GdkColormap* colormap = gdk_colormap_get_system(); | |
869 | ||
d3d99fde | 870 | gdk_colormap_free_colors(colormap, drawing_colors, NUM_COLORS); |
44ffb95f | 871 | gdk_colormap_free_colors(colormap, drawing_colors_cpu, NUM_COLORS_CPU); |
8743690d | 872 | gdk_colormap_free_colors(colormap, drawing_colors_irq, NUM_COLORS_IRQ); |
0305fe77 | 873 | gdk_colormap_free_colors(colormap, drawing_colors_soft_irq, NUM_COLORS_IRQ); |
38726a78 | 874 | gdk_colormap_free_colors(colormap, drawing_colors_trap, NUM_COLORS_TRAP); |
20d16f82 | 875 | gdk_colormap_free_colors(colormap, drawing_colors_bdev, NUM_COLORS_BDEV); |
9e01e6d4 | 876 | |
877 | // Do not unref here, Drawing_t destroyed by it's widget. | |
878 | //g_object_unref( G_OBJECT(drawing->drawing_area)); | |
879 | if(drawing->gc != NULL) | |
880 | gdk_gc_unref(drawing->gc); | |
881 | ||
882 | g_object_unref(drawing->pango_layout); | |
883 | if(drawing->dotted_gc != NULL) gdk_gc_unref(drawing->dotted_gc); | |
884 | if(drawing->ruler_gc_butt != NULL) gdk_gc_unref(drawing->ruler_gc_butt); | |
885 | if(drawing->ruler_gc_round != NULL) gdk_gc_unref(drawing->ruler_gc_round); | |
886 | ||
887 | g_free(drawing); | |
888 | g_info("drawing_destroy end"); | |
889 | } | |
890 | ||
891 | GtkWidget *drawing_get_drawing_area(Drawing_t *drawing) | |
892 | { | |
893 | return drawing->drawing_area; | |
894 | } | |
895 | ||
896 | GtkWidget *drawing_get_widget(Drawing_t *drawing) | |
897 | { | |
898 | return drawing->vbox; | |
899 | } | |
900 | ||
901 | void drawing_draw_line( Drawing_t *drawing, | |
902 | GdkPixmap *pixmap, | |
903 | guint x1, guint y1, | |
904 | guint x2, guint y2, | |
905 | GdkGC *GC) | |
906 | { | |
907 | gdk_draw_line (pixmap, | |
908 | GC, | |
909 | x1, y1, x2, y2); | |
910 | } | |
911 | ||
912 | void drawing_clear(Drawing_t *drawing) | |
913 | { | |
914 | //if (drawing->pixmap) | |
915 | // gdk_pixmap_unref(drawing->pixmap); | |
916 | ControlFlowData *cfd = drawing->control_flow_data; | |
917 | ||
918 | ||
919 | rectangle_pixmap(cfd->process_list, | |
920 | drawing->drawing_area->style->black_gc, | |
921 | TRUE, | |
922 | 0, 0, | |
923 | drawing->alloc_width, // do not overlap | |
924 | -1); | |
925 | ||
926 | //drawing->height = 1; | |
927 | /* Allocate a new pixmap with new height */ | |
928 | //drawing->pixmap = gdk_pixmap_new(drawing->drawing_area->window, | |
929 | // drawing->width + SAFETY + EXTRA_ALLOC, | |
930 | // drawing->height + EXTRA_ALLOC, | |
931 | // -1); | |
932 | //drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC; | |
933 | //drawing->alloc_height = drawing->height + EXTRA_ALLOC; | |
934 | ||
935 | //gtk_widget_set_size_request(drawing->drawing_area, | |
936 | // -1, | |
937 | // drawing->height); | |
938 | //gtk_widget_queue_resize_no_redraw(drawing->drawing_area); | |
939 | ||
940 | /* ask for the buffer to be redrawn */ | |
941 | gtk_widget_queue_draw ( drawing->drawing_area); | |
942 | } | |
943 | ||
944 | #if 0 | |
945 | /* Insert a square corresponding to a new process in the list */ | |
946 | /* Applies to whole drawing->width */ | |
947 | void drawing_insert_square(Drawing_t *drawing, | |
948 | guint y, | |
949 | guint height) | |
950 | { | |
951 | //GdkRectangle update_rect; | |
952 | gboolean reallocate = FALSE; | |
953 | GdkPixmap *new_pixmap; | |
954 | ||
955 | /* Allocate a new pixmap with new height */ | |
956 | if(drawing->alloc_height < drawing->height + height) { | |
957 | ||
958 | new_pixmap = gdk_pixmap_new(drawing->drawing_area->window, | |
959 | drawing->width + SAFETY + EXTRA_ALLOC, | |
960 | drawing->height + height + EXTRA_ALLOC, | |
961 | -1); | |
962 | drawing->alloc_width = drawing->width + SAFETY + EXTRA_ALLOC; | |
963 | drawing->alloc_height = drawing->height + height + EXTRA_ALLOC; | |
964 | reallocate = TRUE; | |
965 | ||
966 | /* Copy the high region */ | |
967 | gdk_draw_pixmap (new_pixmap, | |
968 | drawing->drawing_area->style->black_gc, | |
969 | drawing->pixmap, | |
970 | 0, 0, | |
971 | 0, 0, | |
972 | drawing->width + SAFETY, y); | |
973 | ||
974 | } else { | |
975 | new_pixmap = drawing->pixmap; | |
976 | } | |
977 | ||
978 | //GdkPixmap *pixmap = gdk_pixmap_new(drawing->drawing_area->window, | |
979 | // drawing->width + SAFETY, | |
980 | // drawing->height + height, | |
981 | // -1); | |
982 | ||
983 | /* add an empty square */ | |
984 | gdk_draw_rectangle (new_pixmap, | |
985 | drawing->drawing_area->style->black_gc, | |
986 | TRUE, | |
987 | 0, y, | |
988 | drawing->width + SAFETY, // do not overlap | |
989 | height); | |
990 | ||
991 | /* copy the bottom of the region */ | |
992 | gdk_draw_pixmap (new_pixmap, | |
993 | drawing->drawing_area->style->black_gc, | |
994 | drawing->pixmap, | |
995 | 0, y, | |
996 | 0, y + height, | |
997 | drawing->width+SAFETY, drawing->height - y); | |
998 | ||
999 | ||
1000 | if(reallocate && likely(drawing->pixmap)) { | |
1001 | gdk_pixmap_unref(drawing->pixmap); | |
1002 | drawing->pixmap = new_pixmap; | |
1003 | } | |
1004 | ||
1005 | if(unlikely(drawing->height==1)) drawing->height = height; | |
1006 | else drawing->height += height; | |
1007 | ||
1008 | gtk_widget_set_size_request(drawing->drawing_area, | |
1009 | -1, | |
1010 | drawing->height); | |
1011 | gtk_widget_queue_resize_no_redraw(drawing->drawing_area); | |
1012 | ||
1013 | /* ask for the buffer to be redrawn */ | |
1014 | gtk_widget_queue_draw_area ( drawing->drawing_area, | |
1015 | 0, y, | |
1016 | drawing->width, drawing->height-y); | |
1017 | } | |
1018 | ||
1019 | ||
1020 | /* Remove a square corresponding to a removed process in the list */ | |
1021 | void drawing_remove_square(Drawing_t *drawing, | |
1022 | guint y, | |
1023 | guint height) | |
1024 | { | |
1025 | GdkPixmap *pixmap; | |
1026 | ||
1027 | if(unlikely((guint)drawing->height == height)) { | |
1028 | //pixmap = gdk_pixmap_new( | |
1029 | // drawing->drawing_area->window, | |
1030 | // drawing->width + SAFETY, | |
1031 | // 1, | |
1032 | // -1); | |
1033 | pixmap = drawing->pixmap; | |
1034 | drawing->height=1; | |
1035 | } else { | |
1036 | /* Allocate a new pixmap with new height */ | |
1037 | //pixmap = gdk_pixmap_new( | |
1038 | // drawing->drawing_area->window, | |
1039 | // drawing->width + SAFETY, | |
1040 | // drawing->height - height, | |
1041 | // -1); | |
1042 | /* Keep the same preallocated pixmap */ | |
1043 | pixmap = drawing->pixmap; | |
1044 | ||
1045 | /* Copy the high region */ | |
1046 | gdk_draw_pixmap (pixmap, | |
1047 | drawing->drawing_area->style->black_gc, | |
1048 | drawing->pixmap, | |
1049 | 0, 0, | |
1050 | 0, 0, | |
1051 | drawing->width + SAFETY, y); | |
1052 | ||
1053 | /* Copy up the bottom of the region */ | |
1054 | gdk_draw_pixmap (pixmap, | |
1055 | drawing->drawing_area->style->black_gc, | |
1056 | drawing->pixmap, | |
1057 | 0, y + height, | |
1058 | 0, y, | |
1059 | drawing->width, drawing->height - y - height); | |
1060 | ||
1061 | drawing->height-=height; | |
1062 | } | |
1063 | ||
1064 | //if(likely(drawing->pixmap)) | |
1065 | // gdk_pixmap_unref(drawing->pixmap); | |
1066 | ||
1067 | //drawing->pixmap = pixmap; | |
1068 | ||
1069 | gtk_widget_set_size_request(drawing->drawing_area, | |
1070 | -1, | |
1071 | drawing->height); | |
1072 | gtk_widget_queue_resize_no_redraw(drawing->drawing_area); | |
1073 | /* ask for the buffer to be redrawn */ | |
1074 | gtk_widget_queue_draw_area ( drawing->drawing_area, | |
1075 | 0, y, | |
1076 | drawing->width, MAX(drawing->height-y, 1)); | |
1077 | } | |
1078 | #endif //0 | |
1079 | ||
1080 | void drawing_update_ruler(Drawing_t *drawing, TimeWindow *time_window) | |
1081 | { | |
9e01e6d4 | 1082 | gtk_widget_queue_draw(drawing->ruler); |
9e01e6d4 | 1083 | } |
1084 | ||
1085 | /* Redraw the ruler */ | |
1086 | static gboolean | |
1087 | expose_ruler( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) | |
1088 | { | |
1089 | Drawing_t *drawing = (Drawing_t*)user_data; | |
1090 | TimeWindow time_window = lttvwindow_get_time_window(drawing->control_flow_data->tab); | |
1091 | gchar text[255]; | |
1092 | ||
1093 | PangoContext *context; | |
1094 | PangoLayout *layout; | |
1095 | PangoFontDescription *FontDesc; | |
1096 | PangoRectangle ink_rect; | |
1097 | gint global_width=0; | |
1098 | GdkColor foreground = { 0, 0, 0, 0 }; | |
1099 | GdkColor background = { 0, 0xffff, 0xffff, 0xffff }; | |
1100 | ||
1101 | LttTime window_end = time_window.end_time; | |
1102 | LttTime half_width = | |
1103 | ltt_time_div(time_window.time_width,2.0); | |
1104 | LttTime window_middle = | |
1105 | ltt_time_add(half_width, | |
1106 | time_window.start_time); | |
1107 | g_debug("ruler expose event"); | |
1108 | ||
1109 | gdk_draw_rectangle (drawing->ruler->window, | |
1110 | drawing->ruler->style->white_gc, | |
1111 | TRUE, | |
1112 | event->area.x, event->area.y, | |
1113 | event->area.width, | |
1114 | event->area.height); | |
1115 | ||
1116 | gdk_draw_line (drawing->ruler->window, | |
1117 | drawing->ruler_gc_butt, | |
1118 | event->area.x, 1, | |
1119 | event->area.x + event->area.width, 1); | |
1120 | ||
1121 | ||
1122 | snprintf(text, 255, "%lus\n%luns", | |
1123 | time_window.start_time.tv_sec, | |
1124 | time_window.start_time.tv_nsec); | |
1125 | ||
1126 | layout = gtk_widget_create_pango_layout(drawing->drawing_area, NULL); | |
1127 | ||
1128 | context = pango_layout_get_context(layout); | |
1129 | FontDesc = pango_context_get_font_description(context); | |
1130 | ||
1131 | pango_font_description_set_size(FontDesc, 6*PANGO_SCALE); | |
1132 | pango_layout_context_changed(layout); | |
1133 | ||
1134 | pango_layout_set_text(layout, text, -1); | |
1135 | pango_layout_get_pixel_extents(layout, &ink_rect, NULL); | |
1136 | global_width += ink_rect.width; | |
1137 | ||
1138 | gdk_draw_layout_with_colors(drawing->ruler->window, | |
1139 | drawing->ruler_gc_butt, | |
1140 | 0, | |
1141 | 6, | |
1142 | layout, &foreground, &background); | |
1143 | ||
1144 | gdk_draw_line (drawing->ruler->window, | |
1145 | drawing->ruler_gc_round, | |
1146 | 1, 1, | |
1147 | 1, 7); | |
1148 | ||
1149 | ||
1150 | snprintf(text, 255, "%lus\n%luns", window_end.tv_sec, | |
1151 | window_end.tv_nsec); | |
1152 | ||
1153 | pango_layout_set_text(layout, text, -1); | |
1154 | pango_layout_get_pixel_extents(layout, &ink_rect, NULL); | |
1155 | global_width += ink_rect.width; | |
1156 | ||
1157 | if(global_width <= drawing->ruler->allocation.width) | |
1158 | { | |
1159 | gdk_draw_layout_with_colors(drawing->ruler->window, | |
1160 | drawing->ruler_gc_butt, | |
1161 | drawing->ruler->allocation.width - ink_rect.width, | |
1162 | 6, | |
1163 | layout, &foreground, &background); | |
1164 | ||
1165 | gdk_draw_line (drawing->ruler->window, | |
1166 | drawing->ruler_gc_butt, | |
1167 | drawing->ruler->allocation.width-1, 1, | |
1168 | drawing->ruler->allocation.width-1, 7); | |
1169 | } | |
1170 | ||
1171 | ||
1172 | snprintf(text, 255, "%lus\n%luns", window_middle.tv_sec, | |
1173 | window_middle.tv_nsec); | |
1174 | ||
1175 | pango_layout_set_text(layout, text, -1); | |
1176 | pango_layout_get_pixel_extents(layout, &ink_rect, NULL); | |
1177 | global_width += ink_rect.width; | |
1178 | ||
1179 | if(global_width <= drawing->ruler->allocation.width) | |
1180 | { | |
1181 | gdk_draw_layout_with_colors(drawing->ruler->window, | |
1182 | drawing->ruler_gc_butt, | |
1183 | (drawing->ruler->allocation.width - ink_rect.width)/2, | |
1184 | 6, | |
1185 | layout, &foreground, &background); | |
1186 | ||
1187 | gdk_draw_line (drawing->ruler->window, | |
1188 | drawing->ruler_gc_butt, | |
1189 | drawing->ruler->allocation.width/2, 1, | |
1190 | drawing->ruler->allocation.width/2, 7); | |
1191 | ||
1192 | ||
1193 | ||
1194 | ||
1195 | } | |
1196 | ||
1197 | g_object_unref(layout); | |
1198 | ||
1199 | return FALSE; | |
1200 | } | |
1201 | ||
1202 | ||
1203 | /* notify mouse on ruler */ | |
1204 | static gboolean | |
1205 | motion_notify_ruler(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) | |
1206 | { | |
1207 | //g_debug("motion"); | |
1208 | //eventually follow mouse and show time here | |
1209 | return 0; | |
1210 | } |