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