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