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