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