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