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