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