traceset position save fix
[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
4e4d11b3 48#ifdef HAVE_CONFIG_H
49#include <config.h>
50#endif
b9a010a2 51
cf6cb7e0 52//#define PANGO_ENABLE_BACKEND
558aa013 53#include <gtk/gtk.h>
54#include <gdk/gdk.h>
5f16133f 55#include <glib.h>
80a52ff8 56#include <assert.h>
50439712 57#include <string.h>
319e9d81 58#include <stdio.h>
5f16133f 59
cf6cb7e0 60//#include <pango/pango.h>
61
80a52ff8 62#include <ltt/event.h>
4ba42155 63#include <ltt/time.h>
50439712 64#include <ltt/type.h>
2c82c4dc 65#include <ltt/trace.h>
80a52ff8 66
2a2fa4f0 67#include <lttv/lttv.h>
558aa013 68#include <lttv/hook.h>
80a52ff8 69#include <lttv/state.h>
2d262115 70#include <lttvwindow/lttvwindow.h>
6395d57c 71#include <lttvwindow/lttvwindowtraces.h>
80a52ff8 72
f0d936c0 73
a117e3f7 74#include "eventhooks.h"
75#include "cfv.h"
76#include "processlist.h"
77#include "drawing.h"
5f16133f 78
80a52ff8 79
1a31868c 80#define MAX_PATH_LEN 256
81
b9a010a2 82#if 0
83typedef struct _ProcessAddClosure {
84 ControlFlowData *cfd;
85 guint trace_num;
86} ProcessAddClosure;
87
88static void process_add(gpointer key,
89 gpointer value,
90 gpointer user_data)
91{
92 LttvProcessState *process = (LttvProcessState*)value;
93 ProcessAddClosure *closure = (ProcessAddClosure*)user_data;
94 ControlFlowData *control_flow_data = closure->cfd;
95 guint trace_num = closure->trace_num;
96
97 /* Add process to process list (if not present) */
98 guint pid;
99 LttTime birth;
100 guint y = 0, height = 0, pl_height = 0;
101
5c230fc4 102 ProcessList *process_list = control_flow_data->process_list;
b9a010a2 103
104 pid = process->pid;
105 birth = process->creation_time;
106 const gchar *name = g_quark_to_string(process->name);
107 HashedProcessData *hashed_process_data = NULL;
108
109 if(processlist_get_process_pixels(process_list,
110 pid,
111 &birth,
112 trace_num,
113 &y,
114 &height,
115 &hashed_process_data) == 1)
116 {
117 /* Process not present */
118 processlist_add(process_list,
119 pid,
120 &birth,
121 trace_num,
122 name,
123 &pl_height,
124 &hashed_process_data);
125 processlist_get_process_pixels(process_list,
126 pid,
127 &birth,
128 trace_num,
129 &y,
130 &height,
131 &hashed_process_data);
132 drawing_insert_square( control_flow_data->drawing, y, height);
133 }
134}
135#endif //0
136
137
6395d57c 138/* Action to do when background computation completed.
139 *
e800cf84 140 * Wait for all the awaited computations to be over.
6395d57c 141 */
142
143gint background_ready(void *hook_data, void *call_data)
144{
145 ControlFlowData *control_flow_data = (ControlFlowData *)hook_data;
146 LttvTrace *trace = (LttvTrace*)call_data;
147
e800cf84 148 control_flow_data->background_info_waiting--;
149
150 if(control_flow_data->background_info_waiting == 0) {
151 g_debug("control flow viewer : background computation data ready.");
6395d57c 152
e800cf84 153 drawing_clear(control_flow_data->drawing);
154 processlist_clear(control_flow_data->process_list);
07390ec1 155 gtk_widget_set_size_request(
156 control_flow_data->drawing->drawing_area,
157 -1, processlist_get_height(control_flow_data->process_list));
e800cf84 158 redraw_notify(control_flow_data, NULL);
b9a010a2 159 }
6395d57c 160
161 return 0;
162}
163
164
165/* Request background computation. Verify if it is in progress or ready first.
e800cf84 166 * Only for each trace in the tab's traceset.
6395d57c 167 */
168void request_background_data(ControlFlowData *control_flow_data)
169{
e800cf84 170 LttvTracesetContext * tsc =
171 lttvwindow_get_traceset_context(control_flow_data->tab);
172 gint num_traces = lttv_traceset_number(tsc->ts);
6395d57c 173 gint i;
174 LttvTrace *trace;
175
176 LttvHooks *background_ready_hook =
177 lttv_hooks_new();
178 lttv_hooks_add(background_ready_hook, background_ready, control_flow_data,
179 LTTV_PRIO_DEFAULT);
e800cf84 180 control_flow_data->background_info_waiting = 0;
6395d57c 181
182 for(i=0;i<num_traces;i++) {
e800cf84 183 trace = lttv_traceset_get(tsc->ts, i);
6395d57c 184
185 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
186
187 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
188 trace) == FALSE) {
189 /* We first remove requests that could have been done for the same
190 * information. Happens when two viewers ask for it before servicing
191 * starts.
192 */
193 lttvwindowtraces_background_request_remove(trace, "state");
194 lttvwindowtraces_background_request_queue(trace,
195 "state");
196 lttvwindowtraces_background_notify_queue(control_flow_data,
197 trace,
198 ltt_time_infinite,
199 NULL,
200 background_ready_hook);
e800cf84 201 control_flow_data->background_info_waiting++;
6395d57c 202 } else { /* in progress */
203
204 lttvwindowtraces_background_notify_current(control_flow_data,
205 trace,
206 ltt_time_infinite,
207 NULL,
208 background_ready_hook);
e800cf84 209 control_flow_data->background_info_waiting++;
6395d57c 210 }
4368b993 211 } else {
212 /* Data ready. Be its nature, this viewer doesn't need to have
213 * its data ready hook called htere, because a background
214 * request is always linked with a redraw.
215 */
6395d57c 216 }
4368b993 217
6395d57c 218 }
219
220 lttv_hooks_destroy(background_ready_hook);
221}
222
223
224
225
f0d936c0 226/**
227 * Event Viewer's constructor hook
228 *
229 * This constructor is given as a parameter to the menuitem and toolbar button
230 * registration. It creates the list.
ca0f8a8e 231 * @param tab A pointer to the parent tab.
f0d936c0 232 * @return The widget created.
233 */
234GtkWidget *
d47b33d2 235h_guicontrolflow(Tab *tab)
f0d936c0 236{
d47b33d2 237 g_info("h_guicontrolflow, %p", tab);
68997a22 238 ControlFlowData *control_flow_data = guicontrolflow() ;
a56a1ba4 239
ca0f8a8e 240 control_flow_data->tab = tab;
a56a1ba4 241
a56a1ba4 242 // Unreg done in the GuiControlFlow_Destructor
6395d57c 243 lttvwindow_register_traceset_notify(tab,
244 traceset_notify,
245 control_flow_data);
246
ca0f8a8e 247 lttvwindow_register_time_window_notify(tab,
224446ce 248 update_time_window_hook,
249 control_flow_data);
ca0f8a8e 250 lttvwindow_register_current_time_notify(tab,
224446ce 251 update_current_time_hook,
252 control_flow_data);
ca0f8a8e 253 lttvwindow_register_redraw_notify(tab,
254 redraw_notify,
255 control_flow_data);
256 lttvwindow_register_continue_notify(tab,
257 continue_notify,
258 control_flow_data);
667ca2a0 259 request_background_data(control_flow_data);
6395d57c 260
ca0f8a8e 261
68997a22 262 return guicontrolflow_get_widget(control_flow_data) ;
a56a1ba4 263
f0d936c0 264}
265
3cff8cc1 266int event_selected_hook(void *hook_data, void *call_data)
f0d936c0 267{
68997a22 268 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
14963be0 269 guint *event_number = (guint*) call_data;
f0d936c0 270
2a2fa4f0 271 g_debug("DEBUG : event selected by main window : %u", *event_number);
a56a1ba4 272
2eef04b5 273 return 0;
f0d936c0 274}
275
9a1ec01b 276/* Function that selects the color of status&exemode line */
6550d711 277static inline PropertiesLine prepare_s_e_line(LttvProcessState *process)
9a1ec01b 278{
279 PropertiesLine prop_line;
280 prop_line.line_width = 2;
281 prop_line.style = GDK_LINE_SOLID;
282 prop_line.y = MIDDLE;
283 //GdkColormap *colormap = gdk_colormap_get_system();
284
9a1ec01b 285 if(process->state->s == LTTV_STATE_RUN) {
286 if(process->state->t == LTTV_STATE_USER_MODE)
287 prop_line.color = drawing_colors[COL_RUN_USER_MODE];
288 else if(process->state->t == LTTV_STATE_SYSCALL)
289 prop_line.color = drawing_colors[COL_RUN_SYSCALL];
290 else if(process->state->t == LTTV_STATE_TRAP)
291 prop_line.color = drawing_colors[COL_RUN_TRAP];
292 else if(process->state->t == LTTV_STATE_IRQ)
293 prop_line.color = drawing_colors[COL_RUN_IRQ];
294 else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
295 prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
296 else
297 g_assert(FALSE); /* RUNNING MODE UNKNOWN */
298 } else if(process->state->s == LTTV_STATE_WAIT) {
299 /* We don't show if we wait while in user mode, trap, irq or syscall */
300 prop_line.color = drawing_colors[COL_WAIT];
301 } else if(process->state->s == LTTV_STATE_WAIT_CPU) {
302 /* We don't show if we wait for CPU while in user mode, trap, irq
303 * or syscall */
304 prop_line.color = drawing_colors[COL_WAIT_CPU];
305 } else if(process->state->s == LTTV_STATE_ZOMBIE) {
306 prop_line.color = drawing_colors[COL_ZOMBIE];
307 } else if(process->state->s == LTTV_STATE_WAIT_FORK) {
308 prop_line.color = drawing_colors[COL_WAIT_FORK];
309 } else if(process->state->s == LTTV_STATE_EXIT) {
310 prop_line.color = drawing_colors[COL_EXIT];
311 } else if(process->state->s == LTTV_STATE_UNNAMED) {
312 prop_line.color = drawing_colors[COL_UNNAMED];
313 } else
314 g_assert(FALSE); /* UNKNOWN STATE */
315
316 return prop_line;
317
318}
319
320#if 0
6550d711 321static inline PropertiesLine prepare_status_line(LttvProcessState *process)
c8bba5fa 322{
323 PropertiesLine prop_line;
324 prop_line.line_width = 2;
325 prop_line.style = GDK_LINE_SOLID;
e800cf84 326 prop_line.y = MIDDLE;
327 //GdkColormap *colormap = gdk_colormap_get_system();
c8bba5fa 328
23093869 329 g_debug("prepare_status_line for state : %s",
330 g_quark_to_string(process->state->s));
c8bba5fa 331
332 /* color of line : status of the process */
333 if(process->state->s == LTTV_STATE_UNNAMED)
e800cf84 334 prop_line.color = drawing_colors[COL_WHITE];
c8bba5fa 335 else if(process->state->s == LTTV_STATE_WAIT_FORK)
e800cf84 336 prop_line.color = drawing_colors[COL_WAIT_FORK];
c8bba5fa 337 else if(process->state->s == LTTV_STATE_WAIT_CPU)
e800cf84 338 prop_line.color = drawing_colors[COL_WAIT_CPU];
dbd243b1 339 else if(process->state->s == LTTV_STATE_EXIT)
340 prop_line.color = drawing_colors[COL_EXIT];
0828099d 341 else if(process->state->s == LTTV_STATE_ZOMBIE)
342 prop_line.color = drawing_colors[COL_ZOMBIE];
c8bba5fa 343 else if(process->state->s == LTTV_STATE_WAIT)
e800cf84 344 prop_line.color = drawing_colors[COL_WAIT];
c8bba5fa 345 else if(process->state->s == LTTV_STATE_RUN)
e800cf84 346 prop_line.color = drawing_colors[COL_RUN];
c8bba5fa 347 else
23093869 348 prop_line.color = drawing_colors[COL_WHITE];
e800cf84 349
350 //gdk_colormap_alloc_color(colormap,
351 // prop_line.color,
352 // FALSE,
353 // TRUE);
c8bba5fa 354
355 return prop_line;
356
357}
9a1ec01b 358#endif //0
c8bba5fa 359
360
e92eabaf 361/* before_schedchange_hook
b9a010a2 362 *
f0d936c0 363 * This function basically draw lines and icons. Two types of lines are drawn :
364 * one small (3 pixels?) representing the state of the process and the second
365 * type is thicker (10 pixels?) representing on which CPU a process is running
366 * (and this only in running state).
367 *
368 * Extremums of the lines :
369 * x_min : time of the last event context for this process kept in memory.
370 * x_max : time of the current event.
371 * y : middle of the process in the process list. The process is found in the
372 * list, therefore is it's position in pixels.
373 *
374 * The choice of lines'color is defined by the context of the last event for this
375 * process.
376 */
b9a010a2 377
378
e92eabaf 379int before_schedchange_hook(void *hook_data, void *call_data)
f0d936c0 380{
2c82c4dc 381 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
382 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
b9a010a2 383 ControlFlowData *control_flow_data = events_request->viewer_data;
384
385 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
386
387 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
348c6ba8 388 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
b9a010a2 389
390 LttEvent *e;
2c82c4dc 391 e = ltt_tracefile_get_event(tfc->tf);
b9a010a2 392
393 LttTime evtime = ltt_event_time(e);
fd22065b 394
10a1069a 395 /* we are in a schedchange, before the state update. We must draw the
396 * items corresponding to the state before it changes : now is the right
397 * time to do it.
398 */
b9a010a2 399
10a1069a 400 guint pid_out;
401 guint pid_in;
402 {
2c82c4dc 403 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
404 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
10a1069a 405 }
406
407 {
408 /* For the pid_out */
409 /* First, check if the current process is in the state computation
410 * process list. If it is there, that means we must add it right now and
411 * draw items from the beginning of the read for it. If it is not
412 * present, it's a new process and it was not present : it will
413 * be added after the state update. */
348c6ba8 414 guint cpu = ltt_tracefile_num(tfc->tf);
415 LttvProcessState *process = ts->running_process[cpu];
40debf7b 416 /* unknown state, bad current pid */
348c6ba8 417 if(process->pid != pid_out)
418 process = lttv_state_find_process(ts, ANY_CPU, pid_out);
b9a010a2 419
10a1069a 420 if(process != NULL) {
421 /* Well, the process_out existed : we must get it in the process hash
422 * or add it, and draw its items.
423 */
424 /* Add process to process list (if not present) */
1c736ed5 425 guint pl_height = 0;
10a1069a 426 HashedProcessData *hashed_process_data = NULL;
5c230fc4 427 ProcessList *process_list = control_flow_data->process_list;
10a1069a 428 LttTime birth = process->creation_time;
b9a010a2 429
ac4e21cf 430 hashed_process_data = processlist_get_process_data(process_list,
10a1069a 431 pid_out,
348c6ba8 432 process->cpu,
10a1069a 433 &birth,
ac4e21cf 434 tfc->t_context->index);
435 if(hashed_process_data == NULL)
10a1069a 436 {
437 g_assert(pid_out == 0 || pid_out != process->ppid);
aac69e70 438 const gchar *name = g_quark_to_string(process->name);
10a1069a 439 /* Process not present */
4e86ae2e 440 ProcessInfo *process_info;
1c736ed5 441 Drawing_t *drawing = control_flow_data->drawing;
10a1069a 442 processlist_add(process_list,
1c736ed5 443 drawing,
10a1069a 444 pid_out,
348c6ba8 445 process->cpu,
10a1069a 446 process->ppid,
447 &birth,
448 tfc->t_context->index,
449 name,
450 &pl_height,
4e86ae2e 451 &process_info,
10a1069a 452 &hashed_process_data);
1c736ed5 453 gtk_widget_set_size_request(drawing->drawing_area,
454 -1,
455 pl_height);
456 gtk_widget_queue_draw(drawing->drawing_area);
457
10a1069a 458 }
ac4e21cf 459
10a1069a 460 /* Now, the process is in the state hash and our own process hash.
461 * We definitely can draw the items related to the ending state.
462 */
e800cf84 463
b2743953 464 if(ltt_time_compare(hashed_process_data->next_good_time,
465 evtime) > 0)
10a1069a 466 {
b2743953 467 if(hashed_process_data->x.middle_marked == FALSE) {
ac4e21cf 468
fd22065b 469 TimeWindow time_window =
470 lttvwindow_get_time_window(control_flow_data->tab);
471#ifdef EXTRA_CHECK
472 if(ltt_time_compare(evtime, time_window.start_time) == -1
473 || ltt_time_compare(evtime, time_window.end_time) == 1)
474 return;
475#endif //EXTRA_CHECK
d6fef890 476 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 477 guint width = drawing->width;
b2743953 478 guint x;
479 convert_time_to_pixels(
480 time_window,
481 evtime,
482 width,
483 &x);
484
485 /* Draw collision indicator */
486 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 487 gdk_draw_point(hashed_process_data->pixmap,
b2743953 488 drawing->gc,
489 x,
1c736ed5 490 (hashed_process_data->height/2)-3);
b2743953 491 hashed_process_data->x.middle_marked = TRUE;
492 }
493 } else {
ac4e21cf 494 TimeWindow time_window =
495 lttvwindow_get_time_window(control_flow_data->tab);
fd22065b 496#ifdef EXTRA_CHECK
ac4e21cf 497 if(ltt_time_compare(evtime, time_window.start_time) == -1
498 || ltt_time_compare(evtime, time_window.end_time) == 1)
499 return;
fd22065b 500#endif //EXTRA_CHECK
d6fef890 501 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 502 guint width = drawing->width;
10a1069a 503 guint x;
10a1069a 504 convert_time_to_pixels(
a18124ff 505 time_window,
4b7dc462 506 evtime,
507 width,
508 &x);
10a1069a 509
10a1069a 510
4b7dc462 511 /* Jump over draw if we are at the same x position */
e72908ed 512 if(x == hashed_process_data->x.middle &&
513 hashed_process_data->x.middle_used)
e800cf84 514 {
e72908ed 515 if(hashed_process_data->x.middle_marked == FALSE) {
516 /* Draw collision indicator */
517 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 518 gdk_draw_point(hashed_process_data->pixmap,
e72908ed 519 drawing->gc,
520 x,
1c736ed5 521 (hashed_process_data->height/2)-3);
de4ea1ad 522 hashed_process_data->x.middle_marked = TRUE;
e72908ed 523 }
4b7dc462 524 /* jump */
525 } else {
526 DrawContext draw_context;
10a1069a 527
4b7dc462 528 /* Now create the drawing context that will be used to draw
529 * items related to the last state. */
1c736ed5 530 draw_context.drawable = hashed_process_data->pixmap;
4b7dc462 531 draw_context.gc = drawing->gc;
532 draw_context.pango_layout = drawing->pango_layout;
533 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
534 draw_context.drawinfo.end.x = x;
535
1c736ed5 536 draw_context.drawinfo.y.over = 1;
537 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
538 draw_context.drawinfo.y.under = hashed_process_data->height;
4b7dc462 539
540 draw_context.drawinfo.start.offset.over = 0;
541 draw_context.drawinfo.start.offset.middle = 0;
542 draw_context.drawinfo.start.offset.under = 0;
543 draw_context.drawinfo.end.offset.over = 0;
544 draw_context.drawinfo.end.offset.middle = 0;
545 draw_context.drawinfo.end.offset.under = 0;
546
547 {
548 /* Draw the line */
9a1ec01b 549 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 550 draw_line((void*)&prop_line, (void*)&draw_context);
551
552 }
553 /* become the last x position */
554 hashed_process_data->x.middle = x;
e72908ed 555 hashed_process_data->x.middle_used = TRUE;
556 hashed_process_data->x.middle_marked = FALSE;
b2743953 557
558 /* Calculate the next good time */
559 convert_pixels_to_time(width, x+1, time_window,
560 &hashed_process_data->next_good_time);
e800cf84 561 }
562 }
563 }
10a1069a 564 }
e800cf84 565
10a1069a 566 {
567 /* For the pid_in */
568 /* First, check if the current process is in the state computation
569 * process list. If it is there, that means we must add it right now and
570 * draw items from the beginning of the read for it. If it is not
571 * present, it's a new process and it was not present : it will
572 * be added after the state update. */
573 LttvProcessState *process;
348c6ba8 574 process = lttv_state_find_process(ts, ANY_CPU, pid_in);
10a1069a 575
576 if(process != NULL) {
577 /* Well, the process_out existed : we must get it in the process hash
578 * or add it, and draw its items.
579 */
580 /* Add process to process list (if not present) */
1c736ed5 581 guint pl_height = 0;
10a1069a 582 HashedProcessData *hashed_process_data = NULL;
5c230fc4 583 ProcessList *process_list = control_flow_data->process_list;
10a1069a 584 LttTime birth = process->creation_time;
e800cf84 585
ac4e21cf 586 hashed_process_data = processlist_get_process_data(process_list,
10a1069a 587 pid_in,
348c6ba8 588 process->cpu,
10a1069a 589 &birth,
ac4e21cf 590 tfc->t_context->index);
591 if(hashed_process_data == NULL)
10a1069a 592 {
593 g_assert(pid_in == 0 || pid_in != process->ppid);
aac69e70 594 const gchar *name = g_quark_to_string(process->name);
10a1069a 595 /* Process not present */
4e86ae2e 596 ProcessInfo *process_info;
1c736ed5 597 Drawing_t *drawing = control_flow_data->drawing;
10a1069a 598 processlist_add(process_list,
1c736ed5 599 drawing,
10a1069a 600 pid_in,
348c6ba8 601 process->cpu,
10a1069a 602 process->ppid,
603 &birth,
604 tfc->t_context->index,
605 name,
606 &pl_height,
4e86ae2e 607 &process_info,
10a1069a 608 &hashed_process_data);
1c736ed5 609 gtk_widget_set_size_request(drawing->drawing_area,
610 -1,
611 pl_height);
612 gtk_widget_queue_draw(drawing->drawing_area);
613
10a1069a 614 }
40debf7b 615 //We could set the current process and hash here, but will be done
616 //by after schedchange hook
10a1069a 617
618 /* Now, the process is in the state hash and our own process hash.
619 * We definitely can draw the items related to the ending state.
620 */
b9a010a2 621
b2743953 622 if(ltt_time_compare(hashed_process_data->next_good_time,
623 evtime) > 0)
10a1069a 624 {
b2743953 625 if(hashed_process_data->x.middle_marked == FALSE) {
ac4e21cf 626
fd22065b 627 TimeWindow time_window =
628 lttvwindow_get_time_window(control_flow_data->tab);
629#ifdef EXTRA_CHECK
630 if(ltt_time_compare(evtime, time_window.start_time) == -1
631 || ltt_time_compare(evtime, time_window.end_time) == 1)
632 return;
633#endif //EXTRA_CHECK
d6fef890 634 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 635 guint width = drawing->width;
b2743953 636 guint x;
637 convert_time_to_pixels(
638 time_window,
639 evtime,
640 width,
641 &x);
642
643 /* Draw collision indicator */
644 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 645 gdk_draw_point(hashed_process_data->pixmap,
b2743953 646 drawing->gc,
647 x,
1c736ed5 648 (hashed_process_data->height/2)-3);
b2743953 649 hashed_process_data->x.middle_marked = TRUE;
650 }
651 } else {
fd22065b 652 TimeWindow time_window =
653 lttvwindow_get_time_window(control_flow_data->tab);
654#ifdef EXTRA_CHECK
655 if(ltt_time_compare(evtime, time_window.start_time) == -1
656 || ltt_time_compare(evtime, time_window.end_time) == 1)
657 return;
658#endif //EXTRA_CHECK
d6fef890 659 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 660 guint width = drawing->width;
10a1069a 661 guint x;
10a1069a 662
663 convert_time_to_pixels(
a18124ff 664 time_window,
4b7dc462 665 evtime,
666 width,
667 &x);
10a1069a 668
10a1069a 669
4b7dc462 670 /* Jump over draw if we are at the same x position */
e72908ed 671 if(x == hashed_process_data->x.middle &&
672 hashed_process_data->x.middle_used)
4b7dc462 673 {
e72908ed 674 if(hashed_process_data->x.middle_marked == FALSE) {
675 /* Draw collision indicator */
676 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 677 gdk_draw_point(hashed_process_data->pixmap,
e72908ed 678 drawing->gc,
679 x,
1c736ed5 680 (hashed_process_data->height/2)-3);
de4ea1ad 681 hashed_process_data->x.middle_marked = TRUE;
e72908ed 682 }
4b7dc462 683 /* jump */
684 } else {
685 DrawContext draw_context;
10a1069a 686
4b7dc462 687 /* Now create the drawing context that will be used to draw
688 * items related to the last state. */
1c736ed5 689 draw_context.drawable = hashed_process_data->pixmap;
4b7dc462 690 draw_context.gc = drawing->gc;
691 draw_context.pango_layout = drawing->pango_layout;
692 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
693 draw_context.drawinfo.end.x = x;
10a1069a 694
1c736ed5 695 draw_context.drawinfo.y.over = 1;
696 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
697 draw_context.drawinfo.y.under = hashed_process_data->height;
10a1069a 698
4b7dc462 699 draw_context.drawinfo.start.offset.over = 0;
700 draw_context.drawinfo.start.offset.middle = 0;
701 draw_context.drawinfo.start.offset.under = 0;
702 draw_context.drawinfo.end.offset.over = 0;
703 draw_context.drawinfo.end.offset.middle = 0;
704 draw_context.drawinfo.end.offset.under = 0;
705
706 {
707 /* Draw the line */
9a1ec01b 708 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 709 draw_line((void*)&prop_line, (void*)&draw_context);
710 }
711
712
713 /* become the last x position */
714 hashed_process_data->x.middle = x;
e72908ed 715 hashed_process_data->x.middle_used = TRUE;
716 hashed_process_data->x.middle_marked = FALSE;
b2743953 717
718 /* Calculate the next good time */
719 convert_pixels_to_time(width, x+1, time_window,
720 &hashed_process_data->next_good_time);
4b7dc462 721 }
c8bba5fa 722 }
b9a010a2 723 }
724 }
b9a010a2 725 return 0;
726
727
b9a010a2 728#if 0
ca0f8a8e 729 EventsRequest *events_request = (EventsRequest*)hook_data;
730 ControlFlowData *control_flow_data =
731 (ControlFlowData*)events_request->viewer_data;
732 Tab *tab = control_flow_data->tab;
e9a9c513 733
a56a1ba4 734 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
e9a9c513 735
736 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1aff52a2 737 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
a56a1ba4 738
e9a9c513 739 LttEvent *e;
e9a9c513 740 e = tfc->e;
741
9444deae 742 LttTime evtime = ltt_event_time(e);
ca0f8a8e 743 TimeWindow time_window =
744 lttvwindow_get_time_window(tab);
9444deae 745
a2aab3a3 746 LttTime time_window.end_time = time_window.time_window.end_time;
6f26fc38 747
9444deae 748 //if(time < time_beg || time > time_end) return;
ca0f8a8e 749 if(ltt_time_compare(evtime, time_window.start_time) == -1
a2aab3a3 750 || ltt_time_compare(evtime, time_window.end_time) == 1)
9444deae 751 return;
752
a56a1ba4 753 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
754 {
2a2fa4f0 755 g_debug("schedchange!");
a56a1ba4 756
757 /* Add process to process list (if not present) and get drawing "y" from
758 * process position */
759 guint pid_out, pid_in;
760 LttvProcessState *process_out, *process_in;
761 LttTime birth;
762 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
763
5c230fc4 764 ProcessList *process_list = control_flow_data->process_list;
a56a1ba4 765
766
767 LttField *f = ltt_event_field(e);
768 LttField *element;
769 element = ltt_field_member(f,0);
770 pid_out = ltt_event_get_long_unsigned(e,element);
771 element = ltt_field_member(f,1);
772 pid_in = ltt_event_get_long_unsigned(e,element);
2a2fa4f0 773 g_debug("out : %u in : %u", pid_out, pid_in);
a56a1ba4 774
775
776 /* Find process pid_out in the list... */
87658614 777 process_out = lttv_state_find_process(tfs, pid_out);
1aff52a2 778 if(process_out == NULL) return 0;
2a2fa4f0 779 g_debug("out : %s",g_quark_to_string(process_out->state->s));
1aff52a2 780
a56a1ba4 781 birth = process_out->creation_time;
51705146 782 const gchar *name = g_quark_to_string(process_out->name);
14963be0 783 HashedProcessData *hashed_process_data_out = NULL;
a56a1ba4 784
785 if(processlist_get_process_pixels(process_list,
786 pid_out,
787 &birth,
d0cd7f09 788 tfc->t_context->index,
a56a1ba4 789 &y_out,
790 &height,
14963be0 791 &hashed_process_data_out) == 1)
a56a1ba4 792 {
51705146 793 /* Process not present */
794 processlist_add(process_list,
795 pid_out,
796 &birth,
797 tfc->t_context->index,
798 name,
799 &pl_height,
800 &hashed_process_data_out);
801 g_assert(processlist_get_process_pixels(process_list,
802 pid_out,
803 &birth,
804 tfc->t_context->index,
805 &y_out,
806 &height,
807 &hashed_process_data_out)==0);
808 drawing_insert_square( control_flow_data->drawing, y_out, height);
a56a1ba4 809 }
51705146 810 //g_free(name);
a56a1ba4 811
812 /* Find process pid_in in the list... */
87658614 813 process_in = lttv_state_find_process(tfs, pid_in);
1aff52a2 814 if(process_in == NULL) return 0;
2a2fa4f0 815 g_debug("in : %s",g_quark_to_string(process_in->state->s));
a56a1ba4 816
817 birth = process_in->creation_time;
51705146 818 name = g_quark_to_string(process_in->name);
14963be0 819 HashedProcessData *hashed_process_data_in = NULL;
a56a1ba4 820
821 if(processlist_get_process_pixels(process_list,
822 pid_in,
823 &birth,
d0cd7f09 824 tfc->t_context->index,
a56a1ba4 825 &y_in,
826 &height,
14963be0 827 &hashed_process_data_in) == 1)
a56a1ba4 828 {
51705146 829 /* Process not present */
a56a1ba4 830 processlist_add(process_list,
831 pid_in,
832 &birth,
d0cd7f09 833 tfc->t_context->index,
a56a1ba4 834 name,
835 &pl_height,
14963be0 836 &hashed_process_data_in);
a56a1ba4 837 processlist_get_process_pixels(process_list,
838 pid_in,
839 &birth,
d0cd7f09 840 tfc->t_context->index,
a56a1ba4 841 &y_in,
842 &height,
14963be0 843 &hashed_process_data_in);
a56a1ba4 844
ca0f8a8e 845 drawing_insert_square( control_flow_data->drawing, y_in, height);
a56a1ba4 846 }
51705146 847 //g_free(name);
a56a1ba4 848
849
850 /* Find pixels corresponding to time of the event. If the time does
851 * not fit in the window, show a warning, not supposed to happend. */
852 guint x = 0;
51705146 853 guint width = control_flow_data->drawing->width;
a56a1ba4 854
855 LttTime time = ltt_event_time(e);
856
a2aab3a3 857 LttTime window_end = time_window.time_window.end_time;
a56a1ba4 858
859 convert_time_to_pixels(
a18124ff 860 time_window,
a56a1ba4 861 time,
862 width,
863 &x);
9444deae 864 //assert(x <= width);
51705146 865 //
a56a1ba4 866 /* draw what represents the event for outgoing process. */
867
14963be0 868 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
68997a22 869 draw_context_out->current->modify_over->x = x;
319e9d81 870 draw_context_out->current->modify_under->x = x;
68997a22 871 draw_context_out->current->modify_over->y = y_out;
319e9d81 872 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
501d5405 873 draw_context_out->drawable = control_flow_data->drawing->pixmap;
874 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
875 GtkWidget *widget = control_flow_data->drawing->drawing_area;
a56a1ba4 876 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
d0cd7f09 877 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
878 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
a56a1ba4 879 //draw_context_out->gc = widget->style->black_gc;
880
881 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
501d5405 882 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
a56a1ba4 883
d0cd7f09 884 /* Draw the line/background of the out process */
885 if(draw_context_out->previous->middle->x == -1)
886 {
ca0f8a8e 887 draw_context_out->previous->over->x =
888 control_flow_data->drawing->damage_begin;
889 draw_context_out->previous->middle->x =
890 control_flow_data->drawing->damage_begin;
891 draw_context_out->previous->under->x =
892 control_flow_data->drawing->damage_begin;
ca0f8a8e 893 g_debug("out middle x_beg : %u",control_flow_data->drawing->damage_begin);
d0cd7f09 894 }
895
896 draw_context_out->current->middle->x = x;
897 draw_context_out->current->over->x = x;
898 draw_context_out->current->under->x = x;
899 draw_context_out->current->middle->y = y_out + height/2;
900 draw_context_out->current->over->y = y_out;
901 draw_context_out->current->under->y = y_out + height;
902 draw_context_out->previous->middle->y = y_out + height/2;
903 draw_context_out->previous->over->y = y_out;
904 draw_context_out->previous->under->y = y_out + height;
905
906 draw_context_out->drawable = control_flow_data->drawing->pixmap;
907 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
908
909 if(process_out->state->s == LTTV_STATE_RUN)
910 {
51705146 911 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
912 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
913 draw_context_out->gc = control_flow_data->drawing->gc;
d0cd7f09 914
915 PropertiesBG prop_bg;
916 prop_bg.color = g_new(GdkColor,1);
917
2c82c4dc 918 switch(ltt_tracefile_num(tfc->tf)) {
d0cd7f09 919 case 0:
920 prop_bg.color->red = 0x1515;
921 prop_bg.color->green = 0x1515;
922 prop_bg.color->blue = 0x8c8c;
923 break;
924 case 1:
925 prop_bg.color->red = 0x4e4e;
926 prop_bg.color->green = 0xa9a9;
927 prop_bg.color->blue = 0xa4a4;
928 break;
929 case 2:
930 prop_bg.color->red = 0x7a7a;
931 prop_bg.color->green = 0x4a4a;
932 prop_bg.color->blue = 0x8b8b;
933 break;
934 case 3:
935 prop_bg.color->red = 0x8080;
936 prop_bg.color->green = 0x7777;
937 prop_bg.color->blue = 0x4747;
938 break;
939 default:
940 prop_bg.color->red = 0xe7e7;
941 prop_bg.color->green = 0xe7e7;
942 prop_bg.color->blue = 0xe7e7;
943 }
944
2a2fa4f0 945 g_debug("calling from draw_event");
d0cd7f09 946 draw_bg((void*)&prop_bg, (void*)draw_context_out);
947 g_free(prop_bg.color);
51705146 948 //gdk_gc_unref(draw_context_out->gc);
d0cd7f09 949 }
950
951 draw_context_out->gc = widget->style->black_gc;
952
a56a1ba4 953 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
2df6f2bd 954 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 955 PropertiesText prop_text_out;
956 prop_text_out.foreground = &colorfg_out;
957 prop_text_out.background = &colorbg_out;
cfe526b1 958 prop_text_out.size = 6;
a56a1ba4 959 prop_text_out.position = OVER;
960
cfe526b1 961 /* color of text : status of the process */
962 if(process_out->state->s == LTTV_STATE_UNNAMED)
963 {
964 prop_text_out.foreground->red = 0xffff;
965 prop_text_out.foreground->green = 0xffff;
966 prop_text_out.foreground->blue = 0xffff;
967 }
968 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
969 {
970 prop_text_out.foreground->red = 0x0fff;
d52cfc84 971 prop_text_out.foreground->green = 0xffff;
972 prop_text_out.foreground->blue = 0xfff0;
cfe526b1 973 }
974 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
975 {
2df6f2bd 976 prop_text_out.foreground->red = 0xffff;
977 prop_text_out.foreground->green = 0xffff;
cfe526b1 978 prop_text_out.foreground->blue = 0x0000;
979 }
0828099d 980 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 981 {
982 prop_text_out.foreground->red = 0xffff;
983 prop_text_out.foreground->green = 0x0000;
984 prop_text_out.foreground->blue = 0xffff;
985 }
986 else if(process_out->state->s == LTTV_STATE_WAIT)
987 {
988 prop_text_out.foreground->red = 0xffff;
989 prop_text_out.foreground->green = 0x0000;
990 prop_text_out.foreground->blue = 0x0000;
991 }
992 else if(process_out->state->s == LTTV_STATE_RUN)
993 {
994 prop_text_out.foreground->red = 0x0000;
995 prop_text_out.foreground->green = 0xffff;
996 prop_text_out.foreground->blue = 0x0000;
997 }
998 else
999 {
1000 prop_text_out.foreground->red = 0xffff;
1001 prop_text_out.foreground->green = 0xffff;
1002 prop_text_out.foreground->blue = 0xffff;
1003 }
1004
d52cfc84 1005
a56a1ba4 1006 /* Print status of the process : U, WF, WC, E, W, R */
1007 if(process_out->state->s == LTTV_STATE_UNNAMED)
cfe526b1 1008 prop_text_out.text = "U->";
a56a1ba4 1009 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
cfe526b1 1010 prop_text_out.text = "WF->";
a56a1ba4 1011 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
cfe526b1 1012 prop_text_out.text = "WC->";
0828099d 1013 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1014 prop_text_out.text = "E->";
a56a1ba4 1015 else if(process_out->state->s == LTTV_STATE_WAIT)
cfe526b1 1016 prop_text_out.text = "W->";
a56a1ba4 1017 else if(process_out->state->s == LTTV_STATE_RUN)
cfe526b1 1018 prop_text_out.text = "R->";
a56a1ba4 1019 else
68997a22 1020 prop_text_out.text = "U";
a56a1ba4 1021
1022 draw_text((void*)&prop_text_out, (void*)draw_context_out);
d0cd7f09 1023 //gdk_gc_unref(draw_context_out->gc);
a56a1ba4 1024
51705146 1025 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1026 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1027 draw_context_out->gc = control_flow_data->drawing->gc;
a56a1ba4 1028
1029 PropertiesLine prop_line_out;
1030 prop_line_out.color = g_new(GdkColor,1);
cfe526b1 1031 prop_line_out.line_width = 2;
a56a1ba4 1032 prop_line_out.style = GDK_LINE_SOLID;
1033 prop_line_out.position = MIDDLE;
d52cfc84 1034
2a2fa4f0 1035 g_debug("out state : %s", g_quark_to_string(process_out->state->s));
a56a1ba4 1036
1037 /* color of line : status of the process */
1038 if(process_out->state->s == LTTV_STATE_UNNAMED)
1039 {
cfe526b1 1040 prop_line_out.color->red = 0xffff;
1041 prop_line_out.color->green = 0xffff;
1042 prop_line_out.color->blue = 0xffff;
a56a1ba4 1043 }
1044 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1045 {
1046 prop_line_out.color->red = 0x0fff;
d52cfc84 1047 prop_line_out.color->green = 0xffff;
1048 prop_line_out.color->blue = 0xfff0;
a56a1ba4 1049 }
1050 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1051 {
2df6f2bd 1052 prop_line_out.color->red = 0xffff;
1053 prop_line_out.color->green = 0xffff;
a56a1ba4 1054 prop_line_out.color->blue = 0x0000;
1055 }
0828099d 1056 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
a56a1ba4 1057 {
1058 prop_line_out.color->red = 0xffff;
1059 prop_line_out.color->green = 0x0000;
1060 prop_line_out.color->blue = 0xffff;
1061 }
1062 else if(process_out->state->s == LTTV_STATE_WAIT)
1063 {
1064 prop_line_out.color->red = 0xffff;
1065 prop_line_out.color->green = 0x0000;
1066 prop_line_out.color->blue = 0x0000;
1067 }
1068 else if(process_out->state->s == LTTV_STATE_RUN)
1069 {
1070 prop_line_out.color->red = 0x0000;
1071 prop_line_out.color->green = 0xffff;
1072 prop_line_out.color->blue = 0x0000;
1073 }
1074 else
1075 {
cfe526b1 1076 prop_line_out.color->red = 0xffff;
1077 prop_line_out.color->green = 0xffff;
1078 prop_line_out.color->blue = 0xffff;
a56a1ba4 1079 }
1080
1081 draw_line((void*)&prop_line_out, (void*)draw_context_out);
1082 g_free(prop_line_out.color);
51705146 1083 //gdk_gc_unref(draw_context_out->gc);
a56a1ba4 1084 /* Note : finishing line will have to be added when trace read over. */
1085
1086 /* Finally, update the drawing context of the pid_in. */
1087
14963be0 1088 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
68997a22 1089 draw_context_in->current->modify_over->x = x;
319e9d81 1090 draw_context_in->current->modify_under->x = x;
68997a22 1091 draw_context_in->current->modify_over->y = y_in;
319e9d81 1092 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
501d5405 1093 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1094 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1095 widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1096 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1097 //draw_context_in->gc = widget->style->black_gc;
d0cd7f09 1098 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1099 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
a56a1ba4 1100
1101 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
501d5405 1102 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1103
1104 /* Draw the line/bg of the in process */
1105 if(draw_context_in->previous->middle->x == -1)
1106 {
ca0f8a8e 1107 draw_context_in->previous->over->x =
1108 control_flow_data->drawing->damage_begin;
1109 draw_context_in->previous->middle->x =
1110 control_flow_data->drawing->damage_begin;
1111 draw_context_in->previous->under->x =
1112 control_flow_data->drawing->damage_begin;
1113
1114 g_debug("in middle x_beg : %u",control_flow_data->drawing->damage_begin);
1115
d0cd7f09 1116 }
1117
1118 draw_context_in->current->middle->x = x;
1119 draw_context_in->current->over->x = x;
1120 draw_context_in->current->under->x = x;
1121 draw_context_in->current->middle->y = y_in + height/2;
1122 draw_context_in->current->over->y = y_in;
1123 draw_context_in->current->under->y = y_in + height;
1124 draw_context_in->previous->middle->y = y_in + height/2;
1125 draw_context_in->previous->over->y = y_in;
1126 draw_context_in->previous->under->y = y_in + height;
a56a1ba4 1127
d0cd7f09 1128 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1129 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1130
1131
1132 if(process_in->state->s == LTTV_STATE_RUN)
1133 {
51705146 1134 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1135 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1136 draw_context_in->gc = control_flow_data->drawing->gc;
d0cd7f09 1137
1138 PropertiesBG prop_bg;
1139 prop_bg.color = g_new(GdkColor,1);
1140
2c82c4dc 1141 switcht(ltt_tracefile_num(tfc->tf)) {
d0cd7f09 1142 case 0:
1143 prop_bg.color->red = 0x1515;
1144 prop_bg.color->green = 0x1515;
1145 prop_bg.color->blue = 0x8c8c;
1146 break;
1147 case 1:
1148 prop_bg.color->red = 0x4e4e;
1149 prop_bg.color->green = 0xa9a9;
1150 prop_bg.color->blue = 0xa4a4;
1151 break;
1152 case 2:
1153 prop_bg.color->red = 0x7a7a;
1154 prop_bg.color->green = 0x4a4a;
1155 prop_bg.color->blue = 0x8b8b;
1156 break;
1157 case 3:
1158 prop_bg.color->red = 0x8080;
1159 prop_bg.color->green = 0x7777;
1160 prop_bg.color->blue = 0x4747;
1161 break;
1162 default:
1163 prop_bg.color->red = 0xe7e7;
1164 prop_bg.color->green = 0xe7e7;
1165 prop_bg.color->blue = 0xe7e7;
1166 }
1167
1168
1169 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1170 g_free(prop_bg.color);
51705146 1171 //gdk_gc_unref(draw_context_in->gc);
d0cd7f09 1172 }
1173
1174 draw_context_in->gc = widget->style->black_gc;
1175
a56a1ba4 1176 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
2df6f2bd 1177 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1178 PropertiesText prop_text_in;
1179 prop_text_in.foreground = &colorfg_in;
1180 prop_text_in.background = &colorbg_in;
cfe526b1 1181 prop_text_in.size = 6;
a56a1ba4 1182 prop_text_in.position = OVER;
1183
2a2fa4f0 1184 g_debug("in state : %s", g_quark_to_string(process_in->state->s));
cfe526b1 1185 /* foreground of text : status of the process */
1186 if(process_in->state->s == LTTV_STATE_UNNAMED)
1187 {
1188 prop_text_in.foreground->red = 0xffff;
1189 prop_text_in.foreground->green = 0xffff;
1190 prop_text_in.foreground->blue = 0xffff;
1191 }
1192 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1193 {
1194 prop_text_in.foreground->red = 0x0fff;
d52cfc84 1195 prop_text_in.foreground->green = 0xffff;
1196 prop_text_in.foreground->blue = 0xfff0;
cfe526b1 1197 }
1198 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1199 {
2df6f2bd 1200 prop_text_in.foreground->red = 0xffff;
1201 prop_text_in.foreground->green = 0xffff;
cfe526b1 1202 prop_text_in.foreground->blue = 0x0000;
1203 }
0828099d 1204 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1205 {
1206 prop_text_in.foreground->red = 0xffff;
1207 prop_text_in.foreground->green = 0x0000;
1208 prop_text_in.foreground->blue = 0xffff;
1209 }
1210 else if(process_in->state->s == LTTV_STATE_WAIT)
1211 {
1212 prop_text_in.foreground->red = 0xffff;
1213 prop_text_in.foreground->green = 0x0000;
1214 prop_text_in.foreground->blue = 0x0000;
1215 }
1216 else if(process_in->state->s == LTTV_STATE_RUN)
1217 {
1218 prop_text_in.foreground->red = 0x0000;
1219 prop_text_in.foreground->green = 0xffff;
1220 prop_text_in.foreground->blue = 0x0000;
1221 }
1222 else
1223 {
1224 prop_text_in.foreground->red = 0xffff;
1225 prop_text_in.foreground->green = 0xffff;
1226 prop_text_in.foreground->blue = 0xffff;
1227 }
1228
1229
1230
a56a1ba4 1231 /* Print status of the process : U, WF, WC, E, W, R */
1232 if(process_in->state->s == LTTV_STATE_UNNAMED)
cfe526b1 1233 prop_text_in.text = "U->";
a56a1ba4 1234 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
cfe526b1 1235 prop_text_in.text = "WF->";
a56a1ba4 1236 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
cfe526b1 1237 prop_text_in.text = "WC->";
0828099d 1238 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1239 prop_text_in.text = "E->";
a56a1ba4 1240 else if(process_in->state->s == LTTV_STATE_WAIT)
cfe526b1 1241 prop_text_in.text = "W->";
a56a1ba4 1242 else if(process_in->state->s == LTTV_STATE_RUN)
cfe526b1 1243 prop_text_in.text = "R->";
a56a1ba4 1244 else
68997a22 1245 prop_text_in.text = "U";
a56a1ba4 1246
1247 draw_text((void*)&prop_text_in, (void*)draw_context_in);
d0cd7f09 1248 //gdk_gc_unref(draw_context_in->gc);
1249
51705146 1250 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1251 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1252 draw_context_in->gc = control_flow_data->drawing->gc;
d0cd7f09 1253
a56a1ba4 1254 PropertiesLine prop_line_in;
1255 prop_line_in.color = g_new(GdkColor,1);
cfe526b1 1256 prop_line_in.line_width = 2;
a56a1ba4 1257 prop_line_in.style = GDK_LINE_SOLID;
1258 prop_line_in.position = MIDDLE;
1259
1260 /* color of line : status of the process */
1261 if(process_in->state->s == LTTV_STATE_UNNAMED)
1262 {
cfe526b1 1263 prop_line_in.color->red = 0xffff;
1264 prop_line_in.color->green = 0xffff;
1265 prop_line_in.color->blue = 0xffff;
a56a1ba4 1266 }
1267 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1268 {
1269 prop_line_in.color->red = 0x0fff;
d52cfc84 1270 prop_line_in.color->green = 0xffff;
1271 prop_line_in.color->blue = 0xfff0;
a56a1ba4 1272 }
1273 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1274 {
2df6f2bd 1275 prop_line_in.color->red = 0xffff;
1276 prop_line_in.color->green = 0xffff;
a56a1ba4 1277 prop_line_in.color->blue = 0x0000;
1278 }
0828099d 1279 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
a56a1ba4 1280 {
1281 prop_line_in.color->red = 0xffff;
1282 prop_line_in.color->green = 0x0000;
1283 prop_line_in.color->blue = 0xffff;
1284 }
1285 else if(process_in->state->s == LTTV_STATE_WAIT)
1286 {
1287 prop_line_in.color->red = 0xffff;
1288 prop_line_in.color->green = 0x0000;
1289 prop_line_in.color->blue = 0x0000;
1290 }
1291 else if(process_in->state->s == LTTV_STATE_RUN)
1292 {
1293 prop_line_in.color->red = 0x0000;
1294 prop_line_in.color->green = 0xffff;
1295 prop_line_in.color->blue = 0x0000;
1296 }
1297 else
1298 {
cfe526b1 1299 prop_line_in.color->red = 0xffff;
1300 prop_line_in.color->green = 0xffff;
1301 prop_line_in.color->blue = 0xffff;
a56a1ba4 1302 }
1303
1304 draw_line((void*)&prop_line_in, (void*)draw_context_in);
1305 g_free(prop_line_in.color);
51705146 1306 //gdk_gc_unref(draw_context_in->gc);
a56a1ba4 1307 }
1308
1309 return 0;
b9a010a2 1310#endif //0
1311
1312
a56a1ba4 1313
51705146 1314 /* Text dump */
80a52ff8 1315#ifdef DONTSHOW
a56a1ba4 1316 GString *string = g_string_new("");;
1317 gboolean field_names = TRUE, state = TRUE;
80a52ff8 1318
e9a9c513 1319 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
1320 g_string_append_printf(string,"\n");
1321
1322 if(state) {
1323 g_string_append_printf(string, " %s",
1324 g_quark_to_string(tfs->process->state->s));
1325 }
1326
1327 g_info("%s",string->str);
1328
a56a1ba4 1329 g_string_free(string, TRUE);
1330
1331 /* End of text dump */
80a52ff8 1332#endif //DONTSHOW
50439712 1333
f0d936c0 1334}
1335
e92eabaf 1336/* after_schedchange_hook
b9a010a2 1337 *
1338 * The draw after hook is called by the reading API to have a
1339 * particular event drawn on the screen.
1340 * @param hook_data ControlFlowData structure of the viewer.
1341 * @param call_data Event context.
1342 *
1343 * This function adds items to be drawn in a queue for each process.
1344 *
1345 */
e92eabaf 1346int after_schedchange_hook(void *hook_data, void *call_data)
f0d936c0 1347{
2c82c4dc 1348 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1349 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
ca0f8a8e 1350 ControlFlowData *control_flow_data = events_request->viewer_data;
50439712 1351
a56a1ba4 1352 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
50439712 1353
1354 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1355
348c6ba8 1356 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1357
b9a010a2 1358 LttEvent *e;
2c82c4dc 1359 e = ltt_tracefile_get_event(tfc->tf);
b9a010a2 1360
1361 LttTime evtime = ltt_event_time(e);
b9a010a2 1362
10a1069a 1363 /* Add process to process list (if not present) */
2eef04b5 1364 LttvProcessState *process_in;
10a1069a 1365 LttTime birth;
1c736ed5 1366 guint pl_height = 0;
10a1069a 1367 HashedProcessData *hashed_process_data_in = NULL;
b9a010a2 1368
5c230fc4 1369 ProcessList *process_list = control_flow_data->process_list;
10a1069a 1370
1371 guint pid_in;
1372 {
1373 guint pid_out;
2c82c4dc 1374 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
1375 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
10a1069a 1376 }
b9a010a2 1377
1378
10a1069a 1379 /* Find process pid_in in the list... */
348c6ba8 1380 //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
1381 //process_in = tfs->process;
1382 guint cpu = ltt_tracefile_num(tfc->tf);
1383 process_in = ts->running_process[cpu];
10a1069a 1384 /* It should exist, because we are after the state update. */
96947fcf 1385#ifdef EXTRA_CHECK
10a1069a 1386 g_assert(process_in != NULL);
96947fcf 1387#endif //EXTRA_CHECK
10a1069a 1388 birth = process_in->creation_time;
b9a010a2 1389
ac4e21cf 1390 hashed_process_data_in = processlist_get_process_data(process_list,
10a1069a 1391 pid_in,
348c6ba8 1392 process_in->cpu,
10a1069a 1393 &birth,
ac4e21cf 1394 tfc->t_context->index);
1395 if(hashed_process_data_in == NULL)
10a1069a 1396 {
1397 g_assert(pid_in == 0 || pid_in != process_in->ppid);
aac69e70 1398 const gchar *name = g_quark_to_string(process_in->name);
4e86ae2e 1399 ProcessInfo *process_info;
1c736ed5 1400 Drawing_t *drawing = control_flow_data->drawing;
10a1069a 1401 /* Process not present */
1402 processlist_add(process_list,
1c736ed5 1403 drawing,
10a1069a 1404 pid_in,
348c6ba8 1405 process_in->cpu,
10a1069a 1406 process_in->ppid,
1407 &birth,
1408 tfc->t_context->index,
1409 name,
1410 &pl_height,
4e86ae2e 1411 &process_info,
10a1069a 1412 &hashed_process_data_in);
1c736ed5 1413 gtk_widget_set_size_request(drawing->drawing_area,
1414 -1,
1415 pl_height);
1416 gtk_widget_queue_draw(drawing->drawing_area);
b9a010a2 1417 }
40debf7b 1418 /* Set the current process */
348c6ba8 1419 process_list->current_hash_data[process_in->cpu] =
40debf7b 1420 hashed_process_data_in;
10a1069a 1421
b2743953 1422 if(ltt_time_compare(hashed_process_data_in->next_good_time,
1423 evtime) <= 0)
1424 {
fd22065b 1425 TimeWindow time_window =
1426 lttvwindow_get_time_window(control_flow_data->tab);
1427
1428#ifdef EXTRA_CHECK
1429 if(ltt_time_compare(evtime, time_window.start_time) == -1
1430 || ltt_time_compare(evtime, time_window.end_time) == 1)
1431 return;
1432#endif //EXTRA_CHECK
d6fef890 1433 Drawing_t *drawing = control_flow_data->drawing;
1434 guint width = drawing->width;
b2743953 1435 guint new_x;
1436
1437 convert_time_to_pixels(
1438 time_window,
1439 evtime,
1440 width,
1441 &new_x);
e72908ed 1442
b2743953 1443 if(hashed_process_data_in->x.middle != new_x) {
1444 hashed_process_data_in->x.middle = new_x;
1445 hashed_process_data_in->x.middle_used = FALSE;
1446 hashed_process_data_in->x.middle_marked = FALSE;
1447 }
1448 }
b9a010a2 1449 return 0;
1450
1451
1452
e72908ed 1453
1454
b9a010a2 1455#if 0
1456 EventsRequest *events_request = (EventsRequest*)hook_data;
1457 ControlFlowData *control_flow_data = events_request->viewer_data;
1458
1459 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1460
1461 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1462 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
1463
a56a1ba4 1464
50439712 1465 LttEvent *e;
1466 e = tfc->e;
1467
9444deae 1468 LttTime evtime = ltt_event_time(e);
ca0f8a8e 1469 TimeWindow time_window =
1470 lttvwindow_get_time_window(control_flow_data->tab);
9444deae 1471
a2aab3a3 1472 LttTime time_window.end_time = time_window.time_window.end_time;
6f26fc38 1473
9444deae 1474 //if(time < time_beg || time > time_end) return;
ca0f8a8e 1475 if(ltt_time_compare(evtime, time_window.start_time) == -1
a2aab3a3 1476 || ltt_time_compare(evtime, time_window.end_time) == 1)
9444deae 1477 return;
1478
1479
a56a1ba4 1480 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
1481 {
2a2fa4f0 1482 g_debug("schedchange!");
a56a1ba4 1483
1484 /* Add process to process list (if not present) and get drawing "y" from
1485 * process position */
1486 guint pid_out, pid_in;
1487 LttvProcessState *process_out, *process_in;
1488 LttTime birth;
1489 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
1490
5c230fc4 1491 ProcessList *process_list = control_flow_data->process_list;
a56a1ba4 1492
1493
1494 LttField *f = ltt_event_field(e);
1495 LttField *element;
1496 element = ltt_field_member(f,0);
1497 pid_out = ltt_event_get_long_unsigned(e,element);
1498 element = ltt_field_member(f,1);
1499 pid_in = ltt_event_get_long_unsigned(e,element);
2a2fa4f0 1500 //g_debug("out : %u in : %u", pid_out, pid_in);
a56a1ba4 1501
1502
1503 /* Find process pid_out in the list... */
2a2fa4f0 1504 process_out = lttv_state_find_process(tfs, pid_out);
1aff52a2 1505 if(process_out == NULL) return 0;
2a2fa4f0 1506 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
a56a1ba4 1507
1508 birth = process_out->creation_time;
1509 gchar *name = strdup(g_quark_to_string(process_out->name));
14963be0 1510 HashedProcessData *hashed_process_data_out = NULL;
a56a1ba4 1511
1512 if(processlist_get_process_pixels(process_list,
1513 pid_out,
1514 &birth,
d0cd7f09 1515 tfc->t_context->index,
a56a1ba4 1516 &y_out,
1517 &height,
14963be0 1518 &hashed_process_data_out) == 1)
a56a1ba4 1519 {
51705146 1520 /* Process not present */
1521 processlist_add(process_list,
1522 pid_out,
1523 &birth,
1524 tfc->t_context->index,
1525 name,
1526 &pl_height,
1527 &hashed_process_data_out);
1528 processlist_get_process_pixels(process_list,
1529 pid_out,
1530 &birth,
1531 tfc->t_context->index,
1532 &y_out,
1533 &height,
1534 &hashed_process_data_out);
1535 drawing_insert_square( control_flow_data->drawing, y_out, height);
a56a1ba4 1536 }
1537
1538 g_free(name);
1539
1540 /* Find process pid_in in the list... */
2a2fa4f0 1541 process_in = lttv_state_find_process(tfs, pid_in);
1aff52a2 1542 if(process_in == NULL) return 0;
2a2fa4f0 1543 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
a56a1ba4 1544
1545 birth = process_in->creation_time;
1546 name = strdup(g_quark_to_string(process_in->name));
14963be0 1547 HashedProcessData *hashed_process_data_in = NULL;
a56a1ba4 1548
1549 if(processlist_get_process_pixels(process_list,
1550 pid_in,
1551 &birth,
d0cd7f09 1552 tfc->t_context->index,
a56a1ba4 1553 &y_in,
1554 &height,
14963be0 1555 &hashed_process_data_in) == 1)
a56a1ba4 1556 {
1557 /* Process not present */
1558 processlist_add(process_list,
1559 pid_in,
1560 &birth,
d0cd7f09 1561 tfc->t_context->index,
a56a1ba4 1562 name,
1563 &pl_height,
14963be0 1564 &hashed_process_data_in);
a56a1ba4 1565 processlist_get_process_pixels(process_list,
1566 pid_in,
1567 &birth,
d0cd7f09 1568 tfc->t_context->index,
a56a1ba4 1569 &y_in,
1570 &height,
14963be0 1571 &hashed_process_data_in);
a56a1ba4 1572
ca0f8a8e 1573 drawing_insert_square( control_flow_data->drawing, y_in, height);
a56a1ba4 1574 }
1575 g_free(name);
1576
1577
1578 /* Find pixels corresponding to time of the event. If the time does
1579 * not fit in the window, show a warning, not supposed to happend. */
1580 //guint x = 0;
501d5405 1581 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
a56a1ba4 1582
1583 //LttTime time = ltt_event_time(e);
1584
a2aab3a3 1585 //LttTime window_end = time_window->time_window.end_time;
a56a1ba4 1586
1587
1588 //convert_time_to_pixels(
a18124ff 1589 // *time_window,
a56a1ba4 1590 // time,
1591 // width,
1592 // &x);
1593
1594 //assert(x <= width);
1595
1596 /* draw what represents the event for outgoing process. */
1597
14963be0 1598 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
68997a22 1599 //draw_context_out->current->modify_over->x = x;
1600 draw_context_out->current->modify_over->y = y_out;
319e9d81 1601 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
501d5405 1602 draw_context_out->drawable = control_flow_data->drawing->pixmap;
1603 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
1604 GtkWidget *widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1605 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
d0cd7f09 1606
a56a1ba4 1607 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
501d5405 1608 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1609
1610 /*if(process_out->state->s == LTTV_STATE_RUN)
1611 {
1612 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1613 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1614 PropertiesBG prop_bg;
1615 prop_bg.color = g_new(GdkColor,1);
1616
1617 prop_bg.color->red = 0xffff;
1618 prop_bg.color->green = 0xffff;
1619 prop_bg.color->blue = 0xffff;
1620
1621 draw_bg((void*)&prop_bg, (void*)draw_context_out);
1622 g_free(prop_bg.color);
1623 gdk_gc_unref(draw_context_out->gc);
1624 }*/
1625
1626 draw_context_out->gc = widget->style->black_gc;
1627
a56a1ba4 1628 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
2df6f2bd 1629 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1630 PropertiesText prop_text_out;
1631 prop_text_out.foreground = &colorfg_out;
1632 prop_text_out.background = &colorbg_out;
cfe526b1 1633 prop_text_out.size = 6;
a56a1ba4 1634 prop_text_out.position = OVER;
1635
cfe526b1 1636 /* color of text : status of the process */
1637 if(process_out->state->s == LTTV_STATE_UNNAMED)
1638 {
1639 prop_text_out.foreground->red = 0xffff;
1640 prop_text_out.foreground->green = 0xffff;
1641 prop_text_out.foreground->blue = 0xffff;
1642 }
1643 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1644 {
1645 prop_text_out.foreground->red = 0x0fff;
d52cfc84 1646 prop_text_out.foreground->green = 0xffff;
1647 prop_text_out.foreground->blue = 0xfff0;
cfe526b1 1648 }
1649 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1650 {
2df6f2bd 1651 prop_text_out.foreground->red = 0xffff;
1652 prop_text_out.foreground->green = 0xffff;
cfe526b1 1653 prop_text_out.foreground->blue = 0x0000;
1654 }
0828099d 1655 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1656 {
1657 prop_text_out.foreground->red = 0xffff;
1658 prop_text_out.foreground->green = 0x0000;
1659 prop_text_out.foreground->blue = 0xffff;
1660 }
1661 else if(process_out->state->s == LTTV_STATE_WAIT)
1662 {
1663 prop_text_out.foreground->red = 0xffff;
1664 prop_text_out.foreground->green = 0x0000;
1665 prop_text_out.foreground->blue = 0x0000;
1666 }
1667 else if(process_out->state->s == LTTV_STATE_RUN)
1668 {
1669 prop_text_out.foreground->red = 0x0000;
1670 prop_text_out.foreground->green = 0xffff;
1671 prop_text_out.foreground->blue = 0x0000;
1672 }
1673 else
1674 {
1675 prop_text_out.foreground->red = 0xffff;
1676 prop_text_out.foreground->green = 0xffff;
1677 prop_text_out.foreground->blue = 0xffff;
1678 }
1679
a56a1ba4 1680 /* Print status of the process : U, WF, WC, E, W, R */
1681 if(process_out->state->s == LTTV_STATE_UNNAMED)
68997a22 1682 prop_text_out.text = "U";
a56a1ba4 1683 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
68997a22 1684 prop_text_out.text = "WF";
a56a1ba4 1685 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
68997a22 1686 prop_text_out.text = "WC";
0828099d 1687 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
68997a22 1688 prop_text_out.text = "E";
a56a1ba4 1689 else if(process_out->state->s == LTTV_STATE_WAIT)
68997a22 1690 prop_text_out.text = "W";
a56a1ba4 1691 else if(process_out->state->s == LTTV_STATE_RUN)
68997a22 1692 prop_text_out.text = "R";
a56a1ba4 1693 else
68997a22 1694 prop_text_out.text = "U";
a56a1ba4 1695
1696 draw_text((void*)&prop_text_out, (void*)draw_context_out);
d0cd7f09 1697
1698 //gdk_gc_unref(draw_context_out->gc);
319e9d81 1699
68997a22 1700 draw_context_out->current->middle->y = y_out+height/2;
d0cd7f09 1701 draw_context_out->current->over->y = y_out;
1702 draw_context_out->current->under->y = y_out+height;
68997a22 1703 draw_context_out->current->status = process_out->state->s;
a56a1ba4 1704
68997a22 1705 /* for pid_out : remove previous, Prev = current, new current (default) */
1706 g_free(draw_context_out->previous->modify_under);
1707 g_free(draw_context_out->previous->modify_middle);
1708 g_free(draw_context_out->previous->modify_over);
1709 g_free(draw_context_out->previous->under);
1710 g_free(draw_context_out->previous->middle);
1711 g_free(draw_context_out->previous->over);
1712 g_free(draw_context_out->previous);
1713
1714 draw_context_out->previous = draw_context_out->current;
a56a1ba4 1715
68997a22 1716 draw_context_out->current = g_new(DrawInfo,1);
1717 draw_context_out->current->over = g_new(ItemInfo,1);
1718 draw_context_out->current->over->x = -1;
1719 draw_context_out->current->over->y = -1;
1720 draw_context_out->current->middle = g_new(ItemInfo,1);
1721 draw_context_out->current->middle->x = -1;
1722 draw_context_out->current->middle->y = -1;
1723 draw_context_out->current->under = g_new(ItemInfo,1);
1724 draw_context_out->current->under->x = -1;
1725 draw_context_out->current->under->y = -1;
1726 draw_context_out->current->modify_over = g_new(ItemInfo,1);
1727 draw_context_out->current->modify_over->x = -1;
1728 draw_context_out->current->modify_over->y = -1;
1729 draw_context_out->current->modify_middle = g_new(ItemInfo,1);
1730 draw_context_out->current->modify_middle->x = -1;
1731 draw_context_out->current->modify_middle->y = -1;
1732 draw_context_out->current->modify_under = g_new(ItemInfo,1);
1733 draw_context_out->current->modify_under->x = -1;
1734 draw_context_out->current->modify_under->y = -1;
1735 draw_context_out->current->status = LTTV_STATE_UNNAMED;
a56a1ba4 1736
1737 /* Finally, update the drawing context of the pid_in. */
1738
14963be0 1739 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
68997a22 1740 //draw_context_in->current->modify_over->x = x;
1741 draw_context_in->current->modify_over->y = y_in;
319e9d81 1742 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
501d5405 1743 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1744 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1745 widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1746 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
a56a1ba4 1747
1748 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
501d5405 1749 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1750
1751 /*if(process_in->state->s == LTTV_STATE_RUN)
1752 {
1753 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1754 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1755 PropertiesBG prop_bg;
1756 prop_bg.color = g_new(GdkColor,1);
1757
1758 prop_bg.color->red = 0xffff;
1759 prop_bg.color->green = 0xffff;
1760 prop_bg.color->blue = 0xffff;
1761
1762 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1763 g_free(prop_bg.color);
1764 gdk_gc_unref(draw_context_in->gc);
1765 }*/
1766
1767 draw_context_in->gc = widget->style->black_gc;
1768
a56a1ba4 1769 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
2df6f2bd 1770 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1771 PropertiesText prop_text_in;
1772 prop_text_in.foreground = &colorfg_in;
1773 prop_text_in.background = &colorbg_in;
cfe526b1 1774 prop_text_in.size = 6;
a56a1ba4 1775 prop_text_in.position = OVER;
1776
cfe526b1 1777 /* foreground of text : status of the process */
1778 if(process_in->state->s == LTTV_STATE_UNNAMED)
1779 {
1780 prop_text_in.foreground->red = 0xffff;
1781 prop_text_in.foreground->green = 0xffff;
1782 prop_text_in.foreground->blue = 0xffff;
1783 }
1784 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1785 {
1786 prop_text_in.foreground->red = 0x0fff;
d52cfc84 1787 prop_text_in.foreground->green = 0xffff;
1788 prop_text_in.foreground->blue = 0xfff0;
cfe526b1 1789 }
1790 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1791 {
2df6f2bd 1792 prop_text_in.foreground->red = 0xffff;
1793 prop_text_in.foreground->green = 0xffff;
cfe526b1 1794 prop_text_in.foreground->blue = 0x0000;
1795 }
0828099d 1796 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1797 {
1798 prop_text_in.foreground->red = 0xffff;
1799 prop_text_in.foreground->green = 0x0000;
1800 prop_text_in.foreground->blue = 0xffff;
1801 }
1802 else if(process_in->state->s == LTTV_STATE_WAIT)
1803 {
1804 prop_text_in.foreground->red = 0xffff;
1805 prop_text_in.foreground->green = 0x0000;
1806 prop_text_in.foreground->blue = 0x0000;
1807 }
1808 else if(process_in->state->s == LTTV_STATE_RUN)
1809 {
1810 prop_text_in.foreground->red = 0x0000;
1811 prop_text_in.foreground->green = 0xffff;
1812 prop_text_in.foreground->blue = 0x0000;
1813 }
1814 else
1815 {
1816 prop_text_in.foreground->red = 0xffff;
1817 prop_text_in.foreground->green = 0xffff;
1818 prop_text_in.foreground->blue = 0xffff;
1819 }
1820
1821
a56a1ba4 1822 /* Print status of the process : U, WF, WC, E, W, R */
1823 if(process_in->state->s == LTTV_STATE_UNNAMED)
68997a22 1824 prop_text_in.text = "U";
a56a1ba4 1825 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
68997a22 1826 prop_text_in.text = "WF";
a56a1ba4 1827 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
68997a22 1828 prop_text_in.text = "WC";
0828099d 1829 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
68997a22 1830 prop_text_in.text = "E";
a56a1ba4 1831 else if(process_in->state->s == LTTV_STATE_WAIT)
68997a22 1832 prop_text_in.text = "W";
a56a1ba4 1833 else if(process_in->state->s == LTTV_STATE_RUN)
68997a22 1834 prop_text_in.text = "R";
a56a1ba4 1835 else
68997a22 1836 prop_text_in.text = "U";
a56a1ba4 1837
1838 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1839
d0cd7f09 1840
319e9d81 1841 if(process_in->state->s == LTTV_STATE_RUN)
1842 {
1843 gchar tmp[255];
1844 prop_text_in.foreground = &colorfg_in;
1845 prop_text_in.background = &colorbg_in;
1846 prop_text_in.foreground->red = 0xffff;
1847 prop_text_in.foreground->green = 0xffff;
1848 prop_text_in.foreground->blue = 0xffff;
1849 prop_text_in.size = 6;
1850 prop_text_in.position = UNDER;
1851
1852 prop_text_in.text = g_new(gchar, 260);
1853 strcpy(prop_text_in.text, "CPU ");
2c82c4dc 1854 snprintf(tmp, 255, "%u", ltt_tracefile_num(tfc->tf));
319e9d81 1855 strcat(prop_text_in.text, tmp);
1856
1857 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1858 g_free(prop_text_in.text);
1859 }
1860
1861
68997a22 1862 draw_context_in->current->middle->y = y_in+height/2;
d0cd7f09 1863 draw_context_in->current->over->y = y_in;
1864 draw_context_in->current->under->y = y_in+height;
68997a22 1865 draw_context_in->current->status = process_in->state->s;
1866
1867 /* for pid_in : remove previous, Prev = current, new current (default) */
1868 g_free(draw_context_in->previous->modify_under);
1869 g_free(draw_context_in->previous->modify_middle);
1870 g_free(draw_context_in->previous->modify_over);
1871 g_free(draw_context_in->previous->under);
1872 g_free(draw_context_in->previous->middle);
1873 g_free(draw_context_in->previous->over);
1874 g_free(draw_context_in->previous);
1875
1876 draw_context_in->previous = draw_context_in->current;
a56a1ba4 1877
68997a22 1878 draw_context_in->current = g_new(DrawInfo,1);
1879 draw_context_in->current->over = g_new(ItemInfo,1);
1880 draw_context_in->current->over->x = -1;
1881 draw_context_in->current->over->y = -1;
1882 draw_context_in->current->middle = g_new(ItemInfo,1);
1883 draw_context_in->current->middle->x = -1;
1884 draw_context_in->current->middle->y = -1;
1885 draw_context_in->current->under = g_new(ItemInfo,1);
1886 draw_context_in->current->under->x = -1;
1887 draw_context_in->current->under->y = -1;
1888 draw_context_in->current->modify_over = g_new(ItemInfo,1);
1889 draw_context_in->current->modify_over->x = -1;
1890 draw_context_in->current->modify_over->y = -1;
1891 draw_context_in->current->modify_middle = g_new(ItemInfo,1);
1892 draw_context_in->current->modify_middle->x = -1;
1893 draw_context_in->current->modify_middle->y = -1;
1894 draw_context_in->current->modify_under = g_new(ItemInfo,1);
1895 draw_context_in->current->modify_under->x = -1;
1896 draw_context_in->current->modify_under->y = -1;
1897 draw_context_in->current->status = LTTV_STATE_UNNAMED;
a56a1ba4 1898
1899 }
1900
1901 return 0;
b9a010a2 1902#endif //0
f0d936c0 1903}
f7afe191 1904
9a1ec01b 1905#if 0
6550d711 1906static inline PropertiesLine prepare_execmode_line(LttvProcessState *process)
23093869 1907{
1908 PropertiesLine prop_line;
1909 prop_line.line_width = 1;
1910 prop_line.style = GDK_LINE_SOLID;
1911 prop_line.y = OVER;
1912 //GdkColormap *colormap = gdk_colormap_get_system();
1913
1914 /* color of line : execution mode of the process */
1915 if(process->state->t == LTTV_STATE_USER_MODE)
1916 prop_line.color = drawing_colors[COL_USER_MODE];
1917 else if(process->state->t == LTTV_STATE_SYSCALL)
1918 prop_line.color = drawing_colors[COL_SYSCALL];
1919 else if(process->state->t == LTTV_STATE_TRAP)
1920 prop_line.color = drawing_colors[COL_TRAP];
1921 else if(process->state->t == LTTV_STATE_IRQ)
1922 prop_line.color = drawing_colors[COL_IRQ];
1923 else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
1924 prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
1925 else
1926 prop_line.color = drawing_colors[COL_WHITE];
1927
1928 //gdk_colormap_alloc_color(colormap,
1929 // prop_line.color,
1930 // FALSE,
1931 // TRUE);
1932
1933 return prop_line;
1934
1935}
9a1ec01b 1936#endif //0
23093869 1937
1938
1939/* before_execmode_hook
1940 *
1941 * This function basically draw lines and icons. Two types of lines are drawn :
1942 * one small (3 pixels?) representing the state of the process and the second
1943 * type is thicker (10 pixels?) representing on which CPU a process is running
1944 * (and this only in running state).
1945 *
1946 * Extremums of the lines :
1947 * x_min : time of the last event context for this process kept in memory.
1948 * x_max : time of the current event.
1949 * y : middle of the process in the process list. The process is found in the
1950 * list, therefore is it's position in pixels.
1951 *
1952 * The choice of lines'color is defined by the context of the last event for this
1953 * process.
1954 */
1955
1956
1957int before_execmode_hook(void *hook_data, void *call_data)
1958{
2c82c4dc 1959 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1960 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
23093869 1961 ControlFlowData *control_flow_data = events_request->viewer_data;
23093869 1962
1963 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1964
1965 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
23093869 1966
348c6ba8 1967 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1968
23093869 1969 LttEvent *e;
2c82c4dc 1970 e = ltt_tracefile_get_event(tfc->tf);
23093869 1971
1972 LttTime evtime = ltt_event_time(e);
23093869 1973
10a1069a 1974 /* we are in a execmode, before the state update. We must draw the
1975 * items corresponding to the state before it changes : now is the right
1976 * time to do it.
1977 */
1978 /* For the pid */
348c6ba8 1979 //LttvProcessState *process = tfs->process;
1980 guint cpu = ltt_tracefile_num(tfc->tf);
1981 LttvProcessState *process = ts->running_process[cpu];
10a1069a 1982 g_assert(process != NULL);
23093869 1983
10a1069a 1984 guint pid = process->pid;
23093869 1985
10a1069a 1986 /* Well, the process_out existed : we must get it in the process hash
1987 * or add it, and draw its items.
1988 */
1989 /* Add process to process list (if not present) */
1c736ed5 1990 guint pl_height = 0;
10a1069a 1991 HashedProcessData *hashed_process_data = NULL;
5c230fc4 1992 ProcessList *process_list = control_flow_data->process_list;
10a1069a 1993 LttTime birth = process->creation_time;
40debf7b 1994
348c6ba8 1995 if(likely(process_list->current_hash_data[cpu] != NULL)) {
1996 hashed_process_data = process_list->current_hash_data[cpu];
40debf7b 1997 } else {
ac4e21cf 1998 hashed_process_data = processlist_get_process_data(process_list,
40debf7b 1999 pid,
348c6ba8 2000 process->cpu,
40debf7b 2001 &birth,
ac4e21cf 2002 tfc->t_context->index);
1d1df11d 2003 if(unlikely(hashed_process_data == NULL))
40debf7b 2004 {
2005 g_assert(pid == 0 || pid != process->ppid);
2006 ProcessInfo *process_info;
2007 /* Process not present */
1c736ed5 2008 Drawing_t *drawing = control_flow_data->drawing;
40debf7b 2009 const gchar *name = g_quark_to_string(process->name);
2010 processlist_add(process_list,
1c736ed5 2011 drawing,
40debf7b 2012 pid,
348c6ba8 2013 process->cpu,
40debf7b 2014 process->ppid,
2015 &birth,
2016 tfc->t_context->index,
2017 name,
2018 &pl_height,
2019 &process_info,
2020 &hashed_process_data);
1c736ed5 2021 gtk_widget_set_size_request(drawing->drawing_area,
2022 -1,
2023 pl_height);
2024 gtk_widget_queue_draw(drawing->drawing_area);
40debf7b 2025 }
2026 /* Set the current process */
348c6ba8 2027 process_list->current_hash_data[process->cpu] =
40debf7b 2028 hashed_process_data;
10a1069a 2029 }
23093869 2030
10a1069a 2031 /* Now, the process is in the state hash and our own process hash.
2032 * We definitely can draw the items related to the ending state.
2033 */
b2743953 2034
1d1df11d 2035 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2036 evtime) > 0))
10a1069a 2037 {
1d1df11d 2038 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
fd22065b 2039 TimeWindow time_window =
2040 lttvwindow_get_time_window(control_flow_data->tab);
2041
2042#ifdef EXTRA_CHECK
2043 if(ltt_time_compare(evtime, time_window.start_time) == -1
2044 || ltt_time_compare(evtime, time_window.end_time) == 1)
2045 return;
2046#endif //EXTRA_CHECK
d6fef890 2047 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 2048 guint width = drawing->width;
b2743953 2049 guint x;
2050 convert_time_to_pixels(
2051 time_window,
2052 evtime,
2053 width,
2054 &x);
2055
2056 /* Draw collision indicator */
2057 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 2058 gdk_draw_point(hashed_process_data->pixmap,
b2743953 2059 drawing->gc,
2060 x,
1c736ed5 2061 (hashed_process_data->height/2)-3);
b2743953 2062 hashed_process_data->x.middle_marked = TRUE;
2063 }
2064 } else {
fd22065b 2065 TimeWindow time_window =
2066 lttvwindow_get_time_window(control_flow_data->tab);
2067
2068#ifdef EXTRA_CHECK
2069 if(ltt_time_compare(evtime, time_window.start_time) == -1
2070 || ltt_time_compare(evtime, time_window.end_time) == 1)
2071 return;
2072#endif //EXTRA_CHECK
d6fef890 2073 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 2074 guint width = drawing->width;
10a1069a 2075 guint x;
dbd243b1 2076
10a1069a 2077 convert_time_to_pixels(
a18124ff 2078 time_window,
10a1069a 2079 evtime,
2080 width,
2081 &x);
dbd243b1 2082
23093869 2083
4b7dc462 2084 /* Jump over draw if we are at the same x position */
1d1df11d 2085 if(unlikely(x == hashed_process_data->x.middle &&
2086 hashed_process_data->x.middle_used))
10a1069a 2087 {
1d1df11d 2088 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
e72908ed 2089 /* Draw collision indicator */
2090 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 2091 gdk_draw_point(hashed_process_data->pixmap,
e72908ed 2092 drawing->gc,
2093 x,
1c736ed5 2094 (hashed_process_data->height/2)-3);
de4ea1ad 2095 hashed_process_data->x.middle_marked = TRUE;
e72908ed 2096 }
4b7dc462 2097 /* jump */
2098 } else {
2099
2100 DrawContext draw_context;
2101 /* Now create the drawing context that will be used to draw
2102 * items related to the last state. */
1c736ed5 2103 draw_context.drawable = hashed_process_data->pixmap;
4b7dc462 2104 draw_context.gc = drawing->gc;
2105 draw_context.pango_layout = drawing->pango_layout;
9a1ec01b 2106 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
4b7dc462 2107 draw_context.drawinfo.end.x = x;
2108
1c736ed5 2109 draw_context.drawinfo.y.over = 1;
2110 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2111 draw_context.drawinfo.y.under = hashed_process_data->height;
4b7dc462 2112
2113 draw_context.drawinfo.start.offset.over = 0;
2114 draw_context.drawinfo.start.offset.middle = 0;
2115 draw_context.drawinfo.start.offset.under = 0;
2116 draw_context.drawinfo.end.offset.over = 0;
2117 draw_context.drawinfo.end.offset.middle = 0;
2118 draw_context.drawinfo.end.offset.under = 0;
2119
2120 {
2121 /* Draw the line */
9a1ec01b 2122 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 2123 draw_line((void*)&prop_line, (void*)&draw_context);
23093869 2124
4b7dc462 2125 }
2126 /* become the last x position */
9a1ec01b 2127 hashed_process_data->x.middle = x;
e72908ed 2128 hashed_process_data->x.middle_used = TRUE;
2129 hashed_process_data->x.middle_marked = FALSE;
b2743953 2130
2131 /* Calculate the next good time */
2132 convert_pixels_to_time(width, x+1, time_window,
2133 &hashed_process_data->next_good_time);
23093869 2134 }
2135 }
2136
2137 return 0;
2138}
2139
2140/* after_execmode_hook
2141 *
2142 * The draw after hook is called by the reading API to have a
2143 * particular event drawn on the screen.
2144 * @param hook_data ControlFlowData structure of the viewer.
2145 * @param call_data Event context.
2146 *
2147 * This function adds items to be drawn in a queue for each process.
2148 *
2149 */
348c6ba8 2150#if 0
23093869 2151int after_execmode_hook(void *hook_data, void *call_data)
2152{
8869ac08 2153 /**************** DOES NOTHING!! *************/
2154 /* hook desactivated in drawing.c */
2155 return 0;
2156
2157
2c82c4dc 2158 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2159 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
23093869 2160 ControlFlowData *control_flow_data = events_request->viewer_data;
2161
2162 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2163
2164 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
23093869 2165
2166 LttEvent *e;
2c82c4dc 2167 e = ltt_tracefile_get_event(tfc->tf);
23093869 2168
2169 LttTime evtime = ltt_event_time(e);
23093869 2170
10a1069a 2171 /* Add process to process list (if not present) */
2172 LttvProcessState *process;
2173 LttTime birth;
1c736ed5 2174 guint pl_height = 0;
10a1069a 2175 HashedProcessData *hashed_process_data = NULL;
23093869 2176
5c230fc4 2177 ProcessList *process_list = control_flow_data->process_list;
23093869 2178
10a1069a 2179 /* Find process pid_in in the list... */
2180 process = tfs->process;
2181 /* It should exist, because we are after the state update. */
2182 g_assert(process != NULL);
23093869 2183
10a1069a 2184 guint pid = process->pid;
23093869 2185
10a1069a 2186 birth = process->creation_time;
23093869 2187
2c82c4dc 2188 if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL)) {
2189 hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
40debf7b 2190 } else {
ac4e21cf 2191 hashed_process_data = processlist_get_process_data(process_list,
40debf7b 2192 pid,
2193 process->last_cpu_index,
2194 &birth,
ac4e21cf 2195 tfc->t_context->index);
1d1df11d 2196 if(unlikely(hashed_process_data == NULL))
40debf7b 2197 {
2198 g_assert(pid == 0 || pid != process->ppid);
2199 /* Process not present */
1c736ed5 2200 Drawing_t *drawing = control_flow_data->drawing;
40debf7b 2201 const gchar *name = g_quark_to_string(process->name);
2202 ProcessInfo *process_info;
2203 processlist_add(process_list,
1c736ed5 2204 drawing,
40debf7b 2205 pid,
2206 process->last_cpu_index,
2207 process->ppid,
2208 &birth,
2209 tfc->t_context->index,
2210 name,
2211 &pl_height,
2212 &process_info,
2213 &hashed_process_data);
1c736ed5 2214 gtk_widget_set_size_request(drawing->drawing_area,
2215 -1,
2216 pl_height);
2217 gtk_widget_queue_draw(drawing->drawing_area);
40debf7b 2218 }
2219 /* Set the current process */
2220 process_list->current_hash_data[process->last_cpu_index] =
2221 hashed_process_data;
23093869 2222 }
40debf7b 2223
1d1df11d 2224 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
2225 evtime) <= 0))
b2743953 2226 {
fd22065b 2227 TimeWindow time_window =
2228 lttvwindow_get_time_window(control_flow_data->tab);
2229
2230#ifdef EXTRA_CHECK
2231 if(ltt_time_compare(evtime, time_window.start_time) == -1
2232 || ltt_time_compare(evtime, time_window.end_time) == 1)
2233 return;
2234#endif //EXTRA_CHECK
d6fef890 2235 Drawing_t *drawing = control_flow_data->drawing;
2236 guint width = drawing->width;
b2743953 2237 guint new_x;
2238
2239 convert_time_to_pixels(
2240 time_window,
2241 evtime,
2242 width,
2243 &new_x);
e72908ed 2244
b2743953 2245 if(hashed_process_data->x.middle != new_x) {
2246 hashed_process_data->x.middle = new_x;
2247 hashed_process_data->x.middle_used = FALSE;
2248 hashed_process_data->x.middle_marked = FALSE;
2249 }
2250 }
23093869 2251 return 0;
2252}
348c6ba8 2253#endif //0
23093869 2254
dbd243b1 2255
2c82c4dc 2256
2257/* before_process_exit_hook
dbd243b1 2258 *
2259 * Draw lines for process event.
2260 *
2261 * @param hook_data ControlFlowData structure of the viewer.
2262 * @param call_data Event context.
2263 *
2264 * This function adds items to be drawn in a queue for each process.
2265 *
2266 */
2c82c4dc 2267
2268
2269int before_process_exit_hook(void *hook_data, void *call_data)
dbd243b1 2270{
2c82c4dc 2271 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2272 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2273
dbd243b1 2274 ControlFlowData *control_flow_data = events_request->viewer_data;
dbd243b1 2275
2276 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2277
2278 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
dbd243b1 2279
348c6ba8 2280 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
2281
dbd243b1 2282 LttEvent *e;
2c82c4dc 2283 e = ltt_tracefile_get_event(tfc->tf);
dbd243b1 2284
2285 LttTime evtime = ltt_event_time(e);
dbd243b1 2286
2c82c4dc 2287 /* Add process to process list (if not present) */
348c6ba8 2288 //LttvProcessState *process = tfs->process;
2289 guint cpu = ltt_tracefile_num(tfc->tf);
2290 LttvProcessState *process = ts->running_process[cpu];
2c82c4dc 2291 guint pid = process->pid;
2292 LttTime birth;
2293 guint pl_height = 0;
2294 HashedProcessData *hashed_process_data = NULL;
dbd243b1 2295
2c82c4dc 2296 ProcessList *process_list = control_flow_data->process_list;
2297
2298 g_assert(process != NULL);
dbd243b1 2299
2c82c4dc 2300 birth = process->creation_time;
dbd243b1 2301
348c6ba8 2302 if(likely(process_list->current_hash_data[cpu] != NULL)) {
2303 hashed_process_data = process_list->current_hash_data[cpu];
2c82c4dc 2304 } else {
2305 hashed_process_data = processlist_get_process_data(process_list,
2306 pid,
348c6ba8 2307 process->cpu,
2c82c4dc 2308 &birth,
2309 tfc->t_context->index);
2310 if(unlikely(hashed_process_data == NULL))
2311 {
2312 g_assert(pid == 0 || pid != process->ppid);
2313 /* Process not present */
2314 Drawing_t *drawing = control_flow_data->drawing;
2315 const gchar *name = g_quark_to_string(process->name);
2316 ProcessInfo *process_info;
2317 processlist_add(process_list,
2318 drawing,
2319 pid,
348c6ba8 2320 process->cpu,
2c82c4dc 2321 process->ppid,
2322 &birth,
2323 tfc->t_context->index,
2324 name,
2325 &pl_height,
2326 &process_info,
2327 &hashed_process_data);
2328 gtk_widget_set_size_request(drawing->drawing_area,
2329 -1,
2330 pl_height);
2331 gtk_widget_queue_draw(drawing->drawing_area);
2332 }
2333 }
dbd243b1 2334
2c82c4dc 2335 /* Now, the process is in the state hash and our own process hash.
2336 * We definitely can draw the items related to the ending state.
2337 */
2338
2339 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2340 evtime) > 0))
2341 {
2342 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2343 TimeWindow time_window =
2344 lttvwindow_get_time_window(control_flow_data->tab);
dbd243b1 2345
2c82c4dc 2346#ifdef EXTRA_CHECK
2347 if(ltt_time_compare(evtime, time_window.start_time) == -1
2348 || ltt_time_compare(evtime, time_window.end_time) == 1)
2349 return;
2350#endif //EXTRA_CHECK
2351 Drawing_t *drawing = control_flow_data->drawing;
2352 guint width = drawing->width;
2353 guint x;
2354 convert_time_to_pixels(
2355 time_window,
2356 evtime,
2357 width,
2358 &x);
dbd243b1 2359
2c82c4dc 2360 /* Draw collision indicator */
2361 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2362 gdk_draw_point(hashed_process_data->pixmap,
2363 drawing->gc,
2364 x,
2365 (hashed_process_data->height/2)-3);
2366 hashed_process_data->x.middle_marked = TRUE;
2367 }
2368 } else {
2369 TimeWindow time_window =
2370 lttvwindow_get_time_window(control_flow_data->tab);
fd22065b 2371
2372#ifdef EXTRA_CHECK
2c82c4dc 2373 if(ltt_time_compare(evtime, time_window.start_time) == -1
2374 || ltt_time_compare(evtime, time_window.end_time) == 1)
2375 return;
fd22065b 2376#endif //EXTRA_CHECK
2c82c4dc 2377 Drawing_t *drawing = control_flow_data->drawing;
2378 guint width = drawing->width;
2379 guint x;
2380
2381 convert_time_to_pixels(
2382 time_window,
2383 evtime,
2384 width,
2385 &x);
2386
b2743953 2387
2c82c4dc 2388 /* Jump over draw if we are at the same x position */
2389 if(unlikely(x == hashed_process_data->x.middle &&
2390 hashed_process_data->x.middle_used))
2391 {
2392 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
b2743953 2393 /* Draw collision indicator */
2394 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 2395 gdk_draw_point(hashed_process_data->pixmap,
b2743953 2396 drawing->gc,
2397 x,
1c736ed5 2398 (hashed_process_data->height/2)-3);
b2743953 2399 hashed_process_data->x.middle_marked = TRUE;
2400 }
2c82c4dc 2401 /* jump */
b2743953 2402 } else {
2c82c4dc 2403 DrawContext draw_context;
fd22065b 2404
2c82c4dc 2405 /* Now create the drawing context that will be used to draw
2406 * items related to the last state. */
2407 draw_context.drawable = hashed_process_data->pixmap;
2408 draw_context.gc = drawing->gc;
2409 draw_context.pango_layout = drawing->pango_layout;
2410 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2411 draw_context.drawinfo.end.x = x;
dbd243b1 2412
2c82c4dc 2413 draw_context.drawinfo.y.over = 1;
2414 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2415 draw_context.drawinfo.y.under = hashed_process_data->height;
dbd243b1 2416
2c82c4dc 2417 draw_context.drawinfo.start.offset.over = 0;
2418 draw_context.drawinfo.start.offset.middle = 0;
2419 draw_context.drawinfo.start.offset.under = 0;
2420 draw_context.drawinfo.end.offset.over = 0;
2421 draw_context.drawinfo.end.offset.middle = 0;
2422 draw_context.drawinfo.end.offset.under = 0;
dbd243b1 2423
2c82c4dc 2424 {
2425 /* Draw the line */
2426 PropertiesLine prop_line = prepare_s_e_line(process);
2427 draw_line((void*)&prop_line, (void*)&draw_context);
dbd243b1 2428
2c82c4dc 2429 }
2430 /* become the last x position */
2431 hashed_process_data->x.middle = x;
2432 hashed_process_data->x.middle_used = TRUE;
2433 hashed_process_data->x.middle_marked = FALSE;
dbd243b1 2434
2c82c4dc 2435 /* Calculate the next good time */
2436 convert_pixels_to_time(width, x+1, time_window,
2437 &hashed_process_data->next_good_time);
2438 }
2439 }
2440
2441 return 0;
2442
2443}
2444
2445
2446
2447/* before_process_release_hook
2448 *
2449 * Draw lines for process event.
2450 *
2451 * @param hook_data ControlFlowData structure of the viewer.
2452 * @param call_data Event context.
2453 *
2454 * This function adds items to be drawn in a queue for each process.
2455 *
2456 */
2457
2458
2459int before_process_release_hook(void *hook_data, void *call_data)
2460{
2461 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2462 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2463
2464 ControlFlowData *control_flow_data = events_request->viewer_data;
2465
2466 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2467
2468 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
2469
348c6ba8 2470 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
2471
2c82c4dc 2472 LttEvent *e;
2473 e = ltt_tracefile_get_event(tfc->tf);
2474
2475 LttTime evtime = ltt_event_time(e);
2476
2477
2478 guint pid;
2479 {
2480 pid = ltt_event_get_long_unsigned(e, thf->f1);
2481 }
2482
2483 /* Add process to process list (if not present) */
2484 /* Don't care about the process if it's not in the state hash already :
2485 * that means a process that has never done anything in the trace and
2486 * unknown suddently gets destroyed : no state meaningful to show. */
348c6ba8 2487 LttvProcessState *process = lttv_state_find_process(ts, ANY_CPU, pid);
2c82c4dc 2488
2489 if(process != NULL) {
2490 LttTime birth;
2491 guint pl_height = 0;
2492 HashedProcessData *hashed_process_data = NULL;
2493
2494 ProcessList *process_list = control_flow_data->process_list;
2495
2496 birth = process->creation_time;
2497
2498 /* Cannot use current process : this event happens on another process,
2499 * action done by the parent. */
2500 hashed_process_data = processlist_get_process_data(process_list,
2501 pid,
348c6ba8 2502 process->cpu,
2c82c4dc 2503 &birth,
2504 tfc->t_context->index);
2505 if(unlikely(hashed_process_data == NULL))
2506 {
2507 g_assert(pid == 0 || pid != process->ppid);
2508 /* Process not present */
2509 Drawing_t *drawing = control_flow_data->drawing;
2510 const gchar *name = g_quark_to_string(process->name);
2511 ProcessInfo *process_info;
2512 processlist_add(process_list,
2513 drawing,
2514 pid,
348c6ba8 2515 process->cpu,
2c82c4dc 2516 process->ppid,
2517 &birth,
2518 tfc->t_context->index,
2519 name,
2520 &pl_height,
2521 &process_info,
2522 &hashed_process_data);
2523 gtk_widget_set_size_request(drawing->drawing_area,
2524 -1,
2525 pl_height);
2526 gtk_widget_queue_draw(drawing->drawing_area);
2527 }
2528
2529 /* Now, the process is in the state hash and our own process hash.
2530 * We definitely can draw the items related to the ending state.
2531 */
2532
2533 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2534 evtime) > 0))
2535 {
2536 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2537 TimeWindow time_window =
2538 lttvwindow_get_time_window(control_flow_data->tab);
2539
2540#ifdef EXTRA_CHECK
2541 if(ltt_time_compare(evtime, time_window.start_time) == -1
2542 || ltt_time_compare(evtime, time_window.end_time) == 1)
2543 return;
2544#endif //EXTRA_CHECK
2545 Drawing_t *drawing = control_flow_data->drawing;
2546 guint width = drawing->width;
2547 guint x;
2548 convert_time_to_pixels(
2549 time_window,
2550 evtime,
2551 width,
2552 &x);
2553
2554 /* Draw collision indicator */
2555 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2556 gdk_draw_point(hashed_process_data->pixmap,
2557 drawing->gc,
2558 x,
2559 (hashed_process_data->height/2)-3);
2560 hashed_process_data->x.middle_marked = TRUE;
2561 }
2562 } else {
2563 TimeWindow time_window =
2564 lttvwindow_get_time_window(control_flow_data->tab);
2565
2566#ifdef EXTRA_CHECK
2567 if(ltt_time_compare(evtime, time_window.start_time) == -1
2568 || ltt_time_compare(evtime, time_window.end_time) == 1)
2569 return;
2570#endif //EXTRA_CHECK
2571 Drawing_t *drawing = control_flow_data->drawing;
2572 guint width = drawing->width;
2573 guint x;
2574
2575 convert_time_to_pixels(
2576 time_window,
2577 evtime,
2578 width,
2579 &x);
2580
2581
2582 /* Jump over draw if we are at the same x position */
2583 if(unlikely(x == hashed_process_data->x.middle &&
2584 hashed_process_data->x.middle_used))
2585 {
2586 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2587 /* Draw collision indicator */
2588 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2589 gdk_draw_point(hashed_process_data->pixmap,
2590 drawing->gc,
2591 x,
2592 (hashed_process_data->height/2)-3);
2593 hashed_process_data->x.middle_marked = TRUE;
2594 }
2595 /* jump */
2596 } else {
2597 DrawContext draw_context;
2598
2599 /* Now create the drawing context that will be used to draw
2600 * items related to the last state. */
2601 draw_context.drawable = hashed_process_data->pixmap;
2602 draw_context.gc = drawing->gc;
2603 draw_context.pango_layout = drawing->pango_layout;
2604 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2605 draw_context.drawinfo.end.x = x;
2606
2607 draw_context.drawinfo.y.over = 1;
2608 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2609 draw_context.drawinfo.y.under = hashed_process_data->height;
2610
2611 draw_context.drawinfo.start.offset.over = 0;
2612 draw_context.drawinfo.start.offset.middle = 0;
2613 draw_context.drawinfo.start.offset.under = 0;
2614 draw_context.drawinfo.end.offset.over = 0;
2615 draw_context.drawinfo.end.offset.middle = 0;
2616 draw_context.drawinfo.end.offset.under = 0;
2617
2618 {
2619 /* Draw the line */
2620 PropertiesLine prop_line = prepare_s_e_line(process);
2621 draw_line((void*)&prop_line, (void*)&draw_context);
2622
2623 }
2624 /* become the last x position */
2625 hashed_process_data->x.middle = x;
2626 hashed_process_data->x.middle_used = TRUE;
2627 hashed_process_data->x.middle_marked = FALSE;
2628
2629 /* Calculate the next good time */
2630 convert_pixels_to_time(width, x+1, time_window,
2631 &hashed_process_data->next_good_time);
2632 }
2633 }
2634 }
2635
2636 return 0;
2637}
2638
2639
2640
2641
2642
2643
2644
2645
2646#if 0
2647/* before_process_hook
2648 *
2649 * Draw lines for process event.
2650 *
2651 * @param hook_data ControlFlowData structure of the viewer.
2652 * @param call_data Event context.
2653 *
2654 * This function adds items to be drawn in a queue for each process.
2655 *
2656 */
2657int before_process_hook(void *hook_data, void *call_data)
2658{
2659 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2660 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2661 ControlFlowData *control_flow_data = events_request->viewer_data;
2662
2663 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2664
2665 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
2666
2667 LttEvent *e;
2668 e = ltt_tracefile_get_event(tfc->tf);
2669
2670 LttTime evtime = ltt_event_time(e);
2671
2672 guint sub_id;
2673 {
2674 LttField *f = ltt_event_field(e);
2675 LttField *element;
2676 element = ltt_field_member(f,0);
2677 sub_id = ltt_event_get_long_unsigned(e,element);
2678 }
2679
2680 if(sub_id == 3) { /* exit */
2681
2682 /* Add process to process list (if not present) */
2683 LttvProcessState *process = tfs->process;
2684 guint pid = process->pid;
2685 LttTime birth;
2686 guint pl_height = 0;
2687 HashedProcessData *hashed_process_data = NULL;
2688
2689 ProcessList *process_list = control_flow_data->process_list;
2690
2691 g_assert(process != NULL);
2692
2693 birth = process->creation_time;
2694
2695 if(likely(process_list->current_hash_data[tfc->index] != NULL)) {
2696 hashed_process_data = process_list->current_hash_data[tfc->index];
2697 } else {
2698 hashed_process_data = processlist_get_process_data(process_list,
2699 pid,
2700 process->last_cpu_index,
2701 &birth,
2702 tfc->t_context->index);
2703 if(unlikely(hashed_process_data == NULL))
2704 {
2705 g_assert(pid == 0 || pid != process->ppid);
2706 /* Process not present */
2707 Drawing_t *drawing = control_flow_data->drawing;
2708 const gchar *name = g_quark_to_string(process->name);
2709 ProcessInfo *process_info;
2710 processlist_add(process_list,
2711 drawing,
2712 pid,
2713 process->last_cpu_index,
2714 process->ppid,
2715 &birth,
2716 tfc->t_context->index,
2717 name,
2718 &pl_height,
2719 &process_info,
2720 &hashed_process_data);
2721 gtk_widget_set_size_request(drawing->drawing_area,
2722 -1,
2723 pl_height);
2724 gtk_widget_queue_draw(drawing->drawing_area);
2725 }
2726 }
2727
2728 /* Now, the process is in the state hash and our own process hash.
2729 * We definitely can draw the items related to the ending state.
2730 */
2731
2732 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2733 evtime) > 0))
2734 {
2735 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2736 TimeWindow time_window =
2737 lttvwindow_get_time_window(control_flow_data->tab);
2738
2739#ifdef EXTRA_CHECK
2740 if(ltt_time_compare(evtime, time_window.start_time) == -1
2741 || ltt_time_compare(evtime, time_window.end_time) == 1)
2742 return;
2743#endif //EXTRA_CHECK
2744 Drawing_t *drawing = control_flow_data->drawing;
2745 guint width = drawing->width;
2746 guint x;
2747 convert_time_to_pixels(
2748 time_window,
2749 evtime,
2750 width,
2751 &x);
2752
2753 /* Draw collision indicator */
2754 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2755 gdk_draw_point(hashed_process_data->pixmap,
2756 drawing->gc,
2757 x,
2758 (hashed_process_data->height/2)-3);
2759 hashed_process_data->x.middle_marked = TRUE;
2760 }
2761 } else {
2762 TimeWindow time_window =
2763 lttvwindow_get_time_window(control_flow_data->tab);
2764
2765#ifdef EXTRA_CHECK
2766 if(ltt_time_compare(evtime, time_window.start_time) == -1
2767 || ltt_time_compare(evtime, time_window.end_time) == 1)
2768 return;
2769#endif //EXTRA_CHECK
2770 Drawing_t *drawing = control_flow_data->drawing;
2771 guint width = drawing->width;
2772 guint x;
2773
2774 convert_time_to_pixels(
2775 time_window,
2776 evtime,
2777 width,
2778 &x);
2779
2780
2781 /* Jump over draw if we are at the same x position */
2782 if(unlikely(x == hashed_process_data->x.middle &&
2783 hashed_process_data->x.middle_used))
2784 {
2785 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2786 /* Draw collision indicator */
2787 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2788 gdk_draw_point(hashed_process_data->pixmap,
2789 drawing->gc,
2790 x,
2791 (hashed_process_data->height/2)-3);
2792 hashed_process_data->x.middle_marked = TRUE;
2793 }
2794 /* jump */
2795 } else {
2796 DrawContext draw_context;
2797
2798 /* Now create the drawing context that will be used to draw
2799 * items related to the last state. */
2800 draw_context.drawable = hashed_process_data->pixmap;
2801 draw_context.gc = drawing->gc;
2802 draw_context.pango_layout = drawing->pango_layout;
2803 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2804 draw_context.drawinfo.end.x = x;
2805
2806 draw_context.drawinfo.y.over = 1;
1c736ed5 2807 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2808 draw_context.drawinfo.y.under = hashed_process_data->height;
4b7dc462 2809
2810 draw_context.drawinfo.start.offset.over = 0;
2811 draw_context.drawinfo.start.offset.middle = 0;
2812 draw_context.drawinfo.start.offset.under = 0;
2813 draw_context.drawinfo.end.offset.over = 0;
2814 draw_context.drawinfo.end.offset.middle = 0;
2815 draw_context.drawinfo.end.offset.under = 0;
dbd243b1 2816
4b7dc462 2817 {
2818 /* Draw the line */
9a1ec01b 2819 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 2820 draw_line((void*)&prop_line, (void*)&draw_context);
2821
2822 }
2823 /* become the last x position */
2824 hashed_process_data->x.middle = x;
e72908ed 2825 hashed_process_data->x.middle_used = TRUE;
2826 hashed_process_data->x.middle_marked = FALSE;
b2743953 2827
2828 /* Calculate the next good time */
2829 convert_pixels_to_time(width, x+1, time_window,
2830 &hashed_process_data->next_good_time);
dbd243b1 2831 }
dbd243b1 2832 }
2833
2da61677 2834 } else if(sub_id == 7) /* release */ {
2835
2836 guint pid;
2837 {
2838 LttField *f = ltt_event_field(e);
2839 LttField *element;
2840 element = ltt_field_member(f,1);
2841 pid = ltt_event_get_long_unsigned(e,element);
2842 }
2843
2844 /* Add process to process list (if not present) */
2845 /* Don't care about the process if it's not in the state hash already :
2846 * that means a process that has never done anything in the trace and
2847 * unknown suddently gets destroyed : no state meaningful to show. */
2848 LttvProcessState *process = lttv_state_find_process(tfs, pid);
2849
2850 if(process != NULL) {
2851 LttTime birth;
2852 guint pl_height = 0;
2853 HashedProcessData *hashed_process_data = NULL;
2854
2855 ProcessList *process_list = control_flow_data->process_list;
2856
2857 birth = process->creation_time;
2858
2859 /* Cannot use current process : this event happens on another process,
2860 * action done by the parent. */
2861 hashed_process_data = processlist_get_process_data(process_list,
2862 pid,
2863 process->last_cpu_index,
2864 &birth,
2865 tfc->t_context->index);
2866 if(unlikely(hashed_process_data == NULL))
2867 {
2868 g_assert(pid == 0 || pid != process->ppid);
2869 /* Process not present */
2870 Drawing_t *drawing = control_flow_data->drawing;
2871 const gchar *name = g_quark_to_string(process->name);
2872 ProcessInfo *process_info;
2873 processlist_add(process_list,
2874 drawing,
2875 pid,
2876 process->last_cpu_index,
2877 process->ppid,
2878 &birth,
2879 tfc->t_context->index,
2880 name,
2881 &pl_height,
2882 &process_info,
2883 &hashed_process_data);
2884 gtk_widget_set_size_request(drawing->drawing_area,
2885 -1,
2886 pl_height);
2887 gtk_widget_queue_draw(drawing->drawing_area);
2888 }
2889
2890 /* Now, the process is in the state hash and our own process hash.
2891 * We definitely can draw the items related to the ending state.
2892 */
2893
2894 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2895 evtime) > 0))
2896 {
2897 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2898 TimeWindow time_window =
2899 lttvwindow_get_time_window(control_flow_data->tab);
2900
2901#ifdef EXTRA_CHECK
2902 if(ltt_time_compare(evtime, time_window.start_time) == -1
2903 || ltt_time_compare(evtime, time_window.end_time) == 1)
2904 return;
2905#endif //EXTRA_CHECK
2906 Drawing_t *drawing = control_flow_data->drawing;
2907 guint width = drawing->width;
2908 guint x;
2909 convert_time_to_pixels(
2910 time_window,
2911 evtime,
2912 width,
2913 &x);
2914
2915 /* Draw collision indicator */
2916 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2917 gdk_draw_point(hashed_process_data->pixmap,
2918 drawing->gc,
2919 x,
2920 (hashed_process_data->height/2)-3);
2921 hashed_process_data->x.middle_marked = TRUE;
2922 }
2923 } else {
2924 TimeWindow time_window =
2925 lttvwindow_get_time_window(control_flow_data->tab);
2926
2927#ifdef EXTRA_CHECK
2928 if(ltt_time_compare(evtime, time_window.start_time) == -1
2929 || ltt_time_compare(evtime, time_window.end_time) == 1)
2930 return;
2931#endif //EXTRA_CHECK
2932 Drawing_t *drawing = control_flow_data->drawing;
2933 guint width = drawing->width;
2934 guint x;
2935
2936 convert_time_to_pixels(
2937 time_window,
2938 evtime,
2939 width,
2940 &x);
2941
2942
2943 /* Jump over draw if we are at the same x position */
2944 if(unlikely(x == hashed_process_data->x.middle &&
2945 hashed_process_data->x.middle_used))
2946 {
2947 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2948 /* Draw collision indicator */
2949 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2950 gdk_draw_point(hashed_process_data->pixmap,
2951 drawing->gc,
2952 x,
2953 (hashed_process_data->height/2)-3);
2954 hashed_process_data->x.middle_marked = TRUE;
2955 }
2956 /* jump */
2957 } else {
2958 DrawContext draw_context;
2959
2960 /* Now create the drawing context that will be used to draw
2961 * items related to the last state. */
2962 draw_context.drawable = hashed_process_data->pixmap;
2963 draw_context.gc = drawing->gc;
2964 draw_context.pango_layout = drawing->pango_layout;
2965 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2966 draw_context.drawinfo.end.x = x;
2967
2968 draw_context.drawinfo.y.over = 1;
2969 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2970 draw_context.drawinfo.y.under = hashed_process_data->height;
2971
2972 draw_context.drawinfo.start.offset.over = 0;
2973 draw_context.drawinfo.start.offset.middle = 0;
2974 draw_context.drawinfo.start.offset.under = 0;
2975 draw_context.drawinfo.end.offset.over = 0;
2976 draw_context.drawinfo.end.offset.middle = 0;
2977 draw_context.drawinfo.end.offset.under = 0;
2978
2979 {
2980 /* Draw the line */
2981 PropertiesLine prop_line = prepare_s_e_line(process);
2982 draw_line((void*)&prop_line, (void*)&draw_context);
2983
2984 }
2985 /* become the last x position */
2986 hashed_process_data->x.middle = x;
2987 hashed_process_data->x.middle_used = TRUE;
2988 hashed_process_data->x.middle_marked = FALSE;
2989
2990 /* Calculate the next good time */
2991 convert_pixels_to_time(width, x+1, time_window,
2992 &hashed_process_data->next_good_time);
2993 }
2994 }
2995 }
2996
dbd243b1 2997 }
2998 return 0;
2999
3000}
3001
2c82c4dc 3002#endif //0
3003
3004
3005
3006/* after_process_fork_hook
3007 *
3008 * Create the processlist entry for the child process. Put the last
3009 * position in x at the current time value.
3010 *
3011 * @param hook_data ControlFlowData structure of the viewer.
3012 * @param call_data Event context.
3013 *
3014 * This function adds items to be drawn in a queue for each process.
3015 *
3016 */
3017int after_process_fork_hook(void *hook_data, void *call_data)
3018{
3019 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3020 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
3021 ControlFlowData *control_flow_data = events_request->viewer_data;
3022
3023 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3024
3025 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
3026
348c6ba8 3027 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
3028
2c82c4dc 3029 LttEvent *e;
3030 e = ltt_tracefile_get_event(tfc->tf);
3031
3032 LttTime evtime = ltt_event_time(e);
3033
3034 guint child_pid;
3035 {
3036 child_pid = ltt_event_get_long_unsigned(e, thf->f2);
3037 }
3038
3039 /* Add process to process list (if not present) */
3040 LttvProcessState *process_child;
3041 LttTime birth;
3042 guint pl_height = 0;
3043 HashedProcessData *hashed_process_data_child = NULL;
3044
3045 ProcessList *process_list = control_flow_data->process_list;
3046
3047 /* Find child in the list... */
348c6ba8 3048 process_child = lttv_state_find_process(ts, ANY_CPU, child_pid);
2c82c4dc 3049 /* It should exist, because we are after the state update. */
3050 g_assert(process_child != NULL);
3051
3052 birth = process_child->creation_time;
3053
3054 /* Cannot use current process, because this action is done by the parent
3055 * on its child. */
3056 hashed_process_data_child = processlist_get_process_data(process_list,
3057 child_pid,
348c6ba8 3058 process_child->cpu,
2c82c4dc 3059 &birth,
3060 tfc->t_context->index);
3061 if(likely(hashed_process_data_child == NULL))
3062 {
3063 g_assert(child_pid == 0 || child_pid != process_child->ppid);
3064 /* Process not present */
3065 Drawing_t *drawing = control_flow_data->drawing;
3066 const gchar *name = g_quark_to_string(process_child->name);
3067 ProcessInfo *process_info;
3068 processlist_add(process_list,
3069 drawing,
3070 child_pid,
348c6ba8 3071 process_child->cpu,
2c82c4dc 3072 process_child->ppid,
3073 &birth,
3074 tfc->t_context->index,
3075 name,
3076 &pl_height,
3077 &process_info,
3078 &hashed_process_data_child);
3079 gtk_widget_set_size_request(drawing->drawing_area,
3080 -1,
3081 pl_height);
3082 gtk_widget_queue_draw(drawing->drawing_area);
3083 }
3084
3085
3086 if(likely(ltt_time_compare(hashed_process_data_child->next_good_time,
3087 evtime) <= 0))
3088 {
3089 TimeWindow time_window =
3090 lttvwindow_get_time_window(control_flow_data->tab);
3091
3092#ifdef EXTRA_CHECK
3093 if(ltt_time_compare(evtime, time_window.start_time) == -1
3094 || ltt_time_compare(evtime, time_window.end_time) == 1)
3095 return;
3096#endif //EXTRA_CHECK
3097 Drawing_t *drawing = control_flow_data->drawing;
3098 guint width = drawing->width;
3099 guint new_x;
3100 convert_time_to_pixels(
3101 time_window,
3102 evtime,
3103 width,
3104 &new_x);
3105
3106 if(likely(hashed_process_data_child->x.over != new_x)) {
3107 hashed_process_data_child->x.over = new_x;
3108 hashed_process_data_child->x.over_used = FALSE;
3109 hashed_process_data_child->x.over_marked = FALSE;
3110 }
3111 if(likely(hashed_process_data_child->x.middle != new_x)) {
3112 hashed_process_data_child->x.middle = new_x;
3113 hashed_process_data_child->x.middle_used = FALSE;
3114 hashed_process_data_child->x.middle_marked = FALSE;
3115 }
3116 if(likely(hashed_process_data_child->x.under != new_x)) {
3117 hashed_process_data_child->x.under = new_x;
3118 hashed_process_data_child->x.under_used = FALSE;
3119 hashed_process_data_child->x.under_marked = FALSE;
3120 }
3121 }
3122 return 0;
3123}
3124
3125
3126
3127/* after_process_exit_hook
3128 *
3129 * Create the processlist entry for the child process. Put the last
3130 * position in x at the current time value.
3131 *
3132 * @param hook_data ControlFlowData structure of the viewer.
3133 * @param call_data Event context.
3134 *
3135 * This function adds items to be drawn in a queue for each process.
3136 *
3137 */
3138int after_process_exit_hook(void *hook_data, void *call_data)
3139{
3140 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3141 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
3142 ControlFlowData *control_flow_data = events_request->viewer_data;
3143
3144 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3145
3146 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
3147
348c6ba8 3148 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
3149
2c82c4dc 3150 LttEvent *e;
3151 e = ltt_tracefile_get_event(tfc->tf);
3152
3153 LttTime evtime = ltt_event_time(e);
3154
3155 /* Add process to process list (if not present) */
348c6ba8 3156 //LttvProcessState *process = tfs->process;
3157 guint cpu = ltt_tracefile_num(tfc->tf);
3158 LttvProcessState *process = ts->running_process[cpu];
3159
3160 /* It should exist, because we are after the state update. */
3161 g_assert(process != NULL);
3162
2c82c4dc 3163 guint pid = process->pid;
3164 LttTime birth;
3165 guint pl_height = 0;
3166 HashedProcessData *hashed_process_data = NULL;
3167
3168 ProcessList *process_list = control_flow_data->process_list;
3169
2c82c4dc 3170 birth = process->creation_time;
3171
348c6ba8 3172 if(likely(process_list->current_hash_data[cpu] != NULL) ){
3173 hashed_process_data = process_list->current_hash_data[cpu];
2c82c4dc 3174 } else {
3175 hashed_process_data = processlist_get_process_data(process_list,
3176 pid,
348c6ba8 3177 process->cpu,
2c82c4dc 3178 &birth,
3179 tfc->t_context->index);
3180 if(unlikely(hashed_process_data == NULL))
3181 {
3182 g_assert(pid == 0 || pid != process->ppid);
3183 /* Process not present */
3184 Drawing_t *drawing = control_flow_data->drawing;
3185 const gchar *name = g_quark_to_string(process->name);
3186 ProcessInfo *process_info;
3187 processlist_add(process_list,
3188 drawing,
3189 pid,
348c6ba8 3190 process->cpu,
2c82c4dc 3191 process->ppid,
3192 &birth,
3193 tfc->t_context->index,
3194 name,
3195 &pl_height,
3196 &process_info,
3197 &hashed_process_data);
3198 gtk_widget_set_size_request(drawing->drawing_area,
3199 -1,
3200 pl_height);
3201 gtk_widget_queue_draw(drawing->drawing_area);
3202 }
3203
3204 /* Set the current process */
348c6ba8 3205 process_list->current_hash_data[process->cpu] =
2c82c4dc 3206 hashed_process_data;
3207 }
3208
3209 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
3210 evtime) <= 0))
3211 {
3212 TimeWindow time_window =
3213 lttvwindow_get_time_window(control_flow_data->tab);
dbd243b1 3214
2c82c4dc 3215#ifdef EXTRA_CHECK
3216 if(ltt_time_compare(evtime, time_window.start_time) == -1
3217 || ltt_time_compare(evtime, time_window.end_time) == 1)
3218 return;
3219#endif //EXTRA_CHECK
3220 Drawing_t *drawing = control_flow_data->drawing;
3221 guint width = drawing->width;
3222 guint new_x;
3223 convert_time_to_pixels(
3224 time_window,
3225 evtime,
3226 width,
3227 &new_x);
3228 if(unlikely(hashed_process_data->x.middle != new_x)) {
3229 hashed_process_data->x.middle = new_x;
3230 hashed_process_data->x.middle_used = FALSE;
3231 hashed_process_data->x.middle_marked = FALSE;
3232 }
3233 }
dbd243b1 3234
2c82c4dc 3235 return 0;
3236}
dbd243b1 3237
3238
2c82c4dc 3239#if 0
dbd243b1 3240
3241/* after_process_hook
e92eabaf 3242 *
3243 * Create the processlist entry for the child process. Put the last
3244 * position in x at the current time value.
3245 *
3246 * @param hook_data ControlFlowData structure of the viewer.
3247 * @param call_data Event context.
3248 *
3249 * This function adds items to be drawn in a queue for each process.
3250 *
3251 */
dbd243b1 3252int after_process_hook(void *hook_data, void *call_data)
e92eabaf 3253{
2c82c4dc 3254 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3255 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
e92eabaf 3256 ControlFlowData *control_flow_data = events_request->viewer_data;
3257
3258 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3259
3260 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
e92eabaf 3261
3262 LttEvent *e;
2c82c4dc 3263 e = ltt_tracefile_get_event(tfc->tf);
e92eabaf 3264
3265 LttTime evtime = ltt_event_time(e);
e92eabaf 3266
10a1069a 3267 guint sub_id;
3268 guint param1;
3269 {
3270 LttField *f = ltt_event_field(e);
3271 LttField *element;
3272 element = ltt_field_member(f,0);
3273 sub_id = ltt_event_get_long_unsigned(e,element);
3274 element = ltt_field_member(f,1);
3275 param1 = ltt_event_get_long_unsigned(e,element);
3276 }
e92eabaf 3277
10a1069a 3278 if(sub_id == 2) { /* fork */
3279
3280 guint child_pid = param1;
3281 /* Add process to process list (if not present) */
3282 LttvProcessState *process_child;
3283 LttTime birth;
1c736ed5 3284 guint pl_height = 0;
10a1069a 3285 HashedProcessData *hashed_process_data_child = NULL;
e92eabaf 3286
5c230fc4 3287 ProcessList *process_list = control_flow_data->process_list;
e92eabaf 3288
10a1069a 3289 /* Find child in the list... */
3290 process_child = lttv_state_find_process(tfs, child_pid);
3291 /* It should exist, because we are after the state update. */
3292 g_assert(process_child != NULL);
e92eabaf 3293
10a1069a 3294 birth = process_child->creation_time;
e92eabaf 3295
2da61677 3296 /* Cannot use current process, because this action is done by the parent
3297 * on its child. */
ac4e21cf 3298 hashed_process_data_child = processlist_get_process_data(process_list,
10a1069a 3299 child_pid,
40debf7b 3300 process_child->last_cpu_index,
10a1069a 3301 &birth,
ac4e21cf 3302 tfc->t_context->index);
1d1df11d 3303 if(likely(hashed_process_data_child == NULL))
10a1069a 3304 {
3305 g_assert(child_pid == 0 || child_pid != process_child->ppid);
3306 /* Process not present */
1c736ed5 3307 Drawing_t *drawing = control_flow_data->drawing;
aac69e70 3308 const gchar *name = g_quark_to_string(process_child->name);
4e86ae2e 3309 ProcessInfo *process_info;
10a1069a 3310 processlist_add(process_list,
1c736ed5 3311 drawing,
10a1069a 3312 child_pid,
40debf7b 3313 process_child->last_cpu_index,
10a1069a 3314 process_child->ppid,
3315 &birth,
3316 tfc->t_context->index,
3317 name,
3318 &pl_height,
4e86ae2e 3319 &process_info,
10a1069a 3320 &hashed_process_data_child);
1c736ed5 3321 gtk_widget_set_size_request(drawing->drawing_area,
3322 -1,
3323 pl_height);
3324 gtk_widget_queue_draw(drawing->drawing_area);
10a1069a 3325 }
e92eabaf 3326
40debf7b 3327
1d1df11d 3328 if(likely(ltt_time_compare(hashed_process_data_child->next_good_time,
3329 evtime) <= 0))
b2743953 3330 {
fd22065b 3331 TimeWindow time_window =
3332 lttvwindow_get_time_window(control_flow_data->tab);
3333
3334#ifdef EXTRA_CHECK
3335 if(ltt_time_compare(evtime, time_window.start_time) == -1
3336 || ltt_time_compare(evtime, time_window.end_time) == 1)
3337 return;
3338#endif //EXTRA_CHECK
d6fef890 3339 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 3340 guint width = drawing->width;
b2743953 3341 guint new_x;
3342 convert_time_to_pixels(
3343 time_window,
3344 evtime,
3345 width,
3346 &new_x);
e72908ed 3347
1d1df11d 3348 if(likely(hashed_process_data_child->x.over != new_x)) {
b2743953 3349 hashed_process_data_child->x.over = new_x;
3350 hashed_process_data_child->x.over_used = FALSE;
3351 hashed_process_data_child->x.over_marked = FALSE;
3352 }
1d1df11d 3353 if(likely(hashed_process_data_child->x.middle != new_x)) {
b2743953 3354 hashed_process_data_child->x.middle = new_x;
3355 hashed_process_data_child->x.middle_used = FALSE;
3356 hashed_process_data_child->x.middle_marked = FALSE;
3357 }
1d1df11d 3358 if(likely(hashed_process_data_child->x.under != new_x)) {
b2743953 3359 hashed_process_data_child->x.under = new_x;
3360 hashed_process_data_child->x.under_used = FALSE;
3361 hashed_process_data_child->x.under_marked = FALSE;
3362 }
e72908ed 3363 }
23093869 3364
10a1069a 3365 } else if(sub_id == 3) { /* exit */
dbd243b1 3366
10a1069a 3367 /* Add process to process list (if not present) */
3368 LttvProcessState *process = tfs->process;
3369 guint pid = process->pid;
3370 LttTime birth;
1c736ed5 3371 guint pl_height = 0;
10a1069a 3372 HashedProcessData *hashed_process_data = NULL;
dbd243b1 3373
5c230fc4 3374 ProcessList *process_list = control_flow_data->process_list;
dbd243b1 3375
10a1069a 3376 /* It should exist, because we are after the state update. */
3377 g_assert(process != NULL);
dbd243b1 3378
10a1069a 3379 birth = process->creation_time;
dbd243b1 3380
2c82c4dc 3381 if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL) ){
3382 hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
40debf7b 3383 } else {
ac4e21cf 3384 hashed_process_data = processlist_get_process_data(process_list,
40debf7b 3385 pid,
3386 process->last_cpu_index,
3387 &birth,
ac4e21cf 3388 tfc->t_context->index);
1d1df11d 3389 if(unlikely(hashed_process_data == NULL))
40debf7b 3390 {
3391 g_assert(pid == 0 || pid != process->ppid);
3392 /* Process not present */
1c736ed5 3393 Drawing_t *drawing = control_flow_data->drawing;
40debf7b 3394 const gchar *name = g_quark_to_string(process->name);
3395 ProcessInfo *process_info;
3396 processlist_add(process_list,
1c736ed5 3397 drawing,
40debf7b 3398 pid,
3399 process->last_cpu_index,
3400 process->ppid,
3401 &birth,
3402 tfc->t_context->index,
3403 name,
3404 &pl_height,
3405 &process_info,
3406 &hashed_process_data);
1c736ed5 3407 gtk_widget_set_size_request(drawing->drawing_area,
3408 -1,
3409 pl_height);
3410 gtk_widget_queue_draw(drawing->drawing_area);
40debf7b 3411 }
3412
3413 /* Set the current process */
3414 process_list->current_hash_data[process->last_cpu_index] =
3415 hashed_process_data;
e92eabaf 3416 }
dbd243b1 3417
1d1df11d 3418 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
3419 evtime) <= 0))
b2743953 3420 {
fd22065b 3421 TimeWindow time_window =
3422 lttvwindow_get_time_window(control_flow_data->tab);
3423
3424#ifdef EXTRA_CHECK
3425 if(ltt_time_compare(evtime, time_window.start_time) == -1
3426 || ltt_time_compare(evtime, time_window.end_time) == 1)
3427 return;
3428#endif //EXTRA_CHECK
d6fef890 3429 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 3430 guint width = drawing->width;
b2743953 3431 guint new_x;
3432 convert_time_to_pixels(
3433 time_window,
3434 evtime,
3435 width,
3436 &new_x);
1d1df11d 3437 if(unlikely(hashed_process_data->x.middle != new_x)) {
b2743953 3438 hashed_process_data->x.middle = new_x;
3439 hashed_process_data->x.middle_used = FALSE;
3440 hashed_process_data->x.middle_marked = FALSE;
3441 }
e72908ed 3442 }
3443
e92eabaf 3444 }
3445 return 0;
3446
3447}
2c82c4dc 3448#endif //0
f7afe191 3449
1b238973 3450gint update_time_window_hook(void *hook_data, void *call_data)
f7afe191 3451{
a56a1ba4 3452 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
a43d67ba 3453 Drawing_t *drawing = control_flow_data->drawing;
1c736ed5 3454 ProcessList *process_list = control_flow_data->process_list;
a43d67ba 3455
224446ce 3456 const TimeWindowNotifyData *time_window_nofify_data =
3457 ((const TimeWindowNotifyData *)call_data);
3458
14963be0 3459 TimeWindow *old_time_window =
224446ce 3460 time_window_nofify_data->old_time_window;
3461 TimeWindow *new_time_window =
3462 time_window_nofify_data->new_time_window;
a56a1ba4 3463
3cb8b205 3464 /* Update the ruler */
3465 drawing_update_ruler(control_flow_data->drawing,
3466 new_time_window);
3467
3468
a56a1ba4 3469 /* Two cases : zoom in/out or scrolling */
3470
3471 /* In order to make sure we can reuse the old drawing, the scale must
3472 * be the same and the new time interval being partly located in the
3473 * currently shown time interval. (reuse is only for scrolling)
3474 */
3475
2eef04b5 3476 g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
14963be0 3477 old_time_window->start_time.tv_sec,
3478 old_time_window->start_time.tv_nsec,
3479 old_time_window->time_width.tv_sec,
3480 old_time_window->time_width.tv_nsec);
a56a1ba4 3481
2eef04b5 3482 g_info("New time window HOOK : %lu, %lu to %lu, %lu",
14963be0 3483 new_time_window->start_time.tv_sec,
3484 new_time_window->start_time.tv_nsec,
3485 new_time_window->time_width.tv_sec,
3486 new_time_window->time_width.tv_nsec);
a56a1ba4 3487
14963be0 3488 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
3489 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
a56a1ba4 3490 {
3491 /* Same scale (scrolling) */
3492 g_info("scrolling");
14963be0 3493 LttTime *ns = &new_time_window->start_time;
20640e70 3494 LttTime *nw = &new_time_window->time_width;
14963be0 3495 LttTime *os = &old_time_window->start_time;
20640e70 3496 LttTime *ow = &old_time_window->time_width;
6f26fc38 3497 LttTime old_end = old_time_window->end_time;
3498 LttTime new_end = new_time_window->end_time;
a56a1ba4 3499 //if(ns<os+w<ns+w)
3500 //if(ns<os+w && os+w<ns+w)
3501 //if(ns<old_end && os<ns)
3502 if(ltt_time_compare(*ns, old_end) == -1
3503 && ltt_time_compare(*os, *ns) == -1)
3504 {
3505 g_info("scrolling near right");
3506 /* Scroll right, keep right part of the screen */
3507 guint x = 0;
51705146 3508 guint width = control_flow_data->drawing->width;
a56a1ba4 3509 convert_time_to_pixels(
a18124ff 3510 *old_time_window,
a56a1ba4 3511 *ns,
3512 width,
3513 &x);
3514
3515 /* Copy old data to new location */
1c736ed5 3516 copy_pixmap_region(process_list,
3517 NULL,
3518 control_flow_data->drawing->drawing_area->style->black_gc,
3519 NULL,
3520 x, 0,
3521 0, 0,
3522 control_flow_data->drawing->width-x+SAFETY, -1);
3523
6395d57c 3524 if(drawing->damage_begin == drawing->damage_end)
3525 drawing->damage_begin = control_flow_data->drawing->width-x;
3526 else
3527 drawing->damage_begin = 0;
3528
3529 drawing->damage_end = control_flow_data->drawing->width;
3530
a56a1ba4 3531 /* Clear the data request background, but not SAFETY */
1c736ed5 3532 rectangle_pixmap(process_list,
cfe526b1 3533 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 3534 TRUE,
6395d57c 3535 drawing->damage_begin+SAFETY, 0,
3536 drawing->damage_end - drawing->damage_begin, // do not overlap
1c736ed5 3537 -1);
7abb23ad 3538 gtk_widget_queue_draw(drawing->drawing_area);
3539 //gtk_widget_queue_draw_area (drawing->drawing_area,
3540 // 0,0,
3541 // control_flow_data->drawing->width,
3542 // control_flow_data->drawing->height);
a43d67ba 3543
a56a1ba4 3544 /* Get new data for the rest. */
501d5405 3545 drawing_data_request(control_flow_data->drawing,
6395d57c 3546 drawing->damage_begin, 0,
3547 drawing->damage_end - drawing->damage_begin,
501d5405 3548 control_flow_data->drawing->height);
a56a1ba4 3549 } else {
3550 //if(ns<os<ns+w)
3551 //if(ns<os && os<ns+w)
3552 //if(ns<os && os<new_end)
3553 if(ltt_time_compare(*ns,*os) == -1
3554 && ltt_time_compare(*os,new_end) == -1)
3555 {
3556 g_info("scrolling near left");
3557 /* Scroll left, keep left part of the screen */
3558 guint x = 0;
51705146 3559 guint width = control_flow_data->drawing->width;
a56a1ba4 3560 convert_time_to_pixels(
a18124ff 3561 *new_time_window,
a56a1ba4 3562 *os,
3563 width,
3564 &x);
6395d57c 3565
a56a1ba4 3566 /* Copy old data to new location */
1c736ed5 3567 copy_pixmap_region (process_list,
3568 NULL,
cfe526b1 3569 control_flow_data->drawing->drawing_area->style->black_gc,
1c736ed5 3570 NULL,
a56a1ba4 3571 0, 0,
3572 x, 0,
3573 -1, -1);
3574
6395d57c 3575 if(drawing->damage_begin == drawing->damage_end)
3576 drawing->damage_end = x;
3577 else
3578 drawing->damage_end =
51705146 3579 control_flow_data->drawing->width;
6395d57c 3580
3581 drawing->damage_begin = 0;
3582
1c736ed5 3583 rectangle_pixmap (process_list,
cfe526b1 3584 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 3585 TRUE,
6395d57c 3586 drawing->damage_begin, 0,
3587 drawing->damage_end - drawing->damage_begin, // do not overlap
1c736ed5 3588 -1);
a43d67ba 3589
7abb23ad 3590 gtk_widget_queue_draw(drawing->drawing_area);
3591 //gtk_widget_queue_draw_area (drawing->drawing_area,
3592 // 0,0,
3593 // control_flow_data->drawing->width,
3594 // control_flow_data->drawing->height);
a43d67ba 3595
6395d57c 3596
a56a1ba4 3597 /* Get new data for the rest. */
501d5405 3598 drawing_data_request(control_flow_data->drawing,
6395d57c 3599 drawing->damage_begin, 0,
3600 drawing->damage_end - drawing->damage_begin,
501d5405 3601 control_flow_data->drawing->height);
a56a1ba4 3602
a56a1ba4 3603 } else {
a43d67ba 3604 if(ltt_time_compare(*ns,*os) == 0)
3605 {
3606 g_info("not scrolling");
3607 } else {
3608 g_info("scrolling far");
3609 /* Cannot reuse any part of the screen : far jump */
3610
3611
1c736ed5 3612 rectangle_pixmap (process_list,
a43d67ba 3613 control_flow_data->drawing->drawing_area->style->black_gc,
3614 TRUE,
a56a1ba4 3615 0, 0,
a43d67ba 3616 control_flow_data->drawing->width+SAFETY, // do not overlap
1c736ed5 3617 -1);
a43d67ba 3618
7abb23ad 3619 //gtk_widget_queue_draw_area (drawing->drawing_area,
3620 // 0,0,
3621 // control_flow_data->drawing->width,
3622 // control_flow_data->drawing->height);
3623 gtk_widget_queue_draw(drawing->drawing_area);
a43d67ba 3624
6395d57c 3625 drawing->damage_begin = 0;
3626 drawing->damage_end = control_flow_data->drawing->width;
3627
a43d67ba 3628 drawing_data_request(control_flow_data->drawing,
a43d67ba 3629 0, 0,
3630 control_flow_data->drawing->width,
3631 control_flow_data->drawing->height);
3632
3633 }
a56a1ba4 3634 }
3635 }
3636 } else {
3637 /* Different scale (zoom) */
3638 g_info("zoom");
3639
1c736ed5 3640 rectangle_pixmap (process_list,
cfe526b1 3641 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 3642 TRUE,
3643 0, 0,
501d5405 3644 control_flow_data->drawing->width+SAFETY, // do not overlap
1c736ed5 3645 -1);
a56a1ba4 3646
7abb23ad 3647 //gtk_widget_queue_draw_area (drawing->drawing_area,
3648 // 0,0,
3649 // control_flow_data->drawing->width,
3650 // control_flow_data->drawing->height);
3651 gtk_widget_queue_draw(drawing->drawing_area);
a56a1ba4 3652
6395d57c 3653 drawing->damage_begin = 0;
3654 drawing->damage_end = control_flow_data->drawing->width;
3655
501d5405 3656 drawing_data_request(control_flow_data->drawing,
a56a1ba4 3657 0, 0,
501d5405 3658 control_flow_data->drawing->width,
3659 control_flow_data->drawing->height);
a56a1ba4 3660 }
3661
3cb8b205 3662
3663
a56a1ba4 3664 return 0;
f7afe191 3665}
3666
6395d57c 3667gint traceset_notify(void *hook_data, void *call_data)
3668{
3669 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
3670 Drawing_t *drawing = control_flow_data->drawing;
6395d57c 3671
6395d57c 3672
b9a010a2 3673 drawing_clear(control_flow_data->drawing);
3674 processlist_clear(control_flow_data->process_list);
07390ec1 3675 gtk_widget_set_size_request(
3676 control_flow_data->drawing->drawing_area,
3677 -1, processlist_get_height(control_flow_data->process_list));
d9267eec 3678 redraw_notify(control_flow_data, NULL);
6395d57c 3679
d9267eec 3680 request_background_data(control_flow_data);
6395d57c 3681
3682 return FALSE;
3683}
3684
ca0f8a8e 3685gint redraw_notify(void *hook_data, void *call_data)
3686{
3687 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
3688 Drawing_t *drawing = control_flow_data->drawing;
3689 GtkWidget *widget = drawing->drawing_area;
3690
3691 drawing->damage_begin = 0;
51705146 3692 drawing->damage_end = drawing->width;
ca0f8a8e 3693
49217bd4 3694 /* fun feature, to be separated someday... */
3695 drawing_clear(control_flow_data->drawing);
3696 processlist_clear(control_flow_data->process_list);
07390ec1 3697 gtk_widget_set_size_request(
3698 control_flow_data->drawing->drawing_area,
3699 -1, processlist_get_height(control_flow_data->process_list));
1c736ed5 3700 // Clear the images
3701 rectangle_pixmap (control_flow_data->process_list,
ca0f8a8e 3702 widget->style->black_gc,
3703 TRUE,
3704 0, 0,
f3b7430d 3705 drawing->alloc_width,
1c736ed5 3706 -1);
ca0f8a8e 3707
f3b7430d 3708 gtk_widget_queue_draw(drawing->drawing_area);
ca0f8a8e 3709
3710 if(drawing->damage_begin < drawing->damage_end)
3711 {
3712 drawing_data_request(drawing,
ca0f8a8e 3713 drawing->damage_begin,
3714 0,
3715 drawing->damage_end-drawing->damage_begin,
51705146 3716 drawing->height);
ca0f8a8e 3717 }
3718
7abb23ad 3719 //gtk_widget_queue_draw_area(drawing->drawing_area,
3720 // 0,0,
3721 // drawing->width,
3722 // drawing->height);
ca0f8a8e 3723 return FALSE;
3724
3725}
3726
3727
3728gint continue_notify(void *hook_data, void *call_data)
a43d67ba 3729{
3730 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
ca0f8a8e 3731 Drawing_t *drawing = control_flow_data->drawing;
a43d67ba 3732
6395d57c 3733 //g_assert(widget->allocation.width == drawing->damage_end);
ca0f8a8e 3734
3735 if(drawing->damage_begin < drawing->damage_end)
3736 {
3737 drawing_data_request(drawing,
ca0f8a8e 3738 drawing->damage_begin,
3739 0,
3740 drawing->damage_end-drawing->damage_begin,
51705146 3741 drawing->height);
ca0f8a8e 3742 }
3743
3744 return FALSE;
3745}
3746
3747
1b238973 3748gint update_current_time_hook(void *hook_data, void *call_data)
f7afe191 3749{
14963be0 3750 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
a43d67ba 3751 Drawing_t *drawing = control_flow_data->drawing;
a56a1ba4 3752
224446ce 3753 LttTime current_time = *((LttTime*)call_data);
a56a1ba4 3754
ca0f8a8e 3755 TimeWindow time_window =
3756 lttvwindow_get_time_window(control_flow_data->tab);
a56a1ba4 3757
ca0f8a8e 3758 LttTime time_begin = time_window.start_time;
3759 LttTime width = time_window.time_width;
90ef7e4a 3760 LttTime half_width;
3761 {
3762 guint64 time_ll = ltt_time_to_uint64(width);
3763 time_ll = time_ll >> 1; /* divide by two */
3764 half_width = ltt_time_from_uint64(time_ll);
3765 }
a56a1ba4 3766 LttTime time_end = ltt_time_add(time_begin, width);
3767
3768 LttvTracesetContext * tsc =
ca0f8a8e 3769 lttvwindow_get_traceset_context(control_flow_data->tab);
a56a1ba4 3770
ca0f8a8e 3771 LttTime trace_start = tsc->time_span.start_time;
3772 LttTime trace_end = tsc->time_span.end_time;
a56a1ba4 3773
2eef04b5 3774 g_info("New current time HOOK : %lu, %lu", current_time.tv_sec,
224446ce 3775 current_time.tv_nsec);
a56a1ba4 3776
3777
3778
3779 /* If current time is inside time interval, just move the highlight
3780 * bar */
3781
3782 /* Else, we have to change the time interval. We have to tell it
3783 * to the main window. */
3784 /* The time interval change will take care of placing the current
3785 * time at the center of the visible area, or nearest possible if we are
3786 * at one end of the trace. */
3787
3788
dbc0ef8a 3789 if(ltt_time_compare(current_time, time_begin) < 0)
a56a1ba4 3790 {
224446ce 3791 TimeWindow new_time_window;
3792
3793 if(ltt_time_compare(current_time,
dbc0ef8a 3794 ltt_time_add(trace_start,half_width)) < 0)
a56a1ba4 3795 time_begin = trace_start;
3796 else
224446ce 3797 time_begin = ltt_time_sub(current_time,half_width);
a56a1ba4 3798
224446ce 3799 new_time_window.start_time = time_begin;
3800 new_time_window.time_width = width;
a18124ff 3801 new_time_window.time_width_double = ltt_time_to_double(width);
6f26fc38 3802 new_time_window.end_time = ltt_time_add(time_begin, width);
a56a1ba4 3803
e800cf84 3804 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
a56a1ba4 3805 }
dbc0ef8a 3806 else if(ltt_time_compare(current_time, time_end) > 0)
a56a1ba4 3807 {
224446ce 3808 TimeWindow new_time_window;
3809
dbc0ef8a 3810 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
a56a1ba4 3811 time_begin = ltt_time_sub(trace_end,width);
3812 else
224446ce 3813 time_begin = ltt_time_sub(current_time,half_width);
a56a1ba4 3814
224446ce 3815 new_time_window.start_time = time_begin;
3816 new_time_window.time_width = width;
a18124ff 3817 new_time_window.time_width_double = ltt_time_to_double(width);
6f26fc38 3818 new_time_window.end_time = ltt_time_add(time_begin, width);
a56a1ba4 3819
e800cf84 3820 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
a56a1ba4 3821
3822 }
7abb23ad 3823 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
3824
a56a1ba4 3825
3826 return 0;
f7afe191 3827}
3828
8b90e648 3829typedef struct _ClosureData {
ca0f8a8e 3830 EventsRequest *events_request;
d0cd7f09 3831 LttvTracesetState *tss;
b9a010a2 3832 LttTime end_time;
bc8d270b 3833 guint x_end;
8b90e648 3834} ClosureData;
a56a1ba4 3835
8b90e648 3836
e800cf84 3837void draw_closure(gpointer key, gpointer value, gpointer user_data)
3838{
a56a1ba4 3839 ProcessInfo *process_info = (ProcessInfo*)key;
3840 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
3841 ClosureData *closure_data = (ClosureData*)user_data;
3842
e800cf84 3843 EventsRequest *events_request = closure_data->events_request;
3844 ControlFlowData *control_flow_data = events_request->viewer_data;
a56a1ba4 3845
e800cf84 3846 LttvTracesetState *tss = closure_data->tss;
d6fef890 3847 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
a56a1ba4 3848
e800cf84 3849 LttTime evtime = closure_data->end_time;
d0cd7f09 3850
e800cf84 3851 {
3852 /* For the process */
3853 /* First, check if the current process is in the state computation
3854 * process list. If it is there, that means we must add it right now and
3855 * draw items from the beginning of the read for it. If it is not
3856 * present, it's a new process and it was not present : it will
3857 * be added after the state update. */
31b6868d 3858#ifdef EXTRA_CHECK
e800cf84 3859 g_assert(lttv_traceset_number(tsc->ts) > 0);
31b6868d 3860#endif //EXTRA_CHECK
2c82c4dc 3861 LttvTraceContext *tc = tsc->traces[process_info->trace_num];
348c6ba8 3862 LttvTraceState *ts = (LttvTraceState*)tc;
2c82c4dc 3863
348c6ba8 3864#if 0
2c82c4dc 3865 //FIXME : optimize data structures.
3866 LttvTracefileState *tfs;
3867 LttvTracefileContext *tfc;
3868 guint i;
3869 for(i=0;i<tc->tracefiles->len;i++) {
3870 tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, i);
3871 if(ltt_tracefile_name(tfc->tf) == LTT_NAME_CPU
3872 && ltt_tracefile_num(tfc->tf) == process_info->cpu)
3873 break;
3874
3875 }
3876 g_assert(i<tc->tracefiles->len);
3877 tfs = LTTV_TRACEFILE_STATE(tfc);
348c6ba8 3878#endif //0
2c82c4dc 3879 // LttvTracefileState *tfs =
3880 // (LttvTracefileState*)tsc->traces[process_info->trace_num]->
3881 // tracefiles[process_info->cpu];
2da61677 3882
e800cf84 3883 LttvProcessState *process;
348c6ba8 3884 process = lttv_state_find_process(ts, process_info->cpu,
e025a729 3885 process_info->pid);
a56a1ba4 3886
1d1df11d 3887 if(unlikely(process != NULL)) {
e800cf84 3888
3889 /* Only draw for processes that are currently in the trace states */
ad2e83ba 3890
5c230fc4 3891 ProcessList *process_list = control_flow_data->process_list;
1d1df11d 3892#ifdef EXTRA_CHECK
e800cf84 3893 /* Should be alike when background info is ready */
3894 if(control_flow_data->background_info_waiting==0)
3895 g_assert(ltt_time_compare(process->creation_time,
3896 process_info->birth) == 0);
1d1df11d 3897#endif //EXTRA_CHECK
e800cf84 3898
3899 /* Now, the process is in the state hash and our own process hash.
3900 * We definitely can draw the items related to the ending state.
3901 */
3902
1d1df11d 3903 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
3904 evtime) <= 0))
e800cf84 3905 {
fd22065b 3906 TimeWindow time_window =
3907 lttvwindow_get_time_window(control_flow_data->tab);
3908
3909#ifdef EXTRA_CHECK
3910 if(ltt_time_compare(evtime, time_window.start_time) == -1
3911 || ltt_time_compare(evtime, time_window.end_time) == 1)
3912 return;
3913#endif //EXTRA_CHECK
d6fef890 3914 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 3915 guint width = drawing->width;
a56a1ba4 3916
bc8d270b 3917 guint x = closure_data->x_end;
8b90e648 3918
4b7dc462 3919 DrawContext draw_context;
3920
e800cf84 3921 /* Now create the drawing context that will be used to draw
3922 * items related to the last state. */
1c736ed5 3923 draw_context.drawable = hashed_process_data->pixmap;
e800cf84 3924 draw_context.gc = drawing->gc;
3925 draw_context.pango_layout = drawing->pango_layout;
e800cf84 3926 draw_context.drawinfo.end.x = x;
3927
1c736ed5 3928 draw_context.drawinfo.y.over = 1;
3929 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
3930 draw_context.drawinfo.y.under = hashed_process_data->height;
e800cf84 3931
3932 draw_context.drawinfo.start.offset.over = 0;
3933 draw_context.drawinfo.start.offset.middle = 0;
3934 draw_context.drawinfo.start.offset.under = 0;
3935 draw_context.drawinfo.end.offset.over = 0;
3936 draw_context.drawinfo.end.offset.middle = 0;
3937 draw_context.drawinfo.end.offset.under = 0;
9a1ec01b 3938#if 0
4b7dc462 3939 /* Jump over draw if we are at the same x position */
3940 if(x == hashed_process_data->x.over)
e800cf84 3941 {
4b7dc462 3942 /* jump */
3943 } else {
23093869 3944 draw_context.drawinfo.start.x = hashed_process_data->x.over;
3945 /* Draw the line */
3946 PropertiesLine prop_line = prepare_execmode_line(process);
3947 draw_line((void*)&prop_line, (void*)&draw_context);
3948
4b7dc462 3949 hashed_process_data->x.over = x;
23093869 3950 }
9a1ec01b 3951#endif //0
4b7dc462 3952
1d1df11d 3953 if(unlikely(x == hashed_process_data->x.middle &&
3954 hashed_process_data->x.middle_used)) {
b2743953 3955#if 0 /* do not mark closure : not missing information */
e72908ed 3956 if(hashed_process_data->x.middle_marked == FALSE) {
3957 /* Draw collision indicator */
3958 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
3959 gdk_draw_point(drawing->pixmap,
3960 drawing->gc,
3961 x,
2c6618bc 3962 y+(height/2)-3);
de4ea1ad 3963 hashed_process_data->x.middle_marked = TRUE;
e72908ed 3964 }
b2743953 3965#endif //0
4b7dc462 3966 /* Jump */
3967 } else {
23093869 3968 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
e800cf84 3969 /* Draw the line */
9a1ec01b 3970 PropertiesLine prop_line = prepare_s_e_line(process);
e800cf84 3971 draw_line((void*)&prop_line, (void*)&draw_context);
3972
4b7dc462 3973 /* become the last x position */
1d1df11d 3974 if(likely(x != hashed_process_data->x.middle)) {
e72908ed 3975 hashed_process_data->x.middle = x;
3976 /* but don't use the pixel */
3977 hashed_process_data->x.middle_used = FALSE;
b2743953 3978
3979 /* Calculate the next good time */
3980 convert_pixels_to_time(width, x+1, time_window,
3981 &hashed_process_data->next_good_time);
e72908ed 3982 }
e800cf84 3983 }
e800cf84 3984 }
3985 }
3986 }
3987 return;
8b90e648 3988}
3989
b9a010a2 3990int before_chunk(void *hook_data, void *call_data)
3991{
3992 EventsRequest *events_request = (EventsRequest*)hook_data;
16b9cadb 3993 LttvTracesetState *tss = (LttvTracesetState*)call_data;
7c0125e0 3994 ControlFlowData *cfd = (ControlFlowData*)events_request->viewer_data;
cd3892fe 3995#if 0
7c0125e0 3996 /* Desactivate sort */
3997 gtk_tree_sortable_set_sort_column_id(
3998 GTK_TREE_SORTABLE(cfd->process_list->list_store),
3999 TRACE_COLUMN,
4000 GTK_SORT_ASCENDING);
cd3892fe 4001#endif //0
b9a010a2 4002 drawing_chunk_begin(events_request, tss);
4003
4004 return 0;
4005}
4006
4007int before_request(void *hook_data, void *call_data)
ca0f8a8e 4008{
4009 EventsRequest *events_request = (EventsRequest*)hook_data;
16b9cadb 4010 LttvTracesetState *tss = (LttvTracesetState*)call_data;
7c0125e0 4011
ca0f8a8e 4012 drawing_data_request_begin(events_request, tss);
4013
4014 return 0;
4015}
4016
4017
8b90e648 4018/*
b9a010a2 4019 * after request is necessary in addition of after chunk in order to draw
4020 * lines until the end of the screen. after chunk just draws lines until
4021 * the last event.
4022 *
8b90e648 4023 * for each process
a56a1ba4 4024 * draw closing line
b9a010a2 4025 * expose
8b90e648 4026 */
b9a010a2 4027int after_request(void *hook_data, void *call_data)
8b90e648 4028{
ca0f8a8e 4029 EventsRequest *events_request = (EventsRequest*)hook_data;
4030 ControlFlowData *control_flow_data = events_request->viewer_data;
16b9cadb 4031 LttvTracesetState *tss = (LttvTracesetState*)call_data;
a56a1ba4 4032
5c230fc4 4033 ProcessList *process_list = control_flow_data->process_list;
b9a010a2 4034 LttTime end_time = events_request->end_time;
4035
4036 ClosureData closure_data;
4037 closure_data.events_request = (EventsRequest*)hook_data;
4038 closure_data.tss = tss;
4039 closure_data.end_time = end_time;
4040
bc8d270b 4041 TimeWindow time_window =
4042 lttvwindow_get_time_window(control_flow_data->tab);
4043 guint width = control_flow_data->drawing->width;
4044 convert_time_to_pixels(
4045 time_window,
4046 end_time,
4047 width,
4048 &closure_data.x_end);
4049
4050
b9a010a2 4051 /* Draw last items */
4052 g_hash_table_foreach(process_list->process_hash, draw_closure,
4053 (void*)&closure_data);
7c0125e0 4054
b9a010a2 4055
4056 /* Request expose */
4057 drawing_request_expose(events_request, tss, end_time);
4058 return 0;
4059}
4060
4061/*
4062 * for each process
4063 * draw closing line
e800cf84 4064 * expose
b9a010a2 4065 */
4066int after_chunk(void *hook_data, void *call_data)
4067{
4068 EventsRequest *events_request = (EventsRequest*)hook_data;
4069 ControlFlowData *control_flow_data = events_request->viewer_data;
16b9cadb 4070 LttvTracesetState *tss = (LttvTracesetState*)call_data;
4071 LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
b9a010a2 4072 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
4073 LttTime end_time;
4074
5c230fc4 4075 ProcessList *process_list = control_flow_data->process_list;
b9a010a2 4076
40debf7b 4077 g_free(process_list->current_hash_data);
4078 process_list->current_hash_data = NULL;
4079
e800cf84 4080 if(tfc != NULL)
4081 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
0c5dbe3b 4082 else /* end of traceset, or position now out of request : end */
4083 end_time = events_request->end_time;
4084
a56a1ba4 4085 ClosureData closure_data;
ca0f8a8e 4086 closure_data.events_request = (EventsRequest*)hook_data;
4087 closure_data.tss = tss;
b9a010a2 4088 closure_data.end_time = end_time;
a56a1ba4 4089
bc8d270b 4090 TimeWindow time_window =
4091 lttvwindow_get_time_window(control_flow_data->tab);
4092 guint width = control_flow_data->drawing->width;
4093 convert_time_to_pixels(
4094 time_window,
4095 end_time,
4096 width,
4097 &closure_data.x_end);
4098
b9a010a2 4099 /* Draw last items */
14963be0 4100 g_hash_table_foreach(process_list->process_hash, draw_closure,
a56a1ba4 4101 (void*)&closure_data);
cd3892fe 4102#if 0
7c0125e0 4103 /* Reactivate sort */
4104 gtk_tree_sortable_set_sort_column_id(
4105 GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
4106 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
4107 GTK_SORT_ASCENDING);
4108
4109 update_index_to_pixmap(control_flow_data->process_list);
cd3892fe 4110 /* Request a full expose : drawing scrambled */
4111 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
4112#endif //0
4113 /* Request expose (updates damages zone also) */
b9a010a2 4114 drawing_request_expose(events_request, tss, end_time);
ca0f8a8e 4115
4116 return 0;
8b90e648 4117}
4118
This page took 0.267633 seconds and 4 git commands to generate.