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