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