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