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