add --fatal, -f, option : makes glib critical messages abort the program
[lttv.git] / ltt / branches / poly / lttv / modules / gui / controlflow / eventhooks.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
20 /*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
23
24
25 //#define PANGO_ENABLE_BACKEND
26 #include <gtk/gtk.h>
27 #include <gdk/gdk.h>
28 #include <glib.h>
29 #include <assert.h>
30 #include <string.h>
31 #include <stdio.h>
32
33 //#include <pango/pango.h>
34
35 #include <ltt/event.h>
36 #include <ltt/time.h>
37 #include <ltt/type.h>
38
39 #include <lttv/lttv.h>
40 #include <lttv/hook.h>
41 #include <lttv/state.h>
42 #include <lttvwindow/lttvwindow.h>
43 #include <lttvwindow/lttvwindowtraces.h>
44
45
46 #include "eventhooks.h"
47 #include "cfv.h"
48 #include "processlist.h"
49 #include "drawing.h"
50 #include "cfv-private.h"
51
52
53 #define MAX_PATH_LEN 256
54
55
56 /* Action to do when background computation completed.
57 *
58 * Eventually, will have to check that every requested traces are finished
59 * before doing the redraw.
60 */
61
62 gint background_ready(void *hook_data, void *call_data)
63 {
64 ControlFlowData *control_flow_data = (ControlFlowData *)hook_data;
65 LttvTrace *trace = (LttvTrace*)call_data;
66
67 g_debug("control flow viewer : background computation data ready.");
68
69 redraw_notify(control_flow_data, NULL);
70
71 return 0;
72 }
73
74
75 /* Request background computation. Verify if it is in progress or ready first.
76 *
77 * Right now, for all loaded traces.
78 *
79 * Later : must be only for each trace in the tab's traceset.
80 */
81 void request_background_data(ControlFlowData *control_flow_data)
82 {
83 gint num_traces = lttvwindowtraces_get_number();
84 gint i;
85 LttvTrace *trace;
86
87 LttvHooks *background_ready_hook =
88 lttv_hooks_new();
89 lttv_hooks_add(background_ready_hook, background_ready, control_flow_data,
90 LTTV_PRIO_DEFAULT);
91
92 for(i=0;i<num_traces;i++) {
93 trace = lttvwindowtraces_get_trace(i);
94
95 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
96
97 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
98 trace) == FALSE) {
99 /* We first remove requests that could have been done for the same
100 * information. Happens when two viewers ask for it before servicing
101 * starts.
102 */
103 lttvwindowtraces_background_request_remove(trace, "state");
104 lttvwindowtraces_background_request_queue(trace,
105 "state");
106 lttvwindowtraces_background_notify_queue(control_flow_data,
107 trace,
108 ltt_time_infinite,
109 NULL,
110 background_ready_hook);
111 } else { /* in progress */
112
113 lttvwindowtraces_background_notify_current(control_flow_data,
114 trace,
115 ltt_time_infinite,
116 NULL,
117 background_ready_hook);
118
119 }
120 }
121 }
122
123 lttv_hooks_destroy(background_ready_hook);
124 }
125
126
127
128
129 /**
130 * Event Viewer's constructor hook
131 *
132 * This constructor is given as a parameter to the menuitem and toolbar button
133 * registration. It creates the list.
134 * @param tab A pointer to the parent tab.
135 * @return The widget created.
136 */
137 GtkWidget *
138 h_guicontrolflow(Tab *tab, LttvTracesetSelector * s, char * key)
139 {
140 g_info("h_guicontrolflow, %p, %p, %s", tab, s, key);
141 ControlFlowData *control_flow_data = guicontrolflow() ;
142
143 control_flow_data->tab = tab;
144
145 //g_debug("time width2 : %u",time_window->time_width);
146 // Unreg done in the GuiControlFlow_Destructor
147 lttvwindow_register_traceset_notify(tab,
148 traceset_notify,
149 control_flow_data);
150
151 lttvwindow_register_time_window_notify(tab,
152 update_time_window_hook,
153 control_flow_data);
154 lttvwindow_register_current_time_notify(tab,
155 update_current_time_hook,
156 control_flow_data);
157 lttvwindow_register_redraw_notify(tab,
158 redraw_notify,
159 control_flow_data);
160 lttvwindow_register_continue_notify(tab,
161 continue_notify,
162 control_flow_data);
163 request_background_data(control_flow_data);
164
165
166 return guicontrolflow_get_widget(control_flow_data) ;
167
168 }
169
170 int event_selected_hook(void *hook_data, void *call_data)
171 {
172 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
173 guint *event_number = (guint*) call_data;
174
175 g_debug("DEBUG : event selected by main window : %u", *event_number);
176
177 // control_flow_data->currently_Selected_Event = *event_number;
178 // control_flow_data->Selected_Event = TRUE ;
179
180 // tree_v_set_cursor(control_flow_data);
181
182 }
183
184 /* Hook called before drawing. Gets the initial context at the beginning of the
185 * drawing interval and copy it to the context in event_request.
186 */
187 int draw_before_hook(void *hook_data, void *call_data)
188 {
189 EventsRequest *events_request = (EventsRequest*)hook_data;
190 //EventsContext Events_Context = (EventsContext*)call_data;
191
192 //event_request->Events_Context = Events_Context;
193
194 return 0;
195 }
196
197 /*
198 * The draw event hook is called by the reading API to have a
199 * particular event drawn on the screen.
200 * @param hook_data ControlFlowData structure of the viewer.
201 * @param call_data Event context.
202 *
203 * This function basically draw lines and icons. Two types of lines are drawn :
204 * one small (3 pixels?) representing the state of the process and the second
205 * type is thicker (10 pixels?) representing on which CPU a process is running
206 * (and this only in running state).
207 *
208 * Extremums of the lines :
209 * x_min : time of the last event context for this process kept in memory.
210 * x_max : time of the current event.
211 * y : middle of the process in the process list. The process is found in the
212 * list, therefore is it's position in pixels.
213 *
214 * The choice of lines'color is defined by the context of the last event for this
215 * process.
216 */
217 int draw_event_hook(void *hook_data, void *call_data)
218 {
219 EventsRequest *events_request = (EventsRequest*)hook_data;
220 ControlFlowData *control_flow_data =
221 (ControlFlowData*)events_request->viewer_data;
222 Tab *tab = control_flow_data->tab;
223
224 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
225
226 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
227 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
228
229 LttEvent *e;
230 e = tfc->e;
231
232 LttTime evtime = ltt_event_time(e);
233 TimeWindow time_window =
234 lttvwindow_get_time_window(tab);
235
236 LttTime end_time = ltt_time_add(time_window.start_time,
237 time_window.time_width);
238 //if(time < time_beg || time > time_end) return;
239 if(ltt_time_compare(evtime, time_window.start_time) == -1
240 || ltt_time_compare(evtime, end_time) == 1)
241 return;
242
243 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
244 {
245 g_debug("schedchange!");
246
247 /* Add process to process list (if not present) and get drawing "y" from
248 * process position */
249 guint pid_out, pid_in;
250 LttvProcessState *process_out, *process_in;
251 LttTime birth;
252 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
253
254 ProcessList *process_list =
255 guicontrolflow_get_process_list(control_flow_data);
256
257
258 LttField *f = ltt_event_field(e);
259 LttField *element;
260 element = ltt_field_member(f,0);
261 pid_out = ltt_event_get_long_unsigned(e,element);
262 element = ltt_field_member(f,1);
263 pid_in = ltt_event_get_long_unsigned(e,element);
264 g_debug("out : %u in : %u", pid_out, pid_in);
265
266
267 /* Find process pid_out in the list... */
268 process_out = lttv_state_find_process(tfs, pid_out);
269 if(process_out == NULL) return 0;
270 g_debug("out : %s",g_quark_to_string(process_out->state->s));
271
272 birth = process_out->creation_time;
273 gchar *name = strdup(g_quark_to_string(process_out->name));
274 HashedProcessData *hashed_process_data_out = NULL;
275
276 if(processlist_get_process_pixels(process_list,
277 pid_out,
278 &birth,
279 tfc->t_context->index,
280 &y_out,
281 &height,
282 &hashed_process_data_out) == 1)
283 {
284 /* Process not present */
285 processlist_add(process_list,
286 pid_out,
287 &birth,
288 tfc->t_context->index,
289 name,
290 &pl_height,
291 &hashed_process_data_out);
292 processlist_get_process_pixels(process_list,
293 pid_out,
294 &birth,
295 tfc->t_context->index,
296 &y_out,
297 &height,
298 &hashed_process_data_out);
299 drawing_insert_square( control_flow_data->drawing, y_out, height);
300 }
301
302 g_free(name);
303
304 /* Find process pid_in in the list... */
305 process_in = lttv_state_find_process(tfs, pid_in);
306 if(process_in == NULL) return 0;
307 g_debug("in : %s",g_quark_to_string(process_in->state->s));
308
309 birth = process_in->creation_time;
310 name = strdup(g_quark_to_string(process_in->name));
311 HashedProcessData *hashed_process_data_in = NULL;
312
313 if(processlist_get_process_pixels(process_list,
314 pid_in,
315 &birth,
316 tfc->t_context->index,
317 &y_in,
318 &height,
319 &hashed_process_data_in) == 1)
320 {
321 /* Process not present */
322 processlist_add(process_list,
323 pid_in,
324 &birth,
325 tfc->t_context->index,
326 name,
327 &pl_height,
328 &hashed_process_data_in);
329 processlist_get_process_pixels(process_list,
330 pid_in,
331 &birth,
332 tfc->t_context->index,
333 &y_in,
334 &height,
335 &hashed_process_data_in);
336
337 drawing_insert_square( control_flow_data->drawing, y_in, height);
338 }
339 g_free(name);
340
341
342 /* Find pixels corresponding to time of the event. If the time does
343 * not fit in the window, show a warning, not supposed to happend. */
344 guint x = 0;
345 guint width = control_flow_data->drawing->drawing_area->allocation.width;
346
347 LttTime time = ltt_event_time(e);
348
349 LttTime window_end = ltt_time_add(time_window.time_width,
350 time_window.start_time);
351
352
353 convert_time_to_pixels(
354 time_window.start_time,
355 window_end,
356 time,
357 width,
358 &x);
359 //assert(x <= width);
360
361 /* draw what represents the event for outgoing process. */
362
363 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
364 draw_context_out->current->modify_over->x = x;
365 draw_context_out->current->modify_under->x = x;
366 draw_context_out->current->modify_over->y = y_out;
367 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
368 draw_context_out->drawable = control_flow_data->drawing->pixmap;
369 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
370 GtkWidget *widget = control_flow_data->drawing->drawing_area;
371 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
372 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
373 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
374 //draw_context_out->gc = widget->style->black_gc;
375
376 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
377 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
378
379 /* Draw the line/background of the out process */
380 if(draw_context_out->previous->middle->x == -1)
381 {
382 draw_context_out->previous->over->x =
383 control_flow_data->drawing->damage_begin;
384 draw_context_out->previous->middle->x =
385 control_flow_data->drawing->damage_begin;
386 draw_context_out->previous->under->x =
387 control_flow_data->drawing->damage_begin;
388
389 g_debug("out middle x_beg : %u",control_flow_data->drawing->damage_begin);
390 }
391
392 draw_context_out->current->middle->x = x;
393 draw_context_out->current->over->x = x;
394 draw_context_out->current->under->x = x;
395 draw_context_out->current->middle->y = y_out + height/2;
396 draw_context_out->current->over->y = y_out;
397 draw_context_out->current->under->y = y_out + height;
398 draw_context_out->previous->middle->y = y_out + height/2;
399 draw_context_out->previous->over->y = y_out;
400 draw_context_out->previous->under->y = y_out + height;
401
402 draw_context_out->drawable = control_flow_data->drawing->pixmap;
403 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
404
405 if(process_out->state->s == LTTV_STATE_RUN)
406 {
407 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
408 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
409
410 PropertiesBG prop_bg;
411 prop_bg.color = g_new(GdkColor,1);
412
413 switch(tfc->index) {
414 case 0:
415 prop_bg.color->red = 0x1515;
416 prop_bg.color->green = 0x1515;
417 prop_bg.color->blue = 0x8c8c;
418 break;
419 case 1:
420 prop_bg.color->red = 0x4e4e;
421 prop_bg.color->green = 0xa9a9;
422 prop_bg.color->blue = 0xa4a4;
423 break;
424 case 2:
425 prop_bg.color->red = 0x7a7a;
426 prop_bg.color->green = 0x4a4a;
427 prop_bg.color->blue = 0x8b8b;
428 break;
429 case 3:
430 prop_bg.color->red = 0x8080;
431 prop_bg.color->green = 0x7777;
432 prop_bg.color->blue = 0x4747;
433 break;
434 default:
435 prop_bg.color->red = 0xe7e7;
436 prop_bg.color->green = 0xe7e7;
437 prop_bg.color->blue = 0xe7e7;
438 }
439
440 g_debug("calling from draw_event");
441 draw_bg((void*)&prop_bg, (void*)draw_context_out);
442 g_free(prop_bg.color);
443 gdk_gc_unref(draw_context_out->gc);
444 }
445
446 draw_context_out->gc = widget->style->black_gc;
447
448 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
449 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
450 PropertiesText prop_text_out;
451 prop_text_out.foreground = &colorfg_out;
452 prop_text_out.background = &colorbg_out;
453 prop_text_out.size = 6;
454 prop_text_out.position = OVER;
455
456 /* color of text : status of the process */
457 if(process_out->state->s == LTTV_STATE_UNNAMED)
458 {
459 prop_text_out.foreground->red = 0xffff;
460 prop_text_out.foreground->green = 0xffff;
461 prop_text_out.foreground->blue = 0xffff;
462 }
463 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
464 {
465 prop_text_out.foreground->red = 0x0fff;
466 prop_text_out.foreground->green = 0xffff;
467 prop_text_out.foreground->blue = 0xfff0;
468 }
469 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
470 {
471 prop_text_out.foreground->red = 0xffff;
472 prop_text_out.foreground->green = 0xffff;
473 prop_text_out.foreground->blue = 0x0000;
474 }
475 else if(process_out->state->s == LTTV_STATE_EXIT)
476 {
477 prop_text_out.foreground->red = 0xffff;
478 prop_text_out.foreground->green = 0x0000;
479 prop_text_out.foreground->blue = 0xffff;
480 }
481 else if(process_out->state->s == LTTV_STATE_WAIT)
482 {
483 prop_text_out.foreground->red = 0xffff;
484 prop_text_out.foreground->green = 0x0000;
485 prop_text_out.foreground->blue = 0x0000;
486 }
487 else if(process_out->state->s == LTTV_STATE_RUN)
488 {
489 prop_text_out.foreground->red = 0x0000;
490 prop_text_out.foreground->green = 0xffff;
491 prop_text_out.foreground->blue = 0x0000;
492 }
493 else
494 {
495 prop_text_out.foreground->red = 0xffff;
496 prop_text_out.foreground->green = 0xffff;
497 prop_text_out.foreground->blue = 0xffff;
498 }
499
500
501 /* Print status of the process : U, WF, WC, E, W, R */
502 if(process_out->state->s == LTTV_STATE_UNNAMED)
503 prop_text_out.text = "U->";
504 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
505 prop_text_out.text = "WF->";
506 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
507 prop_text_out.text = "WC->";
508 else if(process_out->state->s == LTTV_STATE_EXIT)
509 prop_text_out.text = "E->";
510 else if(process_out->state->s == LTTV_STATE_WAIT)
511 prop_text_out.text = "W->";
512 else if(process_out->state->s == LTTV_STATE_RUN)
513 prop_text_out.text = "R->";
514 else
515 prop_text_out.text = "U";
516
517 draw_text((void*)&prop_text_out, (void*)draw_context_out);
518 //gdk_gc_unref(draw_context_out->gc);
519
520 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
521 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
522
523 PropertiesLine prop_line_out;
524 prop_line_out.color = g_new(GdkColor,1);
525 prop_line_out.line_width = 2;
526 prop_line_out.style = GDK_LINE_SOLID;
527 prop_line_out.position = MIDDLE;
528
529 g_debug("out state : %s", g_quark_to_string(process_out->state->s));
530
531 /* color of line : status of the process */
532 if(process_out->state->s == LTTV_STATE_UNNAMED)
533 {
534 prop_line_out.color->red = 0xffff;
535 prop_line_out.color->green = 0xffff;
536 prop_line_out.color->blue = 0xffff;
537 }
538 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
539 {
540 prop_line_out.color->red = 0x0fff;
541 prop_line_out.color->green = 0xffff;
542 prop_line_out.color->blue = 0xfff0;
543 }
544 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
545 {
546 prop_line_out.color->red = 0xffff;
547 prop_line_out.color->green = 0xffff;
548 prop_line_out.color->blue = 0x0000;
549 }
550 else if(process_out->state->s == LTTV_STATE_EXIT)
551 {
552 prop_line_out.color->red = 0xffff;
553 prop_line_out.color->green = 0x0000;
554 prop_line_out.color->blue = 0xffff;
555 }
556 else if(process_out->state->s == LTTV_STATE_WAIT)
557 {
558 prop_line_out.color->red = 0xffff;
559 prop_line_out.color->green = 0x0000;
560 prop_line_out.color->blue = 0x0000;
561 }
562 else if(process_out->state->s == LTTV_STATE_RUN)
563 {
564 prop_line_out.color->red = 0x0000;
565 prop_line_out.color->green = 0xffff;
566 prop_line_out.color->blue = 0x0000;
567 }
568 else
569 {
570 prop_line_out.color->red = 0xffff;
571 prop_line_out.color->green = 0xffff;
572 prop_line_out.color->blue = 0xffff;
573 }
574
575 draw_line((void*)&prop_line_out, (void*)draw_context_out);
576 g_free(prop_line_out.color);
577 gdk_gc_unref(draw_context_out->gc);
578 /* Note : finishing line will have to be added when trace read over. */
579
580 /* Finally, update the drawing context of the pid_in. */
581
582 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
583 draw_context_in->current->modify_over->x = x;
584 draw_context_in->current->modify_under->x = x;
585 draw_context_in->current->modify_over->y = y_in;
586 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
587 draw_context_in->drawable = control_flow_data->drawing->pixmap;
588 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
589 widget = control_flow_data->drawing->drawing_area;
590 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
591 //draw_context_in->gc = widget->style->black_gc;
592 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
593 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
594
595 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
596 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
597
598 /* Draw the line/bg of the in process */
599 if(draw_context_in->previous->middle->x == -1)
600 {
601 draw_context_in->previous->over->x =
602 control_flow_data->drawing->damage_begin;
603 draw_context_in->previous->middle->x =
604 control_flow_data->drawing->damage_begin;
605 draw_context_in->previous->under->x =
606 control_flow_data->drawing->damage_begin;
607
608 g_debug("in middle x_beg : %u",control_flow_data->drawing->damage_begin);
609
610 }
611
612 draw_context_in->current->middle->x = x;
613 draw_context_in->current->over->x = x;
614 draw_context_in->current->under->x = x;
615 draw_context_in->current->middle->y = y_in + height/2;
616 draw_context_in->current->over->y = y_in;
617 draw_context_in->current->under->y = y_in + height;
618 draw_context_in->previous->middle->y = y_in + height/2;
619 draw_context_in->previous->over->y = y_in;
620 draw_context_in->previous->under->y = y_in + height;
621
622 draw_context_in->drawable = control_flow_data->drawing->pixmap;
623 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
624
625
626 if(process_in->state->s == LTTV_STATE_RUN)
627 {
628 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
629 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
630
631 PropertiesBG prop_bg;
632 prop_bg.color = g_new(GdkColor,1);
633
634 switch(tfc->index) {
635 case 0:
636 prop_bg.color->red = 0x1515;
637 prop_bg.color->green = 0x1515;
638 prop_bg.color->blue = 0x8c8c;
639 break;
640 case 1:
641 prop_bg.color->red = 0x4e4e;
642 prop_bg.color->green = 0xa9a9;
643 prop_bg.color->blue = 0xa4a4;
644 break;
645 case 2:
646 prop_bg.color->red = 0x7a7a;
647 prop_bg.color->green = 0x4a4a;
648 prop_bg.color->blue = 0x8b8b;
649 break;
650 case 3:
651 prop_bg.color->red = 0x8080;
652 prop_bg.color->green = 0x7777;
653 prop_bg.color->blue = 0x4747;
654 break;
655 default:
656 prop_bg.color->red = 0xe7e7;
657 prop_bg.color->green = 0xe7e7;
658 prop_bg.color->blue = 0xe7e7;
659 }
660
661
662 draw_bg((void*)&prop_bg, (void*)draw_context_in);
663 g_free(prop_bg.color);
664 gdk_gc_unref(draw_context_in->gc);
665 }
666
667 draw_context_in->gc = widget->style->black_gc;
668
669 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
670 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
671 PropertiesText prop_text_in;
672 prop_text_in.foreground = &colorfg_in;
673 prop_text_in.background = &colorbg_in;
674 prop_text_in.size = 6;
675 prop_text_in.position = OVER;
676
677 g_debug("in state : %s", g_quark_to_string(process_in->state->s));
678 /* foreground of text : status of the process */
679 if(process_in->state->s == LTTV_STATE_UNNAMED)
680 {
681 prop_text_in.foreground->red = 0xffff;
682 prop_text_in.foreground->green = 0xffff;
683 prop_text_in.foreground->blue = 0xffff;
684 }
685 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
686 {
687 prop_text_in.foreground->red = 0x0fff;
688 prop_text_in.foreground->green = 0xffff;
689 prop_text_in.foreground->blue = 0xfff0;
690 }
691 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
692 {
693 prop_text_in.foreground->red = 0xffff;
694 prop_text_in.foreground->green = 0xffff;
695 prop_text_in.foreground->blue = 0x0000;
696 }
697 else if(process_in->state->s == LTTV_STATE_EXIT)
698 {
699 prop_text_in.foreground->red = 0xffff;
700 prop_text_in.foreground->green = 0x0000;
701 prop_text_in.foreground->blue = 0xffff;
702 }
703 else if(process_in->state->s == LTTV_STATE_WAIT)
704 {
705 prop_text_in.foreground->red = 0xffff;
706 prop_text_in.foreground->green = 0x0000;
707 prop_text_in.foreground->blue = 0x0000;
708 }
709 else if(process_in->state->s == LTTV_STATE_RUN)
710 {
711 prop_text_in.foreground->red = 0x0000;
712 prop_text_in.foreground->green = 0xffff;
713 prop_text_in.foreground->blue = 0x0000;
714 }
715 else
716 {
717 prop_text_in.foreground->red = 0xffff;
718 prop_text_in.foreground->green = 0xffff;
719 prop_text_in.foreground->blue = 0xffff;
720 }
721
722
723
724 /* Print status of the process : U, WF, WC, E, W, R */
725 if(process_in->state->s == LTTV_STATE_UNNAMED)
726 prop_text_in.text = "U->";
727 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
728 prop_text_in.text = "WF->";
729 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
730 prop_text_in.text = "WC->";
731 else if(process_in->state->s == LTTV_STATE_EXIT)
732 prop_text_in.text = "E->";
733 else if(process_in->state->s == LTTV_STATE_WAIT)
734 prop_text_in.text = "W->";
735 else if(process_in->state->s == LTTV_STATE_RUN)
736 prop_text_in.text = "R->";
737 else
738 prop_text_in.text = "U";
739
740 draw_text((void*)&prop_text_in, (void*)draw_context_in);
741 //gdk_gc_unref(draw_context_in->gc);
742
743 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
744 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
745
746 PropertiesLine prop_line_in;
747 prop_line_in.color = g_new(GdkColor,1);
748 prop_line_in.line_width = 2;
749 prop_line_in.style = GDK_LINE_SOLID;
750 prop_line_in.position = MIDDLE;
751
752 /* color of line : status of the process */
753 if(process_in->state->s == LTTV_STATE_UNNAMED)
754 {
755 prop_line_in.color->red = 0xffff;
756 prop_line_in.color->green = 0xffff;
757 prop_line_in.color->blue = 0xffff;
758 }
759 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
760 {
761 prop_line_in.color->red = 0x0fff;
762 prop_line_in.color->green = 0xffff;
763 prop_line_in.color->blue = 0xfff0;
764 }
765 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
766 {
767 prop_line_in.color->red = 0xffff;
768 prop_line_in.color->green = 0xffff;
769 prop_line_in.color->blue = 0x0000;
770 }
771 else if(process_in->state->s == LTTV_STATE_EXIT)
772 {
773 prop_line_in.color->red = 0xffff;
774 prop_line_in.color->green = 0x0000;
775 prop_line_in.color->blue = 0xffff;
776 }
777 else if(process_in->state->s == LTTV_STATE_WAIT)
778 {
779 prop_line_in.color->red = 0xffff;
780 prop_line_in.color->green = 0x0000;
781 prop_line_in.color->blue = 0x0000;
782 }
783 else if(process_in->state->s == LTTV_STATE_RUN)
784 {
785 prop_line_in.color->red = 0x0000;
786 prop_line_in.color->green = 0xffff;
787 prop_line_in.color->blue = 0x0000;
788 }
789 else
790 {
791 prop_line_in.color->red = 0xffff;
792 prop_line_in.color->green = 0xffff;
793 prop_line_in.color->blue = 0xffff;
794 }
795
796 draw_line((void*)&prop_line_in, (void*)draw_context_in);
797 g_free(prop_line_in.color);
798 gdk_gc_unref(draw_context_in->gc);
799 }
800
801 return 0;
802
803 /* Temp dump */
804 #ifdef DONTSHOW
805 GString *string = g_string_new("");;
806 gboolean field_names = TRUE, state = TRUE;
807
808 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
809 g_string_append_printf(string,"\n");
810
811 if(state) {
812 g_string_append_printf(string, " %s",
813 g_quark_to_string(tfs->process->state->s));
814 }
815
816 g_info("%s",string->str);
817
818 g_string_free(string, TRUE);
819
820 /* End of text dump */
821 #endif //DONTSHOW
822
823 }
824
825
826 int draw_after_hook(void *hook_data, void *call_data)
827 {
828 EventsRequest *events_request = (EventsRequest*)hook_data;
829 ControlFlowData *control_flow_data = events_request->viewer_data;
830
831 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
832
833 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
834 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
835
836
837 LttEvent *e;
838 e = tfc->e;
839
840 LttTime evtime = ltt_event_time(e);
841 TimeWindow time_window =
842 lttvwindow_get_time_window(control_flow_data->tab);
843
844 LttTime end_time = ltt_time_add(time_window.start_time,
845 time_window.time_width);
846 //if(time < time_beg || time > time_end) return;
847 if(ltt_time_compare(evtime, time_window.start_time) == -1
848 || ltt_time_compare(evtime, end_time) == 1)
849 return;
850
851
852 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
853 {
854 g_debug("schedchange!");
855
856 /* Add process to process list (if not present) and get drawing "y" from
857 * process position */
858 guint pid_out, pid_in;
859 LttvProcessState *process_out, *process_in;
860 LttTime birth;
861 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
862
863 ProcessList *process_list =
864 guicontrolflow_get_process_list(control_flow_data);
865
866
867 LttField *f = ltt_event_field(e);
868 LttField *element;
869 element = ltt_field_member(f,0);
870 pid_out = ltt_event_get_long_unsigned(e,element);
871 element = ltt_field_member(f,1);
872 pid_in = ltt_event_get_long_unsigned(e,element);
873 //g_debug("out : %u in : %u", pid_out, pid_in);
874
875
876 /* Find process pid_out in the list... */
877 process_out = lttv_state_find_process(tfs, pid_out);
878 if(process_out == NULL) return 0;
879 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
880
881 birth = process_out->creation_time;
882 gchar *name = strdup(g_quark_to_string(process_out->name));
883 HashedProcessData *hashed_process_data_out = NULL;
884
885 if(processlist_get_process_pixels(process_list,
886 pid_out,
887 &birth,
888 tfc->t_context->index,
889 &y_out,
890 &height,
891 &hashed_process_data_out) == 1)
892 {
893 /* Process not present */
894 processlist_add(process_list,
895 pid_out,
896 &birth,
897 tfc->t_context->index,
898 name,
899 &pl_height,
900 &hashed_process_data_out);
901 processlist_get_process_pixels(process_list,
902 pid_out,
903 &birth,
904 tfc->t_context->index,
905 &y_out,
906 &height,
907 &hashed_process_data_out);
908 drawing_insert_square( control_flow_data->drawing, y_out, height);
909 }
910
911 g_free(name);
912
913 /* Find process pid_in in the list... */
914 process_in = lttv_state_find_process(tfs, pid_in);
915 if(process_in == NULL) return 0;
916 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
917
918 birth = process_in->creation_time;
919 name = strdup(g_quark_to_string(process_in->name));
920 HashedProcessData *hashed_process_data_in = NULL;
921
922 if(processlist_get_process_pixels(process_list,
923 pid_in,
924 &birth,
925 tfc->t_context->index,
926 &y_in,
927 &height,
928 &hashed_process_data_in) == 1)
929 {
930 /* Process not present */
931 processlist_add(process_list,
932 pid_in,
933 &birth,
934 tfc->t_context->index,
935 name,
936 &pl_height,
937 &hashed_process_data_in);
938 processlist_get_process_pixels(process_list,
939 pid_in,
940 &birth,
941 tfc->t_context->index,
942 &y_in,
943 &height,
944 &hashed_process_data_in);
945
946 drawing_insert_square( control_flow_data->drawing, y_in, height);
947 }
948 g_free(name);
949
950
951 /* Find pixels corresponding to time of the event. If the time does
952 * not fit in the window, show a warning, not supposed to happend. */
953 //guint x = 0;
954 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
955
956 //LttTime time = ltt_event_time(e);
957
958 //LttTime window_end = ltt_time_add(time_window->time_width,
959 // time_window->start_time);
960
961
962 //convert_time_to_pixels(
963 // time_window->start_time,
964 // window_end,
965 // time,
966 // width,
967 // &x);
968
969 //assert(x <= width);
970
971 /* draw what represents the event for outgoing process. */
972
973 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
974 //draw_context_out->current->modify_over->x = x;
975 draw_context_out->current->modify_over->y = y_out;
976 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
977 draw_context_out->drawable = control_flow_data->drawing->pixmap;
978 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
979 GtkWidget *widget = control_flow_data->drawing->drawing_area;
980 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
981
982 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
983 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
984
985 /*if(process_out->state->s == LTTV_STATE_RUN)
986 {
987 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
988 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
989 PropertiesBG prop_bg;
990 prop_bg.color = g_new(GdkColor,1);
991
992 prop_bg.color->red = 0xffff;
993 prop_bg.color->green = 0xffff;
994 prop_bg.color->blue = 0xffff;
995
996 draw_bg((void*)&prop_bg, (void*)draw_context_out);
997 g_free(prop_bg.color);
998 gdk_gc_unref(draw_context_out->gc);
999 }*/
1000
1001 draw_context_out->gc = widget->style->black_gc;
1002
1003 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
1004 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
1005 PropertiesText prop_text_out;
1006 prop_text_out.foreground = &colorfg_out;
1007 prop_text_out.background = &colorbg_out;
1008 prop_text_out.size = 6;
1009 prop_text_out.position = OVER;
1010
1011 /* color of text : status of the process */
1012 if(process_out->state->s == LTTV_STATE_UNNAMED)
1013 {
1014 prop_text_out.foreground->red = 0xffff;
1015 prop_text_out.foreground->green = 0xffff;
1016 prop_text_out.foreground->blue = 0xffff;
1017 }
1018 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1019 {
1020 prop_text_out.foreground->red = 0x0fff;
1021 prop_text_out.foreground->green = 0xffff;
1022 prop_text_out.foreground->blue = 0xfff0;
1023 }
1024 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1025 {
1026 prop_text_out.foreground->red = 0xffff;
1027 prop_text_out.foreground->green = 0xffff;
1028 prop_text_out.foreground->blue = 0x0000;
1029 }
1030 else if(process_out->state->s == LTTV_STATE_EXIT)
1031 {
1032 prop_text_out.foreground->red = 0xffff;
1033 prop_text_out.foreground->green = 0x0000;
1034 prop_text_out.foreground->blue = 0xffff;
1035 }
1036 else if(process_out->state->s == LTTV_STATE_WAIT)
1037 {
1038 prop_text_out.foreground->red = 0xffff;
1039 prop_text_out.foreground->green = 0x0000;
1040 prop_text_out.foreground->blue = 0x0000;
1041 }
1042 else if(process_out->state->s == LTTV_STATE_RUN)
1043 {
1044 prop_text_out.foreground->red = 0x0000;
1045 prop_text_out.foreground->green = 0xffff;
1046 prop_text_out.foreground->blue = 0x0000;
1047 }
1048 else
1049 {
1050 prop_text_out.foreground->red = 0xffff;
1051 prop_text_out.foreground->green = 0xffff;
1052 prop_text_out.foreground->blue = 0xffff;
1053 }
1054
1055 /* Print status of the process : U, WF, WC, E, W, R */
1056 if(process_out->state->s == LTTV_STATE_UNNAMED)
1057 prop_text_out.text = "U";
1058 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1059 prop_text_out.text = "WF";
1060 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1061 prop_text_out.text = "WC";
1062 else if(process_out->state->s == LTTV_STATE_EXIT)
1063 prop_text_out.text = "E";
1064 else if(process_out->state->s == LTTV_STATE_WAIT)
1065 prop_text_out.text = "W";
1066 else if(process_out->state->s == LTTV_STATE_RUN)
1067 prop_text_out.text = "R";
1068 else
1069 prop_text_out.text = "U";
1070
1071 draw_text((void*)&prop_text_out, (void*)draw_context_out);
1072
1073 //gdk_gc_unref(draw_context_out->gc);
1074
1075 draw_context_out->current->middle->y = y_out+height/2;
1076 draw_context_out->current->over->y = y_out;
1077 draw_context_out->current->under->y = y_out+height;
1078 draw_context_out->current->status = process_out->state->s;
1079
1080 /* for pid_out : remove previous, Prev = current, new current (default) */
1081 g_free(draw_context_out->previous->modify_under);
1082 g_free(draw_context_out->previous->modify_middle);
1083 g_free(draw_context_out->previous->modify_over);
1084 g_free(draw_context_out->previous->under);
1085 g_free(draw_context_out->previous->middle);
1086 g_free(draw_context_out->previous->over);
1087 g_free(draw_context_out->previous);
1088
1089 draw_context_out->previous = draw_context_out->current;
1090
1091 draw_context_out->current = g_new(DrawInfo,1);
1092 draw_context_out->current->over = g_new(ItemInfo,1);
1093 draw_context_out->current->over->x = -1;
1094 draw_context_out->current->over->y = -1;
1095 draw_context_out->current->middle = g_new(ItemInfo,1);
1096 draw_context_out->current->middle->x = -1;
1097 draw_context_out->current->middle->y = -1;
1098 draw_context_out->current->under = g_new(ItemInfo,1);
1099 draw_context_out->current->under->x = -1;
1100 draw_context_out->current->under->y = -1;
1101 draw_context_out->current->modify_over = g_new(ItemInfo,1);
1102 draw_context_out->current->modify_over->x = -1;
1103 draw_context_out->current->modify_over->y = -1;
1104 draw_context_out->current->modify_middle = g_new(ItemInfo,1);
1105 draw_context_out->current->modify_middle->x = -1;
1106 draw_context_out->current->modify_middle->y = -1;
1107 draw_context_out->current->modify_under = g_new(ItemInfo,1);
1108 draw_context_out->current->modify_under->x = -1;
1109 draw_context_out->current->modify_under->y = -1;
1110 draw_context_out->current->status = LTTV_STATE_UNNAMED;
1111
1112 /* Finally, update the drawing context of the pid_in. */
1113
1114 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
1115 //draw_context_in->current->modify_over->x = x;
1116 draw_context_in->current->modify_over->y = y_in;
1117 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
1118 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1119 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1120 widget = control_flow_data->drawing->drawing_area;
1121 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1122
1123 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
1124 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
1125
1126 /*if(process_in->state->s == LTTV_STATE_RUN)
1127 {
1128 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1129 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1130 PropertiesBG prop_bg;
1131 prop_bg.color = g_new(GdkColor,1);
1132
1133 prop_bg.color->red = 0xffff;
1134 prop_bg.color->green = 0xffff;
1135 prop_bg.color->blue = 0xffff;
1136
1137 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1138 g_free(prop_bg.color);
1139 gdk_gc_unref(draw_context_in->gc);
1140 }*/
1141
1142 draw_context_in->gc = widget->style->black_gc;
1143
1144 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
1145 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
1146 PropertiesText prop_text_in;
1147 prop_text_in.foreground = &colorfg_in;
1148 prop_text_in.background = &colorbg_in;
1149 prop_text_in.size = 6;
1150 prop_text_in.position = OVER;
1151
1152 /* foreground of text : status of the process */
1153 if(process_in->state->s == LTTV_STATE_UNNAMED)
1154 {
1155 prop_text_in.foreground->red = 0xffff;
1156 prop_text_in.foreground->green = 0xffff;
1157 prop_text_in.foreground->blue = 0xffff;
1158 }
1159 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1160 {
1161 prop_text_in.foreground->red = 0x0fff;
1162 prop_text_in.foreground->green = 0xffff;
1163 prop_text_in.foreground->blue = 0xfff0;
1164 }
1165 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1166 {
1167 prop_text_in.foreground->red = 0xffff;
1168 prop_text_in.foreground->green = 0xffff;
1169 prop_text_in.foreground->blue = 0x0000;
1170 }
1171 else if(process_in->state->s == LTTV_STATE_EXIT)
1172 {
1173 prop_text_in.foreground->red = 0xffff;
1174 prop_text_in.foreground->green = 0x0000;
1175 prop_text_in.foreground->blue = 0xffff;
1176 }
1177 else if(process_in->state->s == LTTV_STATE_WAIT)
1178 {
1179 prop_text_in.foreground->red = 0xffff;
1180 prop_text_in.foreground->green = 0x0000;
1181 prop_text_in.foreground->blue = 0x0000;
1182 }
1183 else if(process_in->state->s == LTTV_STATE_RUN)
1184 {
1185 prop_text_in.foreground->red = 0x0000;
1186 prop_text_in.foreground->green = 0xffff;
1187 prop_text_in.foreground->blue = 0x0000;
1188 }
1189 else
1190 {
1191 prop_text_in.foreground->red = 0xffff;
1192 prop_text_in.foreground->green = 0xffff;
1193 prop_text_in.foreground->blue = 0xffff;
1194 }
1195
1196
1197 /* Print status of the process : U, WF, WC, E, W, R */
1198 if(process_in->state->s == LTTV_STATE_UNNAMED)
1199 prop_text_in.text = "U";
1200 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1201 prop_text_in.text = "WF";
1202 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1203 prop_text_in.text = "WC";
1204 else if(process_in->state->s == LTTV_STATE_EXIT)
1205 prop_text_in.text = "E";
1206 else if(process_in->state->s == LTTV_STATE_WAIT)
1207 prop_text_in.text = "W";
1208 else if(process_in->state->s == LTTV_STATE_RUN)
1209 prop_text_in.text = "R";
1210 else
1211 prop_text_in.text = "U";
1212
1213 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1214
1215
1216 if(process_in->state->s == LTTV_STATE_RUN)
1217 {
1218 gchar tmp[255];
1219 prop_text_in.foreground = &colorfg_in;
1220 prop_text_in.background = &colorbg_in;
1221 prop_text_in.foreground->red = 0xffff;
1222 prop_text_in.foreground->green = 0xffff;
1223 prop_text_in.foreground->blue = 0xffff;
1224 prop_text_in.size = 6;
1225 prop_text_in.position = UNDER;
1226
1227 prop_text_in.text = g_new(gchar, 260);
1228 strcpy(prop_text_in.text, "CPU ");
1229 snprintf(tmp, 255, "%u", tfc->index);
1230 strcat(prop_text_in.text, tmp);
1231
1232 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1233 g_free(prop_text_in.text);
1234 }
1235
1236
1237 draw_context_in->current->middle->y = y_in+height/2;
1238 draw_context_in->current->over->y = y_in;
1239 draw_context_in->current->under->y = y_in+height;
1240 draw_context_in->current->status = process_in->state->s;
1241
1242 /* for pid_in : remove previous, Prev = current, new current (default) */
1243 g_free(draw_context_in->previous->modify_under);
1244 g_free(draw_context_in->previous->modify_middle);
1245 g_free(draw_context_in->previous->modify_over);
1246 g_free(draw_context_in->previous->under);
1247 g_free(draw_context_in->previous->middle);
1248 g_free(draw_context_in->previous->over);
1249 g_free(draw_context_in->previous);
1250
1251 draw_context_in->previous = draw_context_in->current;
1252
1253 draw_context_in->current = g_new(DrawInfo,1);
1254 draw_context_in->current->over = g_new(ItemInfo,1);
1255 draw_context_in->current->over->x = -1;
1256 draw_context_in->current->over->y = -1;
1257 draw_context_in->current->middle = g_new(ItemInfo,1);
1258 draw_context_in->current->middle->x = -1;
1259 draw_context_in->current->middle->y = -1;
1260 draw_context_in->current->under = g_new(ItemInfo,1);
1261 draw_context_in->current->under->x = -1;
1262 draw_context_in->current->under->y = -1;
1263 draw_context_in->current->modify_over = g_new(ItemInfo,1);
1264 draw_context_in->current->modify_over->x = -1;
1265 draw_context_in->current->modify_over->y = -1;
1266 draw_context_in->current->modify_middle = g_new(ItemInfo,1);
1267 draw_context_in->current->modify_middle->x = -1;
1268 draw_context_in->current->modify_middle->y = -1;
1269 draw_context_in->current->modify_under = g_new(ItemInfo,1);
1270 draw_context_in->current->modify_under->x = -1;
1271 draw_context_in->current->modify_under->y = -1;
1272 draw_context_in->current->status = LTTV_STATE_UNNAMED;
1273
1274 }
1275
1276 return 0;
1277 }
1278
1279
1280
1281
1282 gint update_time_window_hook(void *hook_data, void *call_data)
1283 {
1284 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1285 Drawing_t *drawing = control_flow_data->drawing;
1286
1287 const TimeWindowNotifyData *time_window_nofify_data =
1288 ((const TimeWindowNotifyData *)call_data);
1289
1290 TimeWindow *old_time_window =
1291 time_window_nofify_data->old_time_window;
1292 TimeWindow *new_time_window =
1293 time_window_nofify_data->new_time_window;
1294
1295 /* Update the ruler */
1296 drawing_update_ruler(control_flow_data->drawing,
1297 new_time_window);
1298
1299
1300 /* Two cases : zoom in/out or scrolling */
1301
1302 /* In order to make sure we can reuse the old drawing, the scale must
1303 * be the same and the new time interval being partly located in the
1304 * currently shown time interval. (reuse is only for scrolling)
1305 */
1306
1307 g_info("Old time window HOOK : %u, %u to %u, %u",
1308 old_time_window->start_time.tv_sec,
1309 old_time_window->start_time.tv_nsec,
1310 old_time_window->time_width.tv_sec,
1311 old_time_window->time_width.tv_nsec);
1312
1313 g_info("New time window HOOK : %u, %u to %u, %u",
1314 new_time_window->start_time.tv_sec,
1315 new_time_window->start_time.tv_nsec,
1316 new_time_window->time_width.tv_sec,
1317 new_time_window->time_width.tv_nsec);
1318
1319 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
1320 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
1321 {
1322 /* Same scale (scrolling) */
1323 g_info("scrolling");
1324 LttTime *ns = &new_time_window->start_time;
1325 LttTime *os = &old_time_window->start_time;
1326 LttTime old_end = ltt_time_add(old_time_window->start_time,
1327 old_time_window->time_width);
1328 LttTime new_end = ltt_time_add(new_time_window->start_time,
1329 new_time_window->time_width);
1330 //if(ns<os+w<ns+w)
1331 //if(ns<os+w && os+w<ns+w)
1332 //if(ns<old_end && os<ns)
1333 if(ltt_time_compare(*ns, old_end) == -1
1334 && ltt_time_compare(*os, *ns) == -1)
1335 {
1336 g_info("scrolling near right");
1337 /* Scroll right, keep right part of the screen */
1338 guint x = 0;
1339 guint width = control_flow_data->drawing->drawing_area->allocation.width;
1340 convert_time_to_pixels(
1341 *os,
1342 old_end,
1343 *ns,
1344 width,
1345 &x);
1346
1347 /* Copy old data to new location */
1348 gdk_draw_drawable (control_flow_data->drawing->pixmap,
1349 control_flow_data->drawing->drawing_area->style->black_gc,
1350 control_flow_data->drawing->pixmap,
1351 x, 0,
1352 0, 0,
1353 control_flow_data->drawing->width-x+SAFETY, -1);
1354
1355 if(drawing->damage_begin == drawing->damage_end)
1356 drawing->damage_begin = control_flow_data->drawing->width-x;
1357 else
1358 drawing->damage_begin = 0;
1359
1360 drawing->damage_end = control_flow_data->drawing->width;
1361
1362 /* Clear the data request background, but not SAFETY */
1363 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1364 //control_flow_data->drawing->drawing_area->style->black_gc,
1365 control_flow_data->drawing->drawing_area->style->black_gc,
1366 TRUE,
1367 drawing->damage_begin+SAFETY, 0,
1368 drawing->damage_end - drawing->damage_begin, // do not overlap
1369 control_flow_data->drawing->height+SAFETY);
1370
1371 gtk_widget_queue_draw_area (drawing->drawing_area,
1372 0,0,
1373 control_flow_data->drawing->width,
1374 control_flow_data->drawing->height);
1375
1376 /* Get new data for the rest. */
1377 drawing_data_request(control_flow_data->drawing,
1378 &control_flow_data->drawing->pixmap,
1379 drawing->damage_begin, 0,
1380 drawing->damage_end - drawing->damage_begin,
1381 control_flow_data->drawing->height);
1382 } else {
1383 //if(ns<os<ns+w)
1384 //if(ns<os && os<ns+w)
1385 //if(ns<os && os<new_end)
1386 if(ltt_time_compare(*ns,*os) == -1
1387 && ltt_time_compare(*os,new_end) == -1)
1388 {
1389 g_info("scrolling near left");
1390 /* Scroll left, keep left part of the screen */
1391 guint x = 0;
1392 guint width = control_flow_data->drawing->drawing_area->allocation.width;
1393 convert_time_to_pixels(
1394 *ns,
1395 new_end,
1396 *os,
1397 width,
1398 &x);
1399
1400
1401 /* Copy old data to new location */
1402 gdk_draw_drawable (control_flow_data->drawing->pixmap,
1403 control_flow_data->drawing->drawing_area->style->black_gc,
1404 control_flow_data->drawing->pixmap,
1405 0, 0,
1406 x, 0,
1407 -1, -1);
1408
1409 *old_time_window = *new_time_window;
1410
1411 if(drawing->damage_begin == drawing->damage_end)
1412 drawing->damage_end = x;
1413 else
1414 drawing->damage_end =
1415 control_flow_data->drawing->drawing_area->allocation.width;
1416
1417 drawing->damage_begin = 0;
1418
1419 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1420 control_flow_data->drawing->drawing_area->style->black_gc,
1421 TRUE,
1422 drawing->damage_begin, 0,
1423 drawing->damage_end - drawing->damage_begin, // do not overlap
1424 control_flow_data->drawing->height+SAFETY);
1425
1426 gtk_widget_queue_draw_area (drawing->drawing_area,
1427 0,0,
1428 control_flow_data->drawing->width,
1429 control_flow_data->drawing->height);
1430
1431
1432 /* Get new data for the rest. */
1433 drawing_data_request(control_flow_data->drawing,
1434 &control_flow_data->drawing->pixmap,
1435 drawing->damage_begin, 0,
1436 drawing->damage_end - drawing->damage_begin,
1437 control_flow_data->drawing->height);
1438
1439 } else {
1440 if(ltt_time_compare(*ns,*os) == 0)
1441 {
1442 g_info("not scrolling");
1443 } else {
1444 g_info("scrolling far");
1445 /* Cannot reuse any part of the screen : far jump */
1446
1447
1448 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1449 control_flow_data->drawing->drawing_area->style->black_gc,
1450 TRUE,
1451 0, 0,
1452 control_flow_data->drawing->width+SAFETY, // do not overlap
1453 control_flow_data->drawing->height+SAFETY);
1454
1455 gtk_widget_queue_draw_area (drawing->drawing_area,
1456 0,0,
1457 control_flow_data->drawing->width,
1458 control_flow_data->drawing->height);
1459
1460 drawing->damage_begin = 0;
1461 drawing->damage_end = control_flow_data->drawing->width;
1462
1463 drawing_data_request(control_flow_data->drawing,
1464 &control_flow_data->drawing->pixmap,
1465 0, 0,
1466 control_flow_data->drawing->width,
1467 control_flow_data->drawing->height);
1468
1469 }
1470 }
1471 }
1472 } else {
1473 /* Different scale (zoom) */
1474 g_info("zoom");
1475
1476 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
1477 control_flow_data->drawing->drawing_area->style->black_gc,
1478 TRUE,
1479 0, 0,
1480 control_flow_data->drawing->width+SAFETY, // do not overlap
1481 control_flow_data->drawing->height+SAFETY);
1482
1483 gtk_widget_queue_draw_area (drawing->drawing_area,
1484 0,0,
1485 control_flow_data->drawing->width,
1486 control_flow_data->drawing->height);
1487
1488 drawing->damage_begin = 0;
1489 drawing->damage_end = control_flow_data->drawing->width;
1490
1491 drawing_data_request(control_flow_data->drawing,
1492 &control_flow_data->drawing->pixmap,
1493 0, 0,
1494 control_flow_data->drawing->width,
1495 control_flow_data->drawing->height);
1496 }
1497
1498
1499
1500 return 0;
1501 }
1502
1503 gint traceset_notify(void *hook_data, void *call_data)
1504 {
1505 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1506 Drawing_t *drawing = control_flow_data->drawing;
1507 GtkWidget *widget = drawing->drawing_area;
1508
1509 drawing->damage_begin = 0;
1510 drawing->damage_end = widget->allocation.width;
1511
1512
1513 // Clear the image
1514 gdk_draw_rectangle (drawing->pixmap,
1515 widget->style->black_gc,
1516 TRUE,
1517 0, 0,
1518 widget->allocation.width+SAFETY,
1519 widget->allocation.height+SAFETY);
1520
1521
1522 if(drawing->damage_begin < drawing->damage_end)
1523 {
1524 drawing_data_request(drawing,
1525 &drawing->pixmap,
1526 drawing->damage_begin,
1527 0,
1528 drawing->damage_end-drawing->damage_begin,
1529 widget->allocation.height);
1530 }
1531
1532 gtk_widget_queue_draw_area(drawing->drawing_area,
1533 0,0,
1534 drawing->width,
1535 drawing->height);
1536
1537 request_background_data(control_flow_data);
1538
1539 return FALSE;
1540 }
1541
1542 gint redraw_notify(void *hook_data, void *call_data)
1543 {
1544 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1545 Drawing_t *drawing = control_flow_data->drawing;
1546 GtkWidget *widget = drawing->drawing_area;
1547
1548 drawing->damage_begin = 0;
1549 drawing->damage_end = widget->allocation.width;
1550
1551
1552 // Clear the image
1553 gdk_draw_rectangle (drawing->pixmap,
1554 widget->style->black_gc,
1555 TRUE,
1556 0, 0,
1557 widget->allocation.width+SAFETY,
1558 widget->allocation.height+SAFETY);
1559
1560
1561 if(drawing->damage_begin < drawing->damage_end)
1562 {
1563 drawing_data_request(drawing,
1564 &drawing->pixmap,
1565 drawing->damage_begin,
1566 0,
1567 drawing->damage_end-drawing->damage_begin,
1568 widget->allocation.height);
1569 }
1570
1571 gtk_widget_queue_draw_area(drawing->drawing_area,
1572 0,0,
1573 drawing->width,
1574 drawing->height);
1575
1576 return FALSE;
1577
1578 }
1579
1580
1581 gint continue_notify(void *hook_data, void *call_data)
1582 {
1583 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1584 Drawing_t *drawing = control_flow_data->drawing;
1585 GtkWidget *widget = drawing->drawing_area;
1586
1587 //g_assert(widget->allocation.width == drawing->damage_end);
1588
1589 if(drawing->damage_begin < drawing->damage_end)
1590 {
1591 drawing_data_request(drawing,
1592 &drawing->pixmap,
1593 drawing->damage_begin,
1594 0,
1595 drawing->damage_end-drawing->damage_begin,
1596 widget->allocation.height);
1597 }
1598
1599 return FALSE;
1600 }
1601
1602
1603 gint after_process_traceset_hook(void *hook_data, void *call_data)
1604 {
1605 //ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
1606 EventsRequest *events_request = (EventsRequest *)hook_data;
1607
1608 ControlFlowData *control_flow_data =
1609 (ControlFlowData*)events_request->viewer_data;
1610
1611
1612 drawing_data_request_end(events_request,
1613 (LttvTracesetState*)call_data);
1614 return 0;
1615 }
1616
1617
1618
1619 gint update_current_time_hook(void *hook_data, void *call_data)
1620 {
1621 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
1622 Drawing_t *drawing = control_flow_data->drawing;
1623
1624 LttTime current_time = *((LttTime*)call_data);
1625
1626 TimeWindow time_window =
1627 lttvwindow_get_time_window(control_flow_data->tab);
1628
1629 LttTime time_begin = time_window.start_time;
1630 LttTime width = time_window.time_width;
1631 LttTime half_width = ltt_time_div(width,2.0);
1632 LttTime time_end = ltt_time_add(time_begin, width);
1633
1634 LttvTracesetContext * tsc =
1635 lttvwindow_get_traceset_context(control_flow_data->tab);
1636
1637 LttTime trace_start = tsc->time_span.start_time;
1638 LttTime trace_end = tsc->time_span.end_time;
1639
1640 g_info("New current time HOOK : %u, %u", current_time.tv_sec,
1641 current_time.tv_nsec);
1642
1643
1644
1645 /* If current time is inside time interval, just move the highlight
1646 * bar */
1647
1648 /* Else, we have to change the time interval. We have to tell it
1649 * to the main window. */
1650 /* The time interval change will take care of placing the current
1651 * time at the center of the visible area, or nearest possible if we are
1652 * at one end of the trace. */
1653
1654
1655 if(ltt_time_compare(current_time, time_begin) == -1)
1656 {
1657 TimeWindow new_time_window;
1658
1659 if(ltt_time_compare(current_time,
1660 ltt_time_add(trace_start,half_width)) == -1)
1661 time_begin = trace_start;
1662 else
1663 time_begin = ltt_time_sub(current_time,half_width);
1664
1665 new_time_window.start_time = time_begin;
1666 new_time_window.time_width = width;
1667
1668 lttvwindow_report_time_window(control_flow_data->tab, &new_time_window);
1669 }
1670 else if(ltt_time_compare(current_time, time_end) == 1)
1671 {
1672 TimeWindow new_time_window;
1673
1674 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) == 1)
1675 time_begin = ltt_time_sub(trace_end,width);
1676 else
1677 time_begin = ltt_time_sub(current_time,half_width);
1678
1679 new_time_window.start_time = time_begin;
1680 new_time_window.time_width = width;
1681
1682 lttvwindow_report_time_window(control_flow_data->tab, &new_time_window);
1683
1684 }
1685 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1686 gtk_widget_queue_draw_area(drawing->drawing_area,
1687 0,0,
1688 drawing->width,
1689 drawing->height);
1690
1691 return 0;
1692 }
1693
1694 typedef struct _ClosureData {
1695 EventsRequest *events_request;
1696 LttvTracesetState *tss;
1697 } ClosureData;
1698
1699
1700 void draw_closure(gpointer key, gpointer value, gpointer user_data)
1701 {
1702 ProcessInfo *process_info = (ProcessInfo*)key;
1703 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
1704 ClosureData *closure_data = (ClosureData*)user_data;
1705
1706 ControlFlowData *control_flow_data =
1707 closure_data->events_request->viewer_data;
1708
1709 GtkWidget *widget = control_flow_data->drawing->drawing_area;
1710
1711 /* Get y position of process */
1712 gint y=0, height=0;
1713
1714 processlist_get_pixels_from_data( control_flow_data->process_list,
1715 process_info,
1716 hashed_process_data,
1717 &y,
1718 &height);
1719 /* Get last state of process */
1720 LttvTraceContext *tc =
1721 ((LttvTracesetContext*)closure_data->tss)->traces[process_info->trace_num];
1722 LttvTracesetContext *tsc = (LttvTracesetContext *)closure_data->tss;
1723
1724 LttvTraceState *ts = (LttvTraceState*)tc;
1725 LttvProcessState *process;
1726
1727 /* We do not provide a cpu_name argument assuming that this is not the
1728 idle job (pid 0) and thus its pid is unique across all cpus */
1729 process = lttv_state_find_process_from_trace(ts, 0, process_info->pid);
1730
1731 /* Draw the closing line */
1732 DrawContext *draw_context = hashed_process_data->draw_context;
1733 if(draw_context->previous->middle->x == -1)
1734 {
1735 draw_context->previous->over->x =
1736 control_flow_data->drawing->damage_begin;
1737 draw_context->previous->middle->x =
1738 control_flow_data->drawing->damage_begin;
1739 draw_context->previous->under->x =
1740 control_flow_data->drawing->damage_begin;
1741
1742 g_debug("out middle x_beg : %u",control_flow_data->drawing->damage_begin);
1743 }
1744
1745 /* Find pixels corresponding to current time . If the time does
1746 * not fit in the window, show a warning, not supposed to happend. */
1747 guint x = 0;
1748 guint width = control_flow_data->drawing->drawing_area->allocation.width;
1749
1750 TimeWindow time_window =
1751 lttvwindow_get_time_window(control_flow_data->tab);
1752
1753 LttTime time = lttv_traceset_context_get_current_tfc(tsc)->timestamp;
1754
1755 LttTime window_end = ltt_time_add(time_window.time_width,
1756 time_window.start_time);
1757
1758 convert_time_to_pixels(
1759 time_window.start_time,
1760 window_end,
1761 time,
1762 width,
1763 &x);
1764
1765 draw_context->current->middle->x = x;
1766 draw_context->current->over->x = x;
1767 draw_context->current->under->x = x;
1768 draw_context->current->middle->y = y + height/2;
1769 draw_context->current->over->y = y ;
1770 draw_context->current->under->y = y + height;
1771 draw_context->previous->middle->y = y + height/2;
1772 draw_context->previous->over->y = y ;
1773 draw_context->previous->under->y = y + height;
1774 draw_context->drawable = control_flow_data->drawing->pixmap;
1775 draw_context->pango_layout = control_flow_data->drawing->pango_layout;
1776 //draw_context->gc = widget->style->black_gc;
1777 draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1778 gdk_gc_copy(draw_context->gc, widget->style->black_gc);
1779
1780 if(process != NULL && process->state->s == LTTV_STATE_RUN)
1781 {
1782 PropertiesBG prop_bg;
1783 prop_bg.color = g_new(GdkColor,1);
1784
1785 /*switch(tfc->index) {
1786 case 0:
1787 prop_bg.color->red = 0x1515;
1788 prop_bg.color->green = 0x1515;
1789 prop_bg.color->blue = 0x8c8c;
1790 break;
1791 case 1:
1792 prop_bg.color->red = 0x4e4e;
1793 prop_bg.color->green = 0xa9a9;
1794 prop_bg.color->blue = 0xa4a4;
1795 break;
1796 case 2:
1797 prop_bg.color->red = 0x7a7a;
1798 prop_bg.color->green = 0x4a4a;
1799 prop_bg.color->blue = 0x8b8b;
1800 break;
1801 case 3:
1802 prop_bg.color->red = 0x8080;
1803 prop_bg.color->green = 0x7777;
1804 prop_bg.color->blue = 0x4747;
1805 break;
1806 default:
1807 prop_bg.color->red = 0xe7e7;
1808 prop_bg.color->green = 0xe7e7;
1809 prop_bg.color->blue = 0xe7e7;
1810 }
1811 */
1812
1813 g_debug("calling from closure");
1814 //FIXME : I need the cpu number in process's state to draw this.
1815 //draw_bg((void*)&prop_bg, (void*)draw_context);
1816 g_free(prop_bg.color);
1817 }
1818
1819
1820 PropertiesLine prop_line;
1821 prop_line.color = g_new(GdkColor,1);
1822 prop_line.line_width = 2;
1823 prop_line.style = GDK_LINE_SOLID;
1824 prop_line.position = MIDDLE;
1825
1826 /* color of line : status of the process */
1827 if(process != NULL)
1828 {
1829 if(process->state->s == LTTV_STATE_UNNAMED)
1830 {
1831 prop_line.color->red = 0xffff;
1832 prop_line.color->green = 0xffff;
1833 prop_line.color->blue = 0xffff;
1834 }
1835 else if(process->state->s == LTTV_STATE_WAIT_FORK)
1836 {
1837 prop_line.color->red = 0x0fff;
1838 prop_line.color->green = 0xffff;
1839 prop_line.color->blue = 0xfff0;
1840 }
1841 else if(process->state->s == LTTV_STATE_WAIT_CPU)
1842 {
1843 prop_line.color->red = 0xffff;
1844 prop_line.color->green = 0xffff;
1845 prop_line.color->blue = 0x0000;
1846 }
1847 else if(process->state->s == LTTV_STATE_EXIT)
1848 {
1849 prop_line.color->red = 0xffff;
1850 prop_line.color->green = 0x0000;
1851 prop_line.color->blue = 0xffff;
1852 }
1853 else if(process->state->s == LTTV_STATE_WAIT)
1854 {
1855 prop_line.color->red = 0xffff;
1856 prop_line.color->green = 0x0000;
1857 prop_line.color->blue = 0x0000;
1858 }
1859 else if(process->state->s == LTTV_STATE_RUN)
1860 {
1861 prop_line.color->red = 0x0000;
1862 prop_line.color->green = 0xffff;
1863 prop_line.color->blue = 0x0000;
1864 }
1865 else
1866 {
1867 prop_line.color->red = 0xffff;
1868 prop_line.color->green = 0xffff;
1869 prop_line.color->blue = 0xffff;
1870 }
1871
1872 }
1873 else
1874 {
1875 prop_line.color->red = 0xffff;
1876 prop_line.color->green = 0xffff;
1877 prop_line.color->blue = 0xffff;
1878 }
1879
1880 draw_line((void*)&prop_line, (void*)draw_context);
1881 g_free(prop_line.color);
1882 gdk_gc_unref(draw_context->gc);
1883
1884 /* Reset draw_context of the process for next request */
1885
1886 hashed_process_data->draw_context->drawable = NULL;
1887 hashed_process_data->draw_context->gc = NULL;
1888 hashed_process_data->draw_context->pango_layout = NULL;
1889 hashed_process_data->draw_context->current->over->x = -1;
1890 hashed_process_data->draw_context->current->over->y = -1;
1891 hashed_process_data->draw_context->current->middle->x = -1;
1892 hashed_process_data->draw_context->current->middle->y = -1;
1893 hashed_process_data->draw_context->current->under->x = -1;
1894 hashed_process_data->draw_context->current->under->y = -1;
1895 hashed_process_data->draw_context->current->modify_over->x = -1;
1896 hashed_process_data->draw_context->current->modify_over->y = -1;
1897 hashed_process_data->draw_context->current->modify_middle->x = -1;
1898 hashed_process_data->draw_context->current->modify_middle->y = -1;
1899 hashed_process_data->draw_context->current->modify_under->x = -1;
1900 hashed_process_data->draw_context->current->modify_under->y = -1;
1901 hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED;
1902 hashed_process_data->draw_context->previous->over->x = -1;
1903 hashed_process_data->draw_context->previous->over->y = -1;
1904 hashed_process_data->draw_context->previous->middle->x = -1;
1905 hashed_process_data->draw_context->previous->middle->y = -1;
1906 hashed_process_data->draw_context->previous->under->x = -1;
1907 hashed_process_data->draw_context->previous->under->y = -1;
1908 hashed_process_data->draw_context->previous->modify_over->x = -1;
1909 hashed_process_data->draw_context->previous->modify_over->y = -1;
1910 hashed_process_data->draw_context->previous->modify_middle->x = -1;
1911 hashed_process_data->draw_context->previous->modify_middle->y = -1;
1912 hashed_process_data->draw_context->previous->modify_under->x = -1;
1913 hashed_process_data->draw_context->previous->modify_under->y = -1;
1914 hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED;
1915
1916 }
1917
1918 int before_data_request(void *hook_data, void *call_data)
1919 {
1920 EventsRequest *events_request = (EventsRequest*)hook_data;
1921 LttvTracesetState *tss = LTTV_TRACESET_STATE(call_data);
1922
1923 drawing_data_request_begin(events_request, tss);
1924
1925 return 0;
1926 }
1927
1928
1929 /*
1930 * for each process
1931 * draw closing line
1932 * new default prev and current
1933 * then finally remove reading hooks.
1934 */
1935 int after_data_request(void *hook_data, void *call_data)
1936 {
1937 EventsRequest *events_request = (EventsRequest*)hook_data;
1938 ControlFlowData *control_flow_data = events_request->viewer_data;
1939 LttvTracesetState *tss = LTTV_TRACESET_STATE(call_data);
1940
1941 ProcessList *process_list =
1942 guicontrolflow_get_process_list(control_flow_data);
1943
1944 ClosureData closure_data;
1945 closure_data.events_request = (EventsRequest*)hook_data;
1946 closure_data.tss = tss;
1947
1948 g_hash_table_foreach(process_list->process_hash, draw_closure,
1949 (void*)&closure_data);
1950
1951 /* Request expose */
1952 drawing_data_request_end(events_request, tss);
1953
1954 return 0;
1955 }
1956
This page took 0.067529 seconds and 5 git commands to generate.