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