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