remove old files
[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 g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
26 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
27
28 //#define PANGO_ENABLE_BACKEND
29 #include <gtk/gtk.h>
30 #include <gdk/gdk.h>
31 #include <glib.h>
32 #include <assert.h>
33 #include <string.h>
34
35 //#include <pango/pango.h>
36
37 #include <ltt/event.h>
38 #include <ltt/time.h>
39 #include <ltt/type.h>
40
41 #include <lttv/hook.h>
42 #include <lttv/common.h>
43 #include <lttv/state.h>
44 #include <lttv/gtkTraceSet.h>
45
46
47 #include "eventhooks.h"
48 #include "cfv.h"
49 #include "processlist.h"
50 #include "drawing.h"
51 #include "cfv-private.h"
52
53
54 #define MAX_PATH_LEN 256
55
56
57 /**
58 * Event Viewer's constructor hook
59 *
60 * This constructor is given as a parameter to the menuitem and toolbar button
61 * registration. It creates the list.
62 * @param mw A pointer to the parent window.
63 * @return The widget created.
64 */
65 GtkWidget *
66 h_guicontrolflow(MainWindow *mw, LttvTracesetSelector * s, char * key)
67 {
68 g_info("h_guicontrolflow, %p, %p, %s", mw, s, key);
69 ControlFlowData *control_flow_data = guicontrolflow() ;
70
71 control_flow_data->mw = mw;
72 TimeWindow *time_window = guicontrolflow_get_time_window(control_flow_data);
73 time_window->start_time.tv_sec = 0;
74 time_window->start_time.tv_nsec = 0;
75 time_window->time_width.tv_sec = 0;
76 time_window->time_width.tv_nsec = 0;
77
78 LttTime *current_time = guicontrolflow_get_current_time(control_flow_data);
79 current_time->tv_sec = 0;
80 current_time->tv_nsec = 0;
81
82 //g_critical("time width1 : %u",time_window->time_width);
83
84 get_time_window(mw,
85 time_window);
86 get_current_time(mw,
87 current_time);
88
89 //g_critical("time width2 : %u",time_window->time_width);
90 // Unreg done in the GuiControlFlow_Destructor
91 reg_update_time_window(update_time_window_hook, control_flow_data,
92 mw);
93 reg_update_current_time(update_current_time_hook, control_flow_data,
94 mw);
95 return guicontrolflow_get_widget(control_flow_data) ;
96
97 }
98
99 int event_selected_hook(void *hook_data, void *call_data)
100 {
101 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
102 guint *event_number = (guint*) call_data;
103
104 g_critical("DEBUG : event selected by main window : %u", *event_number);
105
106 // control_flow_data->currently_Selected_Event = *event_number;
107 // control_flow_data->Selected_Event = TRUE ;
108
109 // tree_v_set_cursor(control_flow_data);
110
111 }
112
113 /* Hook called before drawing. Gets the initial context at the beginning of the
114 * drawing interval and copy it to the context in event_request.
115 */
116 int draw_before_hook(void *hook_data, void *call_data)
117 {
118 EventRequest *event_request = (EventRequest*)hook_data;
119 //EventsContext Events_Context = (EventsContext*)call_data;
120
121 //event_request->Events_Context = Events_Context;
122
123 return 0;
124 }
125
126 /*
127 * The draw event hook is called by the reading API to have a
128 * particular event drawn on the screen.
129 * @param hook_data ControlFlowData structure of the viewer.
130 * @param call_data Event context.
131 *
132 * This function basically draw lines and icons. Two types of lines are drawn :
133 * one small (3 pixels?) representing the state of the process and the second
134 * type is thicker (10 pixels?) representing on which CPU a process is running
135 * (and this only in running state).
136 *
137 * Extremums of the lines :
138 * x_min : time of the last event context for this process kept in memory.
139 * x_max : time of the current event.
140 * y : middle of the process in the process list. The process is found in the
141 * list, therefore is it's position in pixels.
142 *
143 * The choice of lines'color is defined by the context of the last event for this
144 * process.
145 */
146 int draw_event_hook(void *hook_data, void *call_data)
147 {
148 EventRequest *event_request = (EventRequest*)hook_data;
149 ControlFlowData *control_flow_data = event_request->control_flow_data;
150
151 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
152
153 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
154
155
156 LttEvent *e;
157 e = tfc->e;
158
159 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
160 {
161 g_critical("schedchange!");
162
163 /* Add process to process list (if not present) and get drawing "y" from
164 * process position */
165 guint pid_out, pid_in;
166 LttvProcessState *process_out, *process_in;
167 LttTime birth;
168 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
169
170 ProcessList *process_list =
171 guicontrolflow_get_process_list(event_request->control_flow_data);
172
173
174 LttField *f = ltt_event_field(e);
175 LttField *element;
176 element = ltt_field_member(f,0);
177 pid_out = ltt_event_get_long_unsigned(e,element);
178 element = ltt_field_member(f,1);
179 pid_in = ltt_event_get_long_unsigned(e,element);
180 g_critical("out : %u in : %u", pid_out, pid_in);
181
182
183 /* Find process pid_out in the list... */
184 process_out = lttv_state_find_process(tfs, pid_out);
185 g_critical("out : %s",g_quark_to_string(process_out->state->s));
186
187 birth = process_out->creation_time;
188 gchar *name = strdup(g_quark_to_string(process_out->name));
189 HashedProcessData *hashed_process_data_out = NULL;
190
191 if(processlist_get_process_pixels(process_list,
192 pid_out,
193 &birth,
194 &y_out,
195 &height,
196 &hashed_process_data_out) == 1)
197 {
198 /* Process not present */
199 processlist_add(process_list,
200 pid_out,
201 &birth,
202 name,
203 &pl_height,
204 &hashed_process_data_out);
205 processlist_get_process_pixels(process_list,
206 pid_out,
207 &birth,
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 g_critical("in : %s",g_quark_to_string(process_in->state->s));
219
220 birth = process_in->creation_time;
221 name = strdup(g_quark_to_string(process_in->name));
222 HashedProcessData *hashed_process_data_in = NULL;
223
224 if(processlist_get_process_pixels(process_list,
225 pid_in,
226 &birth,
227 &y_in,
228 &height,
229 &hashed_process_data_in) == 1)
230 {
231 /* Process not present */
232 processlist_add(process_list,
233 pid_in,
234 &birth,
235 name,
236 &pl_height,
237 &hashed_process_data_in);
238 processlist_get_process_pixels(process_list,
239 pid_in,
240 &birth,
241 &y_in,
242 &height,
243 &hashed_process_data_in);
244
245 drawing_insert_square( event_request->control_flow_data->drawing, y_in, height);
246 }
247 g_free(name);
248
249
250 /* Find pixels corresponding to time of the event. If the time does
251 * not fit in the window, show a warning, not supposed to happend. */
252 guint x = 0;
253 guint width = control_flow_data->drawing->drawing_area->allocation.width;
254
255 LttTime time = ltt_event_time(e);
256
257 LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width,
258 control_flow_data->time_window.start_time);
259
260
261 convert_time_to_pixels(
262 control_flow_data->time_window.start_time,
263 window_end,
264 time,
265 width,
266 &x);
267
268 assert(x <= width);
269
270 /* draw what represents the event for outgoing process. */
271
272 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
273 draw_context_out->current->modify_over->x = x;
274 draw_context_out->current->modify_over->y = y_out;
275 draw_context_out->drawable = control_flow_data->drawing->pixmap;
276 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
277 GtkWidget *widget = control_flow_data->drawing->drawing_area;
278 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
279 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
280 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
281 //draw_context_out->gc = widget->style->black_gc;
282
283 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
284 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
285
286 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
287 GdkColor colorbg_out = { 0, 0xffff, 0xffff, 0xffff };
288 PropertiesText prop_text_out;
289 prop_text_out.foreground = &colorfg_out;
290 prop_text_out.background = &colorbg_out;
291 prop_text_out.size = 10;
292 prop_text_out.position = OVER;
293
294 /* Print status of the process : U, WF, WC, E, W, R */
295 if(process_out->state->s == LTTV_STATE_UNNAMED)
296 prop_text_out.text = "U";
297 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
298 prop_text_out.text = "WF";
299 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
300 prop_text_out.text = "WC";
301 else if(process_out->state->s == LTTV_STATE_EXIT)
302 prop_text_out.text = "E";
303 else if(process_out->state->s == LTTV_STATE_WAIT)
304 prop_text_out.text = "W";
305 else if(process_out->state->s == LTTV_STATE_RUN)
306 prop_text_out.text = "R";
307 else
308 prop_text_out.text = "U";
309
310 draw_text((void*)&prop_text_out, (void*)draw_context_out);
311 gdk_gc_unref(draw_context_out->gc);
312
313 /* Draw the line of the out process */
314 if(draw_context_out->previous->middle->x == -1)
315 {
316 draw_context_out->previous->middle->x = event_request->x_begin;
317 g_critical("out middle x_beg : %u",event_request->x_begin);
318 }
319
320 draw_context_out->current->middle->x = x;
321 draw_context_out->current->middle->y = y_out + height/2;
322 draw_context_out->previous->middle->y = y_out + height/2;
323 draw_context_out->drawable = control_flow_data->drawing->pixmap;
324 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
325 //draw_context_out->gc = widget->style->black_gc;
326 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
327 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
328
329 PropertiesLine prop_line_out;
330 prop_line_out.color = g_new(GdkColor,1);
331 prop_line_out.line_width = 4;
332 prop_line_out.style = GDK_LINE_SOLID;
333 prop_line_out.position = MIDDLE;
334
335 /* color of line : status of the process */
336 if(process_out->state->s == LTTV_STATE_UNNAMED)
337 {
338 prop_line_out.color->red = 0x0000;
339 prop_line_out.color->green = 0x0000;
340 prop_line_out.color->blue = 0x0000;
341 }
342 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
343 {
344 prop_line_out.color->red = 0x0fff;
345 prop_line_out.color->green = 0x0000;
346 prop_line_out.color->blue = 0x0fff;
347 }
348 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
349 {
350 prop_line_out.color->red = 0x0fff;
351 prop_line_out.color->green = 0x0fff;
352 prop_line_out.color->blue = 0x0000;
353 }
354 else if(process_out->state->s == LTTV_STATE_EXIT)
355 {
356 prop_line_out.color->red = 0xffff;
357 prop_line_out.color->green = 0x0000;
358 prop_line_out.color->blue = 0xffff;
359 }
360 else if(process_out->state->s == LTTV_STATE_WAIT)
361 {
362 prop_line_out.color->red = 0xffff;
363 prop_line_out.color->green = 0x0000;
364 prop_line_out.color->blue = 0x0000;
365 }
366 else if(process_out->state->s == LTTV_STATE_RUN)
367 {
368 prop_line_out.color->red = 0x0000;
369 prop_line_out.color->green = 0xffff;
370 prop_line_out.color->blue = 0x0000;
371 }
372 else
373 {
374 prop_line_out.color->red = 0x0000;
375 prop_line_out.color->green = 0x0000;
376 prop_line_out.color->blue = 0x0000;
377 }
378
379 draw_line((void*)&prop_line_out, (void*)draw_context_out);
380 g_free(prop_line_out.color);
381 gdk_gc_unref(draw_context_out->gc);
382 /* Note : finishing line will have to be added when trace read over. */
383
384 /* Finally, update the drawing context of the pid_in. */
385
386 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
387 draw_context_in->current->modify_over->x = x;
388 draw_context_in->current->modify_over->y = y_in;
389 draw_context_in->drawable = control_flow_data->drawing->pixmap;
390 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
391 widget = control_flow_data->drawing->drawing_area;
392 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
393 //draw_context_in->gc = widget->style->black_gc;
394 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
395 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
396
397 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
398 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
399
400 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
401 GdkColor colorbg_in = { 0, 0xffff, 0xffff, 0xffff };
402 PropertiesText prop_text_in;
403 prop_text_in.foreground = &colorfg_in;
404 prop_text_in.background = &colorbg_in;
405 prop_text_in.size = 10;
406 prop_text_in.position = OVER;
407
408 /* Print status of the process : U, WF, WC, E, W, R */
409 if(process_in->state->s == LTTV_STATE_UNNAMED)
410 prop_text_in.text = "U";
411 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
412 prop_text_in.text = "WF";
413 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
414 prop_text_in.text = "WC";
415 else if(process_in->state->s == LTTV_STATE_EXIT)
416 prop_text_in.text = "E";
417 else if(process_in->state->s == LTTV_STATE_WAIT)
418 prop_text_in.text = "W";
419 else if(process_in->state->s == LTTV_STATE_RUN)
420 prop_text_in.text = "R";
421 else
422 prop_text_in.text = "U";
423
424 draw_text((void*)&prop_text_in, (void*)draw_context_in);
425 gdk_gc_unref(draw_context_in->gc);
426
427 /* Draw the line of the in process */
428 if(draw_context_in->previous->middle->x == -1)
429 {
430 draw_context_in->previous->middle->x = event_request->x_begin;
431 g_critical("in middle x_beg : %u",event_request->x_begin);
432 }
433
434 draw_context_in->current->middle->x = x;
435 draw_context_in->previous->middle->y = y_in + height/2;
436 draw_context_in->current->middle->y = y_in + height/2;
437 draw_context_in->drawable = control_flow_data->drawing->pixmap;
438 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
439 //draw_context_in->gc = widget->style->black_gc;
440 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
441 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
442
443 PropertiesLine prop_line_in;
444 prop_line_in.color = g_new(GdkColor,1);
445 prop_line_in.line_width = 4;
446 prop_line_in.style = GDK_LINE_SOLID;
447 prop_line_in.position = MIDDLE;
448
449 /* color of line : status of the process */
450 if(process_in->state->s == LTTV_STATE_UNNAMED)
451 {
452 prop_line_in.color->red = 0x0000;
453 prop_line_in.color->green = 0x0000;
454 prop_line_in.color->blue = 0x0000;
455 }
456 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
457 {
458 prop_line_in.color->red = 0x0fff;
459 prop_line_in.color->green = 0x0000;
460 prop_line_in.color->blue = 0x0fff;
461 }
462 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
463 {
464 prop_line_in.color->red = 0x0fff;
465 prop_line_in.color->green = 0x0fff;
466 prop_line_in.color->blue = 0x0000;
467 }
468 else if(process_in->state->s == LTTV_STATE_EXIT)
469 {
470 prop_line_in.color->red = 0xffff;
471 prop_line_in.color->green = 0x0000;
472 prop_line_in.color->blue = 0xffff;
473 }
474 else if(process_in->state->s == LTTV_STATE_WAIT)
475 {
476 prop_line_in.color->red = 0xffff;
477 prop_line_in.color->green = 0x0000;
478 prop_line_in.color->blue = 0x0000;
479 }
480 else if(process_in->state->s == LTTV_STATE_RUN)
481 {
482 prop_line_in.color->red = 0x0000;
483 prop_line_in.color->green = 0xffff;
484 prop_line_in.color->blue = 0x0000;
485 }
486 else
487 {
488 prop_line_in.color->red = 0x0000;
489 prop_line_in.color->green = 0x0000;
490 prop_line_in.color->blue = 0x0000;
491 }
492
493 draw_line((void*)&prop_line_in, (void*)draw_context_in);
494 g_free(prop_line_in.color);
495 gdk_gc_unref(draw_context_in->gc);
496 }
497
498 return 0;
499
500 /* Temp dump */
501 #ifdef DONTSHOW
502 GString *string = g_string_new("");;
503 gboolean field_names = TRUE, state = TRUE;
504
505 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
506 g_string_append_printf(string,"\n");
507
508 if(state) {
509 g_string_append_printf(string, " %s",
510 g_quark_to_string(tfs->process->state->s));
511 }
512
513 g_info("%s",string->str);
514
515 g_string_free(string, TRUE);
516
517 /* End of text dump */
518 #endif //DONTSHOW
519
520 }
521
522
523 int draw_after_hook(void *hook_data, void *call_data)
524 {
525 EventRequest *event_request = (EventRequest*)hook_data;
526 ControlFlowData *control_flow_data = event_request->control_flow_data;
527
528 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
529
530 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
531
532
533 LttEvent *e;
534 e = tfc->e;
535
536 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
537 {
538 g_critical("schedchange!");
539
540 /* Add process to process list (if not present) and get drawing "y" from
541 * process position */
542 guint pid_out, pid_in;
543 LttvProcessState *process_out, *process_in;
544 LttTime birth;
545 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
546
547 ProcessList *process_list =
548 guicontrolflow_get_process_list(event_request->control_flow_data);
549
550
551 LttField *f = ltt_event_field(e);
552 LttField *element;
553 element = ltt_field_member(f,0);
554 pid_out = ltt_event_get_long_unsigned(e,element);
555 element = ltt_field_member(f,1);
556 pid_in = ltt_event_get_long_unsigned(e,element);
557 g_critical("out : %u in : %u", pid_out, pid_in);
558
559
560 /* Find process pid_out in the list... */
561 process_out = lttv_state_find_process(tfs, pid_out);
562 g_critical("out : %s",g_quark_to_string(process_out->state->s));
563
564 birth = process_out->creation_time;
565 gchar *name = strdup(g_quark_to_string(process_out->name));
566 HashedProcessData *hashed_process_data_out = NULL;
567
568 if(processlist_get_process_pixels(process_list,
569 pid_out,
570 &birth,
571 &y_out,
572 &height,
573 &hashed_process_data_out) == 1)
574 {
575 /* Process not present */
576 processlist_add(process_list,
577 pid_out,
578 &birth,
579 name,
580 &pl_height,
581 &hashed_process_data_out);
582 processlist_get_process_pixels(process_list,
583 pid_out,
584 &birth,
585 &y_out,
586 &height,
587 &hashed_process_data_out);
588 drawing_insert_square( event_request->control_flow_data->drawing, y_out, height);
589 }
590
591 g_free(name);
592
593 /* Find process pid_in in the list... */
594 process_in = lttv_state_find_process(tfs, pid_in);
595 g_critical("in : %s",g_quark_to_string(process_in->state->s));
596
597 birth = process_in->creation_time;
598 name = strdup(g_quark_to_string(process_in->name));
599 HashedProcessData *hashed_process_data_in = NULL;
600
601 if(processlist_get_process_pixels(process_list,
602 pid_in,
603 &birth,
604 &y_in,
605 &height,
606 &hashed_process_data_in) == 1)
607 {
608 /* Process not present */
609 processlist_add(process_list,
610 pid_in,
611 &birth,
612 name,
613 &pl_height,
614 &hashed_process_data_in);
615 processlist_get_process_pixels(process_list,
616 pid_in,
617 &birth,
618 &y_in,
619 &height,
620 &hashed_process_data_in);
621
622 drawing_insert_square( event_request->control_flow_data->drawing, y_in, height);
623 }
624 g_free(name);
625
626
627 /* Find pixels corresponding to time of the event. If the time does
628 * not fit in the window, show a warning, not supposed to happend. */
629 //guint x = 0;
630 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
631
632 //LttTime time = ltt_event_time(e);
633
634 //LttTime window_end = ltt_time_add(control_flow_data->time_window.time_width,
635 // control_flow_data->time_window.start_time);
636
637
638 //convert_time_to_pixels(
639 // control_flow_data->time_window.start_time,
640 // window_end,
641 // time,
642 // width,
643 // &x);
644
645 //assert(x <= width);
646
647 /* draw what represents the event for outgoing process. */
648
649 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
650 //draw_context_out->current->modify_over->x = x;
651 draw_context_out->current->modify_over->y = y_out;
652 draw_context_out->drawable = control_flow_data->drawing->pixmap;
653 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
654 GtkWidget *widget = control_flow_data->drawing->drawing_area;
655 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
656 draw_context_out->gc = widget->style->black_gc;
657
658 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
659 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
660
661 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
662 GdkColor colorbg_out = { 0, 0xffff, 0xffff, 0xffff };
663 PropertiesText prop_text_out;
664 prop_text_out.foreground = &colorfg_out;
665 prop_text_out.background = &colorbg_out;
666 prop_text_out.size = 10;
667 prop_text_out.position = OVER;
668
669 /* Print status of the process : U, WF, WC, E, W, R */
670 if(process_out->state->s == LTTV_STATE_UNNAMED)
671 prop_text_out.text = "U";
672 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
673 prop_text_out.text = "WF";
674 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
675 prop_text_out.text = "WC";
676 else if(process_out->state->s == LTTV_STATE_EXIT)
677 prop_text_out.text = "E";
678 else if(process_out->state->s == LTTV_STATE_WAIT)
679 prop_text_out.text = "W";
680 else if(process_out->state->s == LTTV_STATE_RUN)
681 prop_text_out.text = "R";
682 else
683 prop_text_out.text = "U";
684
685 draw_text((void*)&prop_text_out, (void*)draw_context_out);
686
687 draw_context_out->current->middle->y = y_out+height/2;
688 draw_context_out->current->status = process_out->state->s;
689
690 /* for pid_out : remove previous, Prev = current, new current (default) */
691 g_free(draw_context_out->previous->modify_under);
692 g_free(draw_context_out->previous->modify_middle);
693 g_free(draw_context_out->previous->modify_over);
694 g_free(draw_context_out->previous->under);
695 g_free(draw_context_out->previous->middle);
696 g_free(draw_context_out->previous->over);
697 g_free(draw_context_out->previous);
698
699 draw_context_out->previous = draw_context_out->current;
700
701 draw_context_out->current = g_new(DrawInfo,1);
702 draw_context_out->current->over = g_new(ItemInfo,1);
703 draw_context_out->current->over->x = -1;
704 draw_context_out->current->over->y = -1;
705 draw_context_out->current->middle = g_new(ItemInfo,1);
706 draw_context_out->current->middle->x = -1;
707 draw_context_out->current->middle->y = -1;
708 draw_context_out->current->under = g_new(ItemInfo,1);
709 draw_context_out->current->under->x = -1;
710 draw_context_out->current->under->y = -1;
711 draw_context_out->current->modify_over = g_new(ItemInfo,1);
712 draw_context_out->current->modify_over->x = -1;
713 draw_context_out->current->modify_over->y = -1;
714 draw_context_out->current->modify_middle = g_new(ItemInfo,1);
715 draw_context_out->current->modify_middle->x = -1;
716 draw_context_out->current->modify_middle->y = -1;
717 draw_context_out->current->modify_under = g_new(ItemInfo,1);
718 draw_context_out->current->modify_under->x = -1;
719 draw_context_out->current->modify_under->y = -1;
720 draw_context_out->current->status = LTTV_STATE_UNNAMED;
721
722 /* Finally, update the drawing context of the pid_in. */
723
724 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
725 //draw_context_in->current->modify_over->x = x;
726 draw_context_in->current->modify_over->y = y_in;
727 draw_context_in->drawable = control_flow_data->drawing->pixmap;
728 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
729 widget = control_flow_data->drawing->drawing_area;
730 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
731 draw_context_in->gc = widget->style->black_gc;
732
733 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
734 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
735
736 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
737 GdkColor colorbg_in = { 0, 0xffff, 0xffff, 0xffff };
738 PropertiesText prop_text_in;
739 prop_text_in.foreground = &colorfg_in;
740 prop_text_in.background = &colorbg_in;
741 prop_text_in.size = 10;
742 prop_text_in.position = OVER;
743
744 /* Print status of the process : U, WF, WC, E, W, R */
745 if(process_in->state->s == LTTV_STATE_UNNAMED)
746 prop_text_in.text = "U";
747 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
748 prop_text_in.text = "WF";
749 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
750 prop_text_in.text = "WC";
751 else if(process_in->state->s == LTTV_STATE_EXIT)
752 prop_text_in.text = "E";
753 else if(process_in->state->s == LTTV_STATE_WAIT)
754 prop_text_in.text = "W";
755 else if(process_in->state->s == LTTV_STATE_RUN)
756 prop_text_in.text = "R";
757 else
758 prop_text_in.text = "U";
759
760 draw_text((void*)&prop_text_in, (void*)draw_context_in);
761
762 draw_context_in->current->middle->y = y_in+height/2;
763 draw_context_in->current->status = process_in->state->s;
764
765 /* for pid_in : remove previous, Prev = current, new current (default) */
766 g_free(draw_context_in->previous->modify_under);
767 g_free(draw_context_in->previous->modify_middle);
768 g_free(draw_context_in->previous->modify_over);
769 g_free(draw_context_in->previous->under);
770 g_free(draw_context_in->previous->middle);
771 g_free(draw_context_in->previous->over);
772 g_free(draw_context_in->previous);
773
774 draw_context_in->previous = draw_context_in->current;
775
776 draw_context_in->current = g_new(DrawInfo,1);
777 draw_context_in->current->over = g_new(ItemInfo,1);
778 draw_context_in->current->over->x = -1;
779 draw_context_in->current->over->y = -1;
780 draw_context_in->current->middle = g_new(ItemInfo,1);
781 draw_context_in->current->middle->x = -1;
782 draw_context_in->current->middle->y = -1;
783 draw_context_in->current->under = g_new(ItemInfo,1);
784 draw_context_in->current->under->x = -1;
785 draw_context_in->current->under->y = -1;
786 draw_context_in->current->modify_over = g_new(ItemInfo,1);
787 draw_context_in->current->modify_over->x = -1;
788 draw_context_in->current->modify_over->y = -1;
789 draw_context_in->current->modify_middle = g_new(ItemInfo,1);
790 draw_context_in->current->modify_middle->x = -1;
791 draw_context_in->current->modify_middle->y = -1;
792 draw_context_in->current->modify_under = g_new(ItemInfo,1);
793 draw_context_in->current->modify_under->x = -1;
794 draw_context_in->current->modify_under->y = -1;
795 draw_context_in->current->status = LTTV_STATE_UNNAMED;
796
797 }
798
799 return 0;
800 }
801
802
803
804
805 gint update_time_window_hook(void *hook_data, void *call_data)
806 {
807 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
808 TimeWindow *old_time_window =
809 guicontrolflow_get_time_window(control_flow_data);
810 TimeWindow *new_time_window = ((TimeWindow*)call_data);
811
812 /* Two cases : zoom in/out or scrolling */
813
814 /* In order to make sure we can reuse the old drawing, the scale must
815 * be the same and the new time interval being partly located in the
816 * currently shown time interval. (reuse is only for scrolling)
817 */
818
819 g_info("Old time window HOOK : %u, %u to %u, %u",
820 old_time_window->start_time.tv_sec,
821 old_time_window->start_time.tv_nsec,
822 old_time_window->time_width.tv_sec,
823 old_time_window->time_width.tv_nsec);
824
825 g_info("New time window HOOK : %u, %u to %u, %u",
826 new_time_window->start_time.tv_sec,
827 new_time_window->start_time.tv_nsec,
828 new_time_window->time_width.tv_sec,
829 new_time_window->time_width.tv_nsec);
830
831 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
832 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
833 {
834 /* Same scale (scrolling) */
835 g_info("scrolling");
836 LttTime *ns = &new_time_window->start_time;
837 LttTime *os = &old_time_window->start_time;
838 LttTime old_end = ltt_time_add(old_time_window->start_time,
839 old_time_window->time_width);
840 LttTime new_end = ltt_time_add(new_time_window->start_time,
841 new_time_window->time_width);
842 //if(ns<os+w<ns+w)
843 //if(ns<os+w && os+w<ns+w)
844 //if(ns<old_end && os<ns)
845 if(ltt_time_compare(*ns, old_end) == -1
846 && ltt_time_compare(*os, *ns) == -1)
847 {
848 g_info("scrolling near right");
849 /* Scroll right, keep right part of the screen */
850 guint x = 0;
851 guint width = control_flow_data->drawing->drawing_area->allocation.width;
852 convert_time_to_pixels(
853 *os,
854 old_end,
855 *ns,
856 width,
857 &x);
858
859 /* Copy old data to new location */
860 gdk_draw_drawable (control_flow_data->drawing->pixmap,
861 control_flow_data->drawing->drawing_area->style->white_gc,
862 control_flow_data->drawing->pixmap,
863 x, 0,
864 0, 0,
865 -1, -1);
866
867 convert_time_to_pixels(
868 *ns,
869 new_end,
870 old_end,
871 width,
872 &x);
873
874 *old_time_window = *new_time_window;
875 /* Clear the data request background, but not SAFETY */
876 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
877 control_flow_data->drawing->drawing_area->style->white_gc,
878 TRUE,
879 x+SAFETY, 0,
880 control_flow_data->drawing->width - x, // do not overlap
881 control_flow_data->drawing->height+SAFETY);
882 /* Get new data for the rest. */
883 drawing_data_request(control_flow_data->drawing,
884 &control_flow_data->drawing->pixmap,
885 x, 0,
886 control_flow_data->drawing->width - x,
887 control_flow_data->drawing->height);
888
889 drawing_refresh(control_flow_data->drawing,
890 0, 0,
891 control_flow_data->drawing->width,
892 control_flow_data->drawing->height);
893
894
895 } else {
896 //if(ns<os<ns+w)
897 //if(ns<os && os<ns+w)
898 //if(ns<os && os<new_end)
899 if(ltt_time_compare(*ns,*os) == -1
900 && ltt_time_compare(*os,new_end) == -1)
901 {
902 g_info("scrolling near left");
903 /* Scroll left, keep left part of the screen */
904 guint x = 0;
905 guint width = control_flow_data->drawing->drawing_area->allocation.width;
906 convert_time_to_pixels(
907 *ns,
908 new_end,
909 *os,
910 width,
911 &x);
912
913 /* Copy old data to new location */
914 gdk_draw_drawable (control_flow_data->drawing->pixmap,
915 control_flow_data->drawing->drawing_area->style->white_gc,
916 control_flow_data->drawing->pixmap,
917 0, 0,
918 x, 0,
919 -1, -1);
920
921 *old_time_window = *new_time_window;
922
923 /* Clean the data request background */
924 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
925 control_flow_data->drawing->drawing_area->style->white_gc,
926 TRUE,
927 0, 0,
928 x, // do not overlap
929 control_flow_data->drawing->height+SAFETY);
930 /* Get new data for the rest. */
931 drawing_data_request(control_flow_data->drawing,
932 &control_flow_data->drawing->pixmap,
933 0, 0,
934 x,
935 control_flow_data->drawing->height);
936
937 drawing_refresh(control_flow_data->drawing,
938 0, 0,
939 control_flow_data->drawing->width,
940 control_flow_data->drawing->height);
941
942 } else {
943 g_info("scrolling far");
944 /* Cannot reuse any part of the screen : far jump */
945 *old_time_window = *new_time_window;
946
947
948 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
949 control_flow_data->drawing->drawing_area->style->white_gc,
950 TRUE,
951 0, 0,
952 control_flow_data->drawing->width+SAFETY, // do not overlap
953 control_flow_data->drawing->height+SAFETY);
954
955 drawing_data_request(control_flow_data->drawing,
956 &control_flow_data->drawing->pixmap,
957 0, 0,
958 control_flow_data->drawing->width,
959 control_flow_data->drawing->height);
960
961 drawing_refresh(control_flow_data->drawing,
962 0, 0,
963 control_flow_data->drawing->width,
964 control_flow_data->drawing->height);
965 }
966 }
967 } else {
968 /* Different scale (zoom) */
969 g_info("zoom");
970
971 *old_time_window = *new_time_window;
972
973 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
974 control_flow_data->drawing->drawing_area->style->white_gc,
975 TRUE,
976 0, 0,
977 control_flow_data->drawing->width+SAFETY, // do not overlap
978 control_flow_data->drawing->height+SAFETY);
979
980
981 drawing_data_request(control_flow_data->drawing,
982 &control_flow_data->drawing->pixmap,
983 0, 0,
984 control_flow_data->drawing->width,
985 control_flow_data->drawing->height);
986
987 drawing_refresh(control_flow_data->drawing,
988 0, 0,
989 control_flow_data->drawing->width,
990 control_flow_data->drawing->height);
991 }
992
993 return 0;
994 }
995
996 gint update_current_time_hook(void *hook_data, void *call_data)
997 {
998 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
999
1000 LttTime* current_time =
1001 guicontrolflow_get_current_time(control_flow_data);
1002 *current_time = *((LttTime*)call_data);
1003
1004 TimeWindow time_window;
1005
1006 LttTime time_begin = control_flow_data->time_window.start_time;
1007 LttTime width = control_flow_data->time_window.time_width;
1008 LttTime half_width = ltt_time_div(width,2.0);
1009 LttTime time_end = ltt_time_add(time_begin, width);
1010
1011 LttvTracesetContext * tsc =
1012 get_traceset_context(control_flow_data->mw);
1013
1014 LttTime trace_start = tsc->Time_Span->startTime;
1015 LttTime trace_end = tsc->Time_Span->endTime;
1016
1017 g_info("New current time HOOK : %u, %u", current_time->tv_sec,
1018 current_time->tv_nsec);
1019
1020
1021
1022 /* If current time is inside time interval, just move the highlight
1023 * bar */
1024
1025 /* Else, we have to change the time interval. We have to tell it
1026 * to the main window. */
1027 /* The time interval change will take care of placing the current
1028 * time at the center of the visible area, or nearest possible if we are
1029 * at one end of the trace. */
1030
1031
1032 if(ltt_time_compare(*current_time, time_begin) == -1)
1033 {
1034 if(ltt_time_compare(*current_time,
1035 ltt_time_add(trace_start,half_width)) == -1)
1036 time_begin = trace_start;
1037 else
1038 time_begin = ltt_time_sub(*current_time,half_width);
1039
1040 time_window.start_time = time_begin;
1041 time_window.time_width = width;
1042
1043 set_time_window(control_flow_data->mw, &time_window);
1044 }
1045 else if(ltt_time_compare(*current_time, time_end) == 1)
1046 {
1047 if(ltt_time_compare(*current_time, ltt_time_sub(trace_end, half_width)) == 1)
1048 time_begin = ltt_time_sub(trace_end,width);
1049 else
1050 time_begin = ltt_time_sub(*current_time,half_width);
1051
1052 time_window.start_time = time_begin;
1053 time_window.time_width = width;
1054
1055 set_time_window(control_flow_data->mw, &time_window);
1056
1057 }
1058 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
1059
1060 return 0;
1061 }
1062
1063 typedef struct _ClosureData {
1064 EventRequest *event_request;
1065 LttvTraceState *ts;
1066 } ClosureData;
1067
1068
1069 void draw_closure(gpointer key, gpointer value, gpointer user_data)
1070 {
1071 ProcessInfo *process_info = (ProcessInfo*)key;
1072 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
1073 ClosureData *closure_data = (ClosureData*)user_data;
1074
1075 ControlFlowData *control_flow_data =
1076 closure_data->event_request->control_flow_data;
1077
1078 GtkWidget *widget = control_flow_data->drawing->drawing_area;
1079
1080 /* Get y position of process */
1081 gint y=0, height=0;
1082
1083 processlist_get_pixels_from_data( control_flow_data->process_list,
1084 process_info,
1085 hashed_process_data,
1086 &y,
1087 &height);
1088 /* Get last state of process */
1089 LttvTraceContext *tc =
1090 (LttvTraceContext *)closure_data->ts;
1091
1092 LttvTraceState *ts = closure_data->ts;
1093 LttvProcessState *process;
1094
1095 process = lttv_state_find_process((LttvTracefileState*)ts, process_info->pid);
1096
1097 /* Draw the closing line */
1098 DrawContext *draw_context = hashed_process_data->draw_context;
1099 if(draw_context->previous->middle->x == -1)
1100 {
1101 draw_context->previous->middle->x = closure_data->event_request->x_begin;
1102 g_critical("out middle x_beg : %u",closure_data->event_request->x_begin);
1103 }
1104
1105 draw_context->current->middle->x = closure_data->event_request->x_end;
1106 draw_context->current->middle->y = y + height/2;
1107 draw_context->previous->middle->y = y + height/2;
1108 draw_context->drawable = control_flow_data->drawing->pixmap;
1109 draw_context->pango_layout = control_flow_data->drawing->pango_layout;
1110 //draw_context->gc = widget->style->black_gc;
1111 draw_context->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1112 gdk_gc_copy(draw_context->gc, widget->style->black_gc);
1113
1114 PropertiesLine prop_line;
1115 prop_line.color = g_new(GdkColor,1);
1116 prop_line.line_width = 6;
1117 prop_line.style = GDK_LINE_SOLID;
1118 prop_line.position = MIDDLE;
1119
1120 /* color of line : status of the process */
1121 if(process->state->s == LTTV_STATE_UNNAMED)
1122 {
1123 prop_line.color->red = 0x0000;
1124 prop_line.color->green = 0x0000;
1125 prop_line.color->blue = 0x0000;
1126 }
1127 else if(process->state->s == LTTV_STATE_WAIT_FORK)
1128 {
1129 prop_line.color->red = 0x0fff;
1130 prop_line.color->green = 0x0000;
1131 prop_line.color->blue = 0x0fff;
1132 }
1133 else if(process->state->s == LTTV_STATE_WAIT_CPU)
1134 {
1135 prop_line.color->red = 0x0fff;
1136 prop_line.color->green = 0x0fff;
1137 prop_line.color->blue = 0x0000;
1138 }
1139 else if(process->state->s == LTTV_STATE_EXIT)
1140 {
1141 prop_line.color->red = 0xffff;
1142 prop_line.color->green = 0x0000;
1143 prop_line.color->blue = 0xffff;
1144 }
1145 else if(process->state->s == LTTV_STATE_WAIT)
1146 {
1147 prop_line.color->red = 0xffff;
1148 prop_line.color->green = 0x0000;
1149 prop_line.color->blue = 0x0000;
1150 }
1151 else if(process->state->s == LTTV_STATE_RUN)
1152 {
1153 prop_line.color->red = 0x0000;
1154 prop_line.color->green = 0xffff;
1155 prop_line.color->blue = 0x0000;
1156 }
1157 else
1158 {
1159 prop_line.color->red = 0x0000;
1160 prop_line.color->green = 0x0000;
1161 prop_line.color->blue = 0x0000;
1162 }
1163
1164 draw_line((void*)&prop_line, (void*)draw_context);
1165 g_free(prop_line.color);
1166 gdk_gc_unref(draw_context->gc);
1167
1168 /* Reset draw_context of the process for next request */
1169
1170 hashed_process_data->draw_context->drawable = NULL;
1171 hashed_process_data->draw_context->gc = NULL;
1172 hashed_process_data->draw_context->pango_layout = NULL;
1173 hashed_process_data->draw_context->current->over->x = -1;
1174 hashed_process_data->draw_context->current->over->y = -1;
1175 hashed_process_data->draw_context->current->middle->x = -1;
1176 hashed_process_data->draw_context->current->middle->y = -1;
1177 hashed_process_data->draw_context->current->under->x = -1;
1178 hashed_process_data->draw_context->current->under->y = -1;
1179 hashed_process_data->draw_context->current->modify_over->x = -1;
1180 hashed_process_data->draw_context->current->modify_over->y = -1;
1181 hashed_process_data->draw_context->current->modify_middle->x = -1;
1182 hashed_process_data->draw_context->current->modify_middle->y = -1;
1183 hashed_process_data->draw_context->current->modify_under->x = -1;
1184 hashed_process_data->draw_context->current->modify_under->y = -1;
1185 hashed_process_data->draw_context->current->status = LTTV_STATE_UNNAMED;
1186 hashed_process_data->draw_context->previous->over->x = -1;
1187 hashed_process_data->draw_context->previous->over->y = -1;
1188 hashed_process_data->draw_context->previous->middle->x = -1;
1189 hashed_process_data->draw_context->previous->middle->y = -1;
1190 hashed_process_data->draw_context->previous->under->x = -1;
1191 hashed_process_data->draw_context->previous->under->y = -1;
1192 hashed_process_data->draw_context->previous->modify_over->x = -1;
1193 hashed_process_data->draw_context->previous->modify_over->y = -1;
1194 hashed_process_data->draw_context->previous->modify_middle->x = -1;
1195 hashed_process_data->draw_context->previous->modify_middle->y = -1;
1196 hashed_process_data->draw_context->previous->modify_under->x = -1;
1197 hashed_process_data->draw_context->previous->modify_under->y = -1;
1198 hashed_process_data->draw_context->previous->status = LTTV_STATE_UNNAMED;
1199
1200
1201 }
1202
1203 /*
1204 * for each process
1205 * draw closing line
1206 * new default prev and current
1207 */
1208 int after_data_request(void *hook_data, void *call_data)
1209 {
1210 EventRequest *event_request = (EventRequest*)hook_data;
1211 ControlFlowData *control_flow_data = event_request->control_flow_data;
1212
1213 ProcessList *process_list =
1214 guicontrolflow_get_process_list(event_request->control_flow_data);
1215
1216 ClosureData closure_data;
1217 closure_data.event_request = (EventRequest*)hook_data;
1218 closure_data.ts = (LttvTraceState*)call_data;
1219
1220 g_hash_table_foreach(process_list->process_hash, draw_closure,
1221 (void*)&closure_data);
1222
1223 }
1224
This page took 0.053988 seconds and 5 git commands to generate.