wait fork state now ok
[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 }
209 }
210 }
211
212 lttv_hooks_destroy(background_ready_hook);
213}
214
215
216
217
f0d936c0 218/**
219 * Event Viewer's constructor hook
220 *
221 * This constructor is given as a parameter to the menuitem and toolbar button
222 * registration. It creates the list.
ca0f8a8e 223 * @param tab A pointer to the parent tab.
f0d936c0 224 * @return The widget created.
225 */
226GtkWidget *
d47b33d2 227h_guicontrolflow(Tab *tab)
f0d936c0 228{
d47b33d2 229 g_info("h_guicontrolflow, %p", tab);
68997a22 230 ControlFlowData *control_flow_data = guicontrolflow() ;
a56a1ba4 231
ca0f8a8e 232 control_flow_data->tab = tab;
a56a1ba4 233
2a2fa4f0 234 //g_debug("time width2 : %u",time_window->time_width);
a56a1ba4 235 // Unreg done in the GuiControlFlow_Destructor
6395d57c 236 lttvwindow_register_traceset_notify(tab,
237 traceset_notify,
238 control_flow_data);
239
ca0f8a8e 240 lttvwindow_register_time_window_notify(tab,
224446ce 241 update_time_window_hook,
242 control_flow_data);
ca0f8a8e 243 lttvwindow_register_current_time_notify(tab,
224446ce 244 update_current_time_hook,
245 control_flow_data);
ca0f8a8e 246 lttvwindow_register_redraw_notify(tab,
247 redraw_notify,
248 control_flow_data);
249 lttvwindow_register_continue_notify(tab,
250 continue_notify,
251 control_flow_data);
6395d57c 252 request_background_data(control_flow_data);
253
ca0f8a8e 254
68997a22 255 return guicontrolflow_get_widget(control_flow_data) ;
a56a1ba4 256
f0d936c0 257}
258
3cff8cc1 259int event_selected_hook(void *hook_data, void *call_data)
f0d936c0 260{
68997a22 261 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
14963be0 262 guint *event_number = (guint*) call_data;
f0d936c0 263
2a2fa4f0 264 g_debug("DEBUG : event selected by main window : %u", *event_number);
a56a1ba4 265
f0d936c0 266}
267
c8bba5fa 268
e92eabaf 269static __inline PropertiesLine prepare_status_line(LttvProcessState *process)
c8bba5fa 270{
271 PropertiesLine prop_line;
272 prop_line.line_width = 2;
273 prop_line.style = GDK_LINE_SOLID;
e800cf84 274 prop_line.y = MIDDLE;
275 //GdkColormap *colormap = gdk_colormap_get_system();
c8bba5fa 276
e92eabaf 277 g_debug("prepare_status_line for state : %s", g_quark_to_string(process->state->s));
c8bba5fa 278
279 /* color of line : status of the process */
280 if(process->state->s == LTTV_STATE_UNNAMED)
e800cf84 281 prop_line.color = drawing_colors[COL_WHITE];
c8bba5fa 282 else if(process->state->s == LTTV_STATE_WAIT_FORK)
e800cf84 283 prop_line.color = drawing_colors[COL_WAIT_FORK];
c8bba5fa 284 else if(process->state->s == LTTV_STATE_WAIT_CPU)
e800cf84 285 prop_line.color = drawing_colors[COL_WAIT_CPU];
0828099d 286 else if(process->state->s == LTTV_STATE_ZOMBIE)
287 prop_line.color = drawing_colors[COL_ZOMBIE];
c8bba5fa 288 else if(process->state->s == LTTV_STATE_WAIT)
e800cf84 289 prop_line.color = drawing_colors[COL_WAIT];
c8bba5fa 290 else if(process->state->s == LTTV_STATE_RUN)
e800cf84 291 prop_line.color = drawing_colors[COL_RUN];
c8bba5fa 292 else
e800cf84 293 prop_line.color = drawing_colors[COL_WHITE];
294
295 //gdk_colormap_alloc_color(colormap,
296 // prop_line.color,
297 // FALSE,
298 // TRUE);
c8bba5fa 299
300 return prop_line;
301
302}
303
304
305
e92eabaf 306/* before_schedchange_hook
b9a010a2 307 *
f0d936c0 308 * This function basically draw lines and icons. Two types of lines are drawn :
309 * one small (3 pixels?) representing the state of the process and the second
310 * type is thicker (10 pixels?) representing on which CPU a process is running
311 * (and this only in running state).
312 *
313 * Extremums of the lines :
314 * x_min : time of the last event context for this process kept in memory.
315 * x_max : time of the current event.
316 * y : middle of the process in the process list. The process is found in the
317 * list, therefore is it's position in pixels.
318 *
319 * The choice of lines'color is defined by the context of the last event for this
320 * process.
321 */
b9a010a2 322
323
e92eabaf 324int before_schedchange_hook(void *hook_data, void *call_data)
f0d936c0 325{
b9a010a2 326 EventsRequest *events_request = (EventsRequest*)hook_data;
327 ControlFlowData *control_flow_data = events_request->viewer_data;
c8bba5fa 328 Drawing_t *drawing = control_flow_data->drawing;
b9a010a2 329
330 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
331
332 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
333 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
334
335 LttEvent *e;
336 e = tfc->e;
337
338 LttTime evtime = ltt_event_time(e);
339 TimeWindow time_window =
340 lttvwindow_get_time_window(control_flow_data->tab);
341
342 LttTime end_time = ltt_time_add(time_window.start_time,
343 time_window.time_width);
344
345 if(ltt_time_compare(evtime, time_window.start_time) == -1
346 || ltt_time_compare(evtime, end_time) == 1)
347 return;
348
c8bba5fa 349 guint width = drawing->width;
b9a010a2 350
351 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0) {
352
353 /* we are in a schedchange, before the state update. We must draw the
354 * items corresponding to the state before it changes : now is the right
355 * time to do it.
356 */
357
358 guint pid_out;
e800cf84 359 guint pid_in;
b9a010a2 360 {
b9a010a2 361 LttField *f = ltt_event_field(e);
362 LttField *element;
363 element = ltt_field_member(f,0);
364 pid_out = ltt_event_get_long_unsigned(e,element);
365 element = ltt_field_member(f,1);
366 pid_in = ltt_event_get_long_unsigned(e,element);
367 g_debug("out : %u in : %u", pid_out, pid_in);
368 }
b9a010a2 369
e800cf84 370 {
371 /* For the pid_out */
372 /* First, check if the current process is in the state computation
373 * process list. If it is there, that means we must add it right now and
374 * draw items from the beginning of the read for it. If it is not
375 * present, it's a new process and it was not present : it will
376 * be added after the state update. */
377 LttvProcessState *process;
378 process = lttv_state_find_process(tfs, pid_out);
b9a010a2 379
e800cf84 380 if(process != NULL) {
381 /* Well, the process_out existed : we must get it in the process hash
382 * or add it, and draw its items.
383 */
384 /* Add process to process list (if not present) */
385 guint y = 0, height = 0, pl_height = 0;
386 HashedProcessData *hashed_process_data = NULL;
387 ProcessList *process_list =
388 guicontrolflow_get_process_list(control_flow_data);
389 LttTime birth = process->creation_time;
390 const gchar *name = g_quark_to_string(process->name);
391
392 if(processlist_get_process_pixels(process_list,
393 pid_out,
394 &birth,
395 tfc->t_context->index,
396 &y,
397 &height,
398 &hashed_process_data) == 1)
399 {
e92eabaf 400 g_assert(pid_out == 0 || pid_out != process->ppid);
e800cf84 401 /* Process not present */
402 processlist_add(process_list,
b9a010a2 403 pid_out,
e92eabaf 404 process->ppid,
b9a010a2 405 &birth,
406 tfc->t_context->index,
e800cf84 407 name,
408 &pl_height,
409 &hashed_process_data);
410 processlist_get_process_pixels(process_list,
411 pid_out,
412 &birth,
413 tfc->t_context->index,
414 &y,
415 &height,
416 &hashed_process_data);
417 drawing_insert_square( drawing, y, height);
418 }
419
420 /* Now, the process is in the state hash and our own process hash.
421 * We definitely can draw the items related to the ending state.
422 */
423
424 /* Check if the x position is unset. In can have been left unset by
425 * a draw closure from a after chunk hook. This should never happen,
426 * because it must be set by before chunk hook to the damage_begin
427 * value.
428 */
429 g_assert(hashed_process_data->x != -1);
430 {
431 guint x;
432 DrawContext draw_context;
433
434 convert_time_to_pixels(
435 time_window.start_time,
436 end_time,
437 evtime,
438 width,
439 &x);
440
441 /* Now create the drawing context that will be used to draw
442 * items related to the last state. */
443 draw_context.drawable = drawing->pixmap;
444 draw_context.gc = drawing->gc;
445 draw_context.pango_layout = drawing->pango_layout;
446 draw_context.drawinfo.start.x = hashed_process_data->x;
447 draw_context.drawinfo.end.x = x;
448
449 draw_context.drawinfo.y.over = y;
450 draw_context.drawinfo.y.middle = y+(height/4);
451 draw_context.drawinfo.y.under = y+(height/2)+2;
452
453 draw_context.drawinfo.start.offset.over = 0;
454 draw_context.drawinfo.start.offset.middle = 0;
455 draw_context.drawinfo.start.offset.under = 0;
456 draw_context.drawinfo.end.offset.over = 0;
457 draw_context.drawinfo.end.offset.middle = 0;
458 draw_context.drawinfo.end.offset.under = 0;
459
460 {
461 /* Draw the line */
e92eabaf 462 PropertiesLine prop_line = prepare_status_line(process);
e800cf84 463 draw_line((void*)&prop_line, (void*)&draw_context);
464
465 }
466 /* become the last x position */
467 hashed_process_data->x = x;
468 }
469 }
470 }
471
472 {
473 /* For the pid_in */
474 /* First, check if the current process is in the state computation
475 * process list. If it is there, that means we must add it right now and
476 * draw items from the beginning of the read for it. If it is not
477 * present, it's a new process and it was not present : it will
478 * be added after the state update. */
479 LttvProcessState *process;
480 process = lttv_state_find_process(tfs, pid_in);
481
482 if(process != NULL) {
483 /* Well, the process_out existed : we must get it in the process hash
484 * or add it, and draw its items.
485 */
486 /* Add process to process list (if not present) */
487 guint y = 0, height = 0, pl_height = 0;
488 HashedProcessData *hashed_process_data = NULL;
489 ProcessList *process_list =
490 guicontrolflow_get_process_list(control_flow_data);
491 LttTime birth = process->creation_time;
492 const gchar *name = g_quark_to_string(process->name);
493
494 if(processlist_get_process_pixels(process_list,
495 pid_in,
b9a010a2 496 &birth,
497 tfc->t_context->index,
c8bba5fa 498 &y,
b9a010a2 499 &height,
e800cf84 500 &hashed_process_data) == 1)
501 {
e92eabaf 502 g_assert(pid_in == 0 || pid_in != process->ppid);
e800cf84 503 /* Process not present */
504 processlist_add(process_list,
505 pid_in,
e92eabaf 506 process->ppid,
e800cf84 507 &birth,
508 tfc->t_context->index,
509 name,
510 &pl_height,
511 &hashed_process_data);
512 processlist_get_process_pixels(process_list,
513 pid_in,
514 &birth,
515 tfc->t_context->index,
516 &y,
517 &height,
518 &hashed_process_data);
519 drawing_insert_square( drawing, y, height);
520 }
b9a010a2 521
e800cf84 522 /* Now, the process is in the state hash and our own process hash.
523 * We definitely can draw the items related to the ending state.
524 */
525
526 /* Check if the x position is unset. In can have been left unset by
527 * a draw closure from a after chunk hook. This should never happen,
528 * because it must be set by before chunk hook to the damage_begin
529 * value.
530 */
531 g_assert(hashed_process_data->x != -1);
c8bba5fa 532 {
e800cf84 533 guint x;
534 DrawContext draw_context;
535
536 convert_time_to_pixels(
537 time_window.start_time,
538 end_time,
539 evtime,
540 width,
541 &x);
542
543 /* Now create the drawing context that will be used to draw
544 * items related to the last state. */
545 draw_context.drawable = drawing->pixmap;
546 draw_context.gc = drawing->gc;
547 draw_context.pango_layout = drawing->pango_layout;
548 draw_context.drawinfo.start.x = hashed_process_data->x;
549 draw_context.drawinfo.end.x = x;
550
551 draw_context.drawinfo.y.over = y;
552 draw_context.drawinfo.y.middle = y+(height/4);
553 draw_context.drawinfo.y.under = y+(height/2)+2;
554
555 draw_context.drawinfo.start.offset.over = 0;
556 draw_context.drawinfo.start.offset.middle = 0;
557 draw_context.drawinfo.start.offset.under = 0;
558 draw_context.drawinfo.end.offset.over = 0;
559 draw_context.drawinfo.end.offset.middle = 0;
560 draw_context.drawinfo.end.offset.under = 0;
561
562 {
563 /* Draw the line */
e92eabaf 564 PropertiesLine prop_line = prepare_status_line(process);
e800cf84 565 draw_line((void*)&prop_line, (void*)&draw_context);
566 }
567
568
569 /* become the last x position */
570 hashed_process_data->x = x;
c8bba5fa 571 }
572 }
b9a010a2 573 }
f37a2002 574 } else if(strcmp(
575 ltt_eventtype_name(ltt_event_eventtype(e)),"process") == 0) {
576 /* We are in a fork or exit event */
577
578
b9a010a2 579 }
580
581
582 return 0;
583
584
b9a010a2 585#if 0
ca0f8a8e 586 EventsRequest *events_request = (EventsRequest*)hook_data;
587 ControlFlowData *control_flow_data =
588 (ControlFlowData*)events_request->viewer_data;
589 Tab *tab = control_flow_data->tab;
e9a9c513 590
a56a1ba4 591 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
e9a9c513 592
593 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1aff52a2 594 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
a56a1ba4 595
e9a9c513 596 LttEvent *e;
e9a9c513 597 e = tfc->e;
598
9444deae 599 LttTime evtime = ltt_event_time(e);
ca0f8a8e 600 TimeWindow time_window =
601 lttvwindow_get_time_window(tab);
9444deae 602
ca0f8a8e 603 LttTime end_time = ltt_time_add(time_window.start_time,
604 time_window.time_width);
9444deae 605 //if(time < time_beg || time > time_end) return;
ca0f8a8e 606 if(ltt_time_compare(evtime, time_window.start_time) == -1
9444deae 607 || ltt_time_compare(evtime, end_time) == 1)
608 return;
609
a56a1ba4 610 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
611 {
2a2fa4f0 612 g_debug("schedchange!");
a56a1ba4 613
614 /* Add process to process list (if not present) and get drawing "y" from
615 * process position */
616 guint pid_out, pid_in;
617 LttvProcessState *process_out, *process_in;
618 LttTime birth;
619 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
620
621 ProcessList *process_list =
ca0f8a8e 622 guicontrolflow_get_process_list(control_flow_data);
a56a1ba4 623
624
625 LttField *f = ltt_event_field(e);
626 LttField *element;
627 element = ltt_field_member(f,0);
628 pid_out = ltt_event_get_long_unsigned(e,element);
629 element = ltt_field_member(f,1);
630 pid_in = ltt_event_get_long_unsigned(e,element);
2a2fa4f0 631 g_debug("out : %u in : %u", pid_out, pid_in);
a56a1ba4 632
633
634 /* Find process pid_out in the list... */
87658614 635 process_out = lttv_state_find_process(tfs, pid_out);
1aff52a2 636 if(process_out == NULL) return 0;
2a2fa4f0 637 g_debug("out : %s",g_quark_to_string(process_out->state->s));
1aff52a2 638
a56a1ba4 639 birth = process_out->creation_time;
51705146 640 const gchar *name = g_quark_to_string(process_out->name);
14963be0 641 HashedProcessData *hashed_process_data_out = NULL;
a56a1ba4 642
643 if(processlist_get_process_pixels(process_list,
644 pid_out,
645 &birth,
d0cd7f09 646 tfc->t_context->index,
a56a1ba4 647 &y_out,
648 &height,
14963be0 649 &hashed_process_data_out) == 1)
a56a1ba4 650 {
51705146 651 /* Process not present */
652 processlist_add(process_list,
653 pid_out,
654 &birth,
655 tfc->t_context->index,
656 name,
657 &pl_height,
658 &hashed_process_data_out);
659 g_assert(processlist_get_process_pixels(process_list,
660 pid_out,
661 &birth,
662 tfc->t_context->index,
663 &y_out,
664 &height,
665 &hashed_process_data_out)==0);
666 drawing_insert_square( control_flow_data->drawing, y_out, height);
a56a1ba4 667 }
51705146 668 //g_free(name);
a56a1ba4 669
670 /* Find process pid_in in the list... */
87658614 671 process_in = lttv_state_find_process(tfs, pid_in);
1aff52a2 672 if(process_in == NULL) return 0;
2a2fa4f0 673 g_debug("in : %s",g_quark_to_string(process_in->state->s));
a56a1ba4 674
675 birth = process_in->creation_time;
51705146 676 name = g_quark_to_string(process_in->name);
14963be0 677 HashedProcessData *hashed_process_data_in = NULL;
a56a1ba4 678
679 if(processlist_get_process_pixels(process_list,
680 pid_in,
681 &birth,
d0cd7f09 682 tfc->t_context->index,
a56a1ba4 683 &y_in,
684 &height,
14963be0 685 &hashed_process_data_in) == 1)
a56a1ba4 686 {
51705146 687 /* Process not present */
a56a1ba4 688 processlist_add(process_list,
689 pid_in,
690 &birth,
d0cd7f09 691 tfc->t_context->index,
a56a1ba4 692 name,
693 &pl_height,
14963be0 694 &hashed_process_data_in);
a56a1ba4 695 processlist_get_process_pixels(process_list,
696 pid_in,
697 &birth,
d0cd7f09 698 tfc->t_context->index,
a56a1ba4 699 &y_in,
700 &height,
14963be0 701 &hashed_process_data_in);
a56a1ba4 702
ca0f8a8e 703 drawing_insert_square( control_flow_data->drawing, y_in, height);
a56a1ba4 704 }
51705146 705 //g_free(name);
a56a1ba4 706
707
708 /* Find pixels corresponding to time of the event. If the time does
709 * not fit in the window, show a warning, not supposed to happend. */
710 guint x = 0;
51705146 711 guint width = control_flow_data->drawing->width;
a56a1ba4 712
713 LttTime time = ltt_event_time(e);
714
ca0f8a8e 715 LttTime window_end = ltt_time_add(time_window.time_width,
716 time_window.start_time);
a56a1ba4 717
718
719 convert_time_to_pixels(
ca0f8a8e 720 time_window.start_time,
a56a1ba4 721 window_end,
722 time,
723 width,
724 &x);
9444deae 725 //assert(x <= width);
51705146 726 //
a56a1ba4 727 /* draw what represents the event for outgoing process. */
728
14963be0 729 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
68997a22 730 draw_context_out->current->modify_over->x = x;
319e9d81 731 draw_context_out->current->modify_under->x = x;
68997a22 732 draw_context_out->current->modify_over->y = y_out;
319e9d81 733 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
501d5405 734 draw_context_out->drawable = control_flow_data->drawing->pixmap;
735 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
736 GtkWidget *widget = control_flow_data->drawing->drawing_area;
a56a1ba4 737 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
d0cd7f09 738 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
739 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
a56a1ba4 740 //draw_context_out->gc = widget->style->black_gc;
741
742 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
501d5405 743 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
a56a1ba4 744
d0cd7f09 745 /* Draw the line/background of the out process */
746 if(draw_context_out->previous->middle->x == -1)
747 {
ca0f8a8e 748 draw_context_out->previous->over->x =
749 control_flow_data->drawing->damage_begin;
750 draw_context_out->previous->middle->x =
751 control_flow_data->drawing->damage_begin;
752 draw_context_out->previous->under->x =
753 control_flow_data->drawing->damage_begin;
754
755 g_debug("out middle x_beg : %u",control_flow_data->drawing->damage_begin);
d0cd7f09 756 }
757
758 draw_context_out->current->middle->x = x;
759 draw_context_out->current->over->x = x;
760 draw_context_out->current->under->x = x;
761 draw_context_out->current->middle->y = y_out + height/2;
762 draw_context_out->current->over->y = y_out;
763 draw_context_out->current->under->y = y_out + height;
764 draw_context_out->previous->middle->y = y_out + height/2;
765 draw_context_out->previous->over->y = y_out;
766 draw_context_out->previous->under->y = y_out + height;
767
768 draw_context_out->drawable = control_flow_data->drawing->pixmap;
769 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
770
771 if(process_out->state->s == LTTV_STATE_RUN)
772 {
51705146 773 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
774 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
775 draw_context_out->gc = control_flow_data->drawing->gc;
d0cd7f09 776
777 PropertiesBG prop_bg;
778 prop_bg.color = g_new(GdkColor,1);
779
780 switch(tfc->index) {
781 case 0:
782 prop_bg.color->red = 0x1515;
783 prop_bg.color->green = 0x1515;
784 prop_bg.color->blue = 0x8c8c;
785 break;
786 case 1:
787 prop_bg.color->red = 0x4e4e;
788 prop_bg.color->green = 0xa9a9;
789 prop_bg.color->blue = 0xa4a4;
790 break;
791 case 2:
792 prop_bg.color->red = 0x7a7a;
793 prop_bg.color->green = 0x4a4a;
794 prop_bg.color->blue = 0x8b8b;
795 break;
796 case 3:
797 prop_bg.color->red = 0x8080;
798 prop_bg.color->green = 0x7777;
799 prop_bg.color->blue = 0x4747;
800 break;
801 default:
802 prop_bg.color->red = 0xe7e7;
803 prop_bg.color->green = 0xe7e7;
804 prop_bg.color->blue = 0xe7e7;
805 }
806
2a2fa4f0 807 g_debug("calling from draw_event");
d0cd7f09 808 draw_bg((void*)&prop_bg, (void*)draw_context_out);
809 g_free(prop_bg.color);
51705146 810 //gdk_gc_unref(draw_context_out->gc);
d0cd7f09 811 }
812
813 draw_context_out->gc = widget->style->black_gc;
814
a56a1ba4 815 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
2df6f2bd 816 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 817 PropertiesText prop_text_out;
818 prop_text_out.foreground = &colorfg_out;
819 prop_text_out.background = &colorbg_out;
cfe526b1 820 prop_text_out.size = 6;
a56a1ba4 821 prop_text_out.position = OVER;
822
cfe526b1 823 /* color of text : status of the process */
824 if(process_out->state->s == LTTV_STATE_UNNAMED)
825 {
826 prop_text_out.foreground->red = 0xffff;
827 prop_text_out.foreground->green = 0xffff;
828 prop_text_out.foreground->blue = 0xffff;
829 }
830 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
831 {
832 prop_text_out.foreground->red = 0x0fff;
d52cfc84 833 prop_text_out.foreground->green = 0xffff;
834 prop_text_out.foreground->blue = 0xfff0;
cfe526b1 835 }
836 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
837 {
2df6f2bd 838 prop_text_out.foreground->red = 0xffff;
839 prop_text_out.foreground->green = 0xffff;
cfe526b1 840 prop_text_out.foreground->blue = 0x0000;
841 }
0828099d 842 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 843 {
844 prop_text_out.foreground->red = 0xffff;
845 prop_text_out.foreground->green = 0x0000;
846 prop_text_out.foreground->blue = 0xffff;
847 }
848 else if(process_out->state->s == LTTV_STATE_WAIT)
849 {
850 prop_text_out.foreground->red = 0xffff;
851 prop_text_out.foreground->green = 0x0000;
852 prop_text_out.foreground->blue = 0x0000;
853 }
854 else if(process_out->state->s == LTTV_STATE_RUN)
855 {
856 prop_text_out.foreground->red = 0x0000;
857 prop_text_out.foreground->green = 0xffff;
858 prop_text_out.foreground->blue = 0x0000;
859 }
860 else
861 {
862 prop_text_out.foreground->red = 0xffff;
863 prop_text_out.foreground->green = 0xffff;
864 prop_text_out.foreground->blue = 0xffff;
865 }
866
d52cfc84 867
a56a1ba4 868 /* Print status of the process : U, WF, WC, E, W, R */
869 if(process_out->state->s == LTTV_STATE_UNNAMED)
cfe526b1 870 prop_text_out.text = "U->";
a56a1ba4 871 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
cfe526b1 872 prop_text_out.text = "WF->";
a56a1ba4 873 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
cfe526b1 874 prop_text_out.text = "WC->";
0828099d 875 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 876 prop_text_out.text = "E->";
a56a1ba4 877 else if(process_out->state->s == LTTV_STATE_WAIT)
cfe526b1 878 prop_text_out.text = "W->";
a56a1ba4 879 else if(process_out->state->s == LTTV_STATE_RUN)
cfe526b1 880 prop_text_out.text = "R->";
a56a1ba4 881 else
68997a22 882 prop_text_out.text = "U";
a56a1ba4 883
884 draw_text((void*)&prop_text_out, (void*)draw_context_out);
d0cd7f09 885 //gdk_gc_unref(draw_context_out->gc);
a56a1ba4 886
51705146 887 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
888 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
889 draw_context_out->gc = control_flow_data->drawing->gc;
a56a1ba4 890
891 PropertiesLine prop_line_out;
892 prop_line_out.color = g_new(GdkColor,1);
cfe526b1 893 prop_line_out.line_width = 2;
a56a1ba4 894 prop_line_out.style = GDK_LINE_SOLID;
895 prop_line_out.position = MIDDLE;
d52cfc84 896
2a2fa4f0 897 g_debug("out state : %s", g_quark_to_string(process_out->state->s));
a56a1ba4 898
899 /* color of line : status of the process */
900 if(process_out->state->s == LTTV_STATE_UNNAMED)
901 {
cfe526b1 902 prop_line_out.color->red = 0xffff;
903 prop_line_out.color->green = 0xffff;
904 prop_line_out.color->blue = 0xffff;
a56a1ba4 905 }
906 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
907 {
908 prop_line_out.color->red = 0x0fff;
d52cfc84 909 prop_line_out.color->green = 0xffff;
910 prop_line_out.color->blue = 0xfff0;
a56a1ba4 911 }
912 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
913 {
2df6f2bd 914 prop_line_out.color->red = 0xffff;
915 prop_line_out.color->green = 0xffff;
a56a1ba4 916 prop_line_out.color->blue = 0x0000;
917 }
0828099d 918 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
a56a1ba4 919 {
920 prop_line_out.color->red = 0xffff;
921 prop_line_out.color->green = 0x0000;
922 prop_line_out.color->blue = 0xffff;
923 }
924 else if(process_out->state->s == LTTV_STATE_WAIT)
925 {
926 prop_line_out.color->red = 0xffff;
927 prop_line_out.color->green = 0x0000;
928 prop_line_out.color->blue = 0x0000;
929 }
930 else if(process_out->state->s == LTTV_STATE_RUN)
931 {
932 prop_line_out.color->red = 0x0000;
933 prop_line_out.color->green = 0xffff;
934 prop_line_out.color->blue = 0x0000;
935 }
936 else
937 {
cfe526b1 938 prop_line_out.color->red = 0xffff;
939 prop_line_out.color->green = 0xffff;
940 prop_line_out.color->blue = 0xffff;
a56a1ba4 941 }
942
943 draw_line((void*)&prop_line_out, (void*)draw_context_out);
944 g_free(prop_line_out.color);
51705146 945 //gdk_gc_unref(draw_context_out->gc);
a56a1ba4 946 /* Note : finishing line will have to be added when trace read over. */
947
948 /* Finally, update the drawing context of the pid_in. */
949
14963be0 950 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
68997a22 951 draw_context_in->current->modify_over->x = x;
319e9d81 952 draw_context_in->current->modify_under->x = x;
68997a22 953 draw_context_in->current->modify_over->y = y_in;
319e9d81 954 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
501d5405 955 draw_context_in->drawable = control_flow_data->drawing->pixmap;
956 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
957 widget = control_flow_data->drawing->drawing_area;
a56a1ba4 958 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
959 //draw_context_in->gc = widget->style->black_gc;
d0cd7f09 960 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
961 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
a56a1ba4 962
963 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
501d5405 964 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 965
966 /* Draw the line/bg of the in process */
967 if(draw_context_in->previous->middle->x == -1)
968 {
ca0f8a8e 969 draw_context_in->previous->over->x =
970 control_flow_data->drawing->damage_begin;
971 draw_context_in->previous->middle->x =
972 control_flow_data->drawing->damage_begin;
973 draw_context_in->previous->under->x =
974 control_flow_data->drawing->damage_begin;
975
976 g_debug("in middle x_beg : %u",control_flow_data->drawing->damage_begin);
977
d0cd7f09 978 }
979
980 draw_context_in->current->middle->x = x;
981 draw_context_in->current->over->x = x;
982 draw_context_in->current->under->x = x;
983 draw_context_in->current->middle->y = y_in + height/2;
984 draw_context_in->current->over->y = y_in;
985 draw_context_in->current->under->y = y_in + height;
986 draw_context_in->previous->middle->y = y_in + height/2;
987 draw_context_in->previous->over->y = y_in;
988 draw_context_in->previous->under->y = y_in + height;
a56a1ba4 989
d0cd7f09 990 draw_context_in->drawable = control_flow_data->drawing->pixmap;
991 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
992
993
994 if(process_in->state->s == LTTV_STATE_RUN)
995 {
51705146 996 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
997 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
998 draw_context_in->gc = control_flow_data->drawing->gc;
d0cd7f09 999
1000 PropertiesBG prop_bg;
1001 prop_bg.color = g_new(GdkColor,1);
1002
1003 switch(tfc->index) {
1004 case 0:
1005 prop_bg.color->red = 0x1515;
1006 prop_bg.color->green = 0x1515;
1007 prop_bg.color->blue = 0x8c8c;
1008 break;
1009 case 1:
1010 prop_bg.color->red = 0x4e4e;
1011 prop_bg.color->green = 0xa9a9;
1012 prop_bg.color->blue = 0xa4a4;
1013 break;
1014 case 2:
1015 prop_bg.color->red = 0x7a7a;
1016 prop_bg.color->green = 0x4a4a;
1017 prop_bg.color->blue = 0x8b8b;
1018 break;
1019 case 3:
1020 prop_bg.color->red = 0x8080;
1021 prop_bg.color->green = 0x7777;
1022 prop_bg.color->blue = 0x4747;
1023 break;
1024 default:
1025 prop_bg.color->red = 0xe7e7;
1026 prop_bg.color->green = 0xe7e7;
1027 prop_bg.color->blue = 0xe7e7;
1028 }
1029
1030
1031 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1032 g_free(prop_bg.color);
51705146 1033 //gdk_gc_unref(draw_context_in->gc);
d0cd7f09 1034 }
1035
1036 draw_context_in->gc = widget->style->black_gc;
1037
a56a1ba4 1038 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
2df6f2bd 1039 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1040 PropertiesText prop_text_in;
1041 prop_text_in.foreground = &colorfg_in;
1042 prop_text_in.background = &colorbg_in;
cfe526b1 1043 prop_text_in.size = 6;
a56a1ba4 1044 prop_text_in.position = OVER;
1045
2a2fa4f0 1046 g_debug("in state : %s", g_quark_to_string(process_in->state->s));
cfe526b1 1047 /* foreground of text : status of the process */
1048 if(process_in->state->s == LTTV_STATE_UNNAMED)
1049 {
1050 prop_text_in.foreground->red = 0xffff;
1051 prop_text_in.foreground->green = 0xffff;
1052 prop_text_in.foreground->blue = 0xffff;
1053 }
1054 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1055 {
1056 prop_text_in.foreground->red = 0x0fff;
d52cfc84 1057 prop_text_in.foreground->green = 0xffff;
1058 prop_text_in.foreground->blue = 0xfff0;
cfe526b1 1059 }
1060 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1061 {
2df6f2bd 1062 prop_text_in.foreground->red = 0xffff;
1063 prop_text_in.foreground->green = 0xffff;
cfe526b1 1064 prop_text_in.foreground->blue = 0x0000;
1065 }
0828099d 1066 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1067 {
1068 prop_text_in.foreground->red = 0xffff;
1069 prop_text_in.foreground->green = 0x0000;
1070 prop_text_in.foreground->blue = 0xffff;
1071 }
1072 else if(process_in->state->s == LTTV_STATE_WAIT)
1073 {
1074 prop_text_in.foreground->red = 0xffff;
1075 prop_text_in.foreground->green = 0x0000;
1076 prop_text_in.foreground->blue = 0x0000;
1077 }
1078 else if(process_in->state->s == LTTV_STATE_RUN)
1079 {
1080 prop_text_in.foreground->red = 0x0000;
1081 prop_text_in.foreground->green = 0xffff;
1082 prop_text_in.foreground->blue = 0x0000;
1083 }
1084 else
1085 {
1086 prop_text_in.foreground->red = 0xffff;
1087 prop_text_in.foreground->green = 0xffff;
1088 prop_text_in.foreground->blue = 0xffff;
1089 }
1090
1091
1092
a56a1ba4 1093 /* Print status of the process : U, WF, WC, E, W, R */
1094 if(process_in->state->s == LTTV_STATE_UNNAMED)
cfe526b1 1095 prop_text_in.text = "U->";
a56a1ba4 1096 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
cfe526b1 1097 prop_text_in.text = "WF->";
a56a1ba4 1098 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
cfe526b1 1099 prop_text_in.text = "WC->";
0828099d 1100 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1101 prop_text_in.text = "E->";
a56a1ba4 1102 else if(process_in->state->s == LTTV_STATE_WAIT)
cfe526b1 1103 prop_text_in.text = "W->";
a56a1ba4 1104 else if(process_in->state->s == LTTV_STATE_RUN)
cfe526b1 1105 prop_text_in.text = "R->";
a56a1ba4 1106 else
68997a22 1107 prop_text_in.text = "U";
a56a1ba4 1108
1109 draw_text((void*)&prop_text_in, (void*)draw_context_in);
d0cd7f09 1110 //gdk_gc_unref(draw_context_in->gc);
1111
51705146 1112 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1113 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1114 draw_context_in->gc = control_flow_data->drawing->gc;
d0cd7f09 1115
a56a1ba4 1116 PropertiesLine prop_line_in;
1117 prop_line_in.color = g_new(GdkColor,1);
cfe526b1 1118 prop_line_in.line_width = 2;
a56a1ba4 1119 prop_line_in.style = GDK_LINE_SOLID;
1120 prop_line_in.position = MIDDLE;
1121
1122 /* color of line : status of the process */
1123 if(process_in->state->s == LTTV_STATE_UNNAMED)
1124 {
cfe526b1 1125 prop_line_in.color->red = 0xffff;
1126 prop_line_in.color->green = 0xffff;
1127 prop_line_in.color->blue = 0xffff;
a56a1ba4 1128 }
1129 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1130 {
1131 prop_line_in.color->red = 0x0fff;
d52cfc84 1132 prop_line_in.color->green = 0xffff;
1133 prop_line_in.color->blue = 0xfff0;
a56a1ba4 1134 }
1135 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1136 {
2df6f2bd 1137 prop_line_in.color->red = 0xffff;
1138 prop_line_in.color->green = 0xffff;
a56a1ba4 1139 prop_line_in.color->blue = 0x0000;
1140 }
0828099d 1141 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
a56a1ba4 1142 {
1143 prop_line_in.color->red = 0xffff;
1144 prop_line_in.color->green = 0x0000;
1145 prop_line_in.color->blue = 0xffff;
1146 }
1147 else if(process_in->state->s == LTTV_STATE_WAIT)
1148 {
1149 prop_line_in.color->red = 0xffff;
1150 prop_line_in.color->green = 0x0000;
1151 prop_line_in.color->blue = 0x0000;
1152 }
1153 else if(process_in->state->s == LTTV_STATE_RUN)
1154 {
1155 prop_line_in.color->red = 0x0000;
1156 prop_line_in.color->green = 0xffff;
1157 prop_line_in.color->blue = 0x0000;
1158 }
1159 else
1160 {
cfe526b1 1161 prop_line_in.color->red = 0xffff;
1162 prop_line_in.color->green = 0xffff;
1163 prop_line_in.color->blue = 0xffff;
a56a1ba4 1164 }
1165
1166 draw_line((void*)&prop_line_in, (void*)draw_context_in);
1167 g_free(prop_line_in.color);
51705146 1168 //gdk_gc_unref(draw_context_in->gc);
a56a1ba4 1169 }
1170
1171 return 0;
b9a010a2 1172#endif //0
1173
1174
a56a1ba4 1175
51705146 1176 /* Text dump */
80a52ff8 1177#ifdef DONTSHOW
a56a1ba4 1178 GString *string = g_string_new("");;
1179 gboolean field_names = TRUE, state = TRUE;
80a52ff8 1180
e9a9c513 1181 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
1182 g_string_append_printf(string,"\n");
1183
1184 if(state) {
1185 g_string_append_printf(string, " %s",
1186 g_quark_to_string(tfs->process->state->s));
1187 }
1188
1189 g_info("%s",string->str);
1190
a56a1ba4 1191 g_string_free(string, TRUE);
1192
1193 /* End of text dump */
80a52ff8 1194#endif //DONTSHOW
50439712 1195
f0d936c0 1196}
1197
e92eabaf 1198/* after_schedchange_hook
b9a010a2 1199 *
1200 * The draw after hook is called by the reading API to have a
1201 * particular event drawn on the screen.
1202 * @param hook_data ControlFlowData structure of the viewer.
1203 * @param call_data Event context.
1204 *
1205 * This function adds items to be drawn in a queue for each process.
1206 *
1207 */
e92eabaf 1208int after_schedchange_hook(void *hook_data, void *call_data)
f0d936c0 1209{
ca0f8a8e 1210 EventsRequest *events_request = (EventsRequest*)hook_data;
1211 ControlFlowData *control_flow_data = events_request->viewer_data;
50439712 1212
a56a1ba4 1213 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
50439712 1214
1215 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1aff52a2 1216 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
50439712 1217
b9a010a2 1218 LttEvent *e;
1219 e = tfc->e;
1220
1221 LttTime evtime = ltt_event_time(e);
1222 TimeWindow time_window =
1223 lttvwindow_get_time_window(control_flow_data->tab);
1224
1225 LttTime end_time = ltt_time_add(time_window.start_time,
1226 time_window.time_width);
1227
1228 if(ltt_time_compare(evtime, time_window.start_time) == -1
1229 || ltt_time_compare(evtime, end_time) == 1)
1230 return;
1231
1232 guint width = control_flow_data->drawing->width;
1233
1234 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0) {
1235
1236 g_debug("schedchange!");
1237
1238 {
1239 /* Add process to process list (if not present) */
1240 LttvProcessState *process_out, *process_in;
1241 LttTime birth;
1242 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
1243 HashedProcessData *hashed_process_data_in = NULL;
1244
1245 ProcessList *process_list =
1246 guicontrolflow_get_process_list(control_flow_data);
1247
1248 guint pid_in;
1249 {
1250 guint pid_out;
1251 LttField *f = ltt_event_field(e);
1252 LttField *element;
1253 element = ltt_field_member(f,0);
1254 pid_out = ltt_event_get_long_unsigned(e,element);
1255 element = ltt_field_member(f,1);
1256 pid_in = ltt_event_get_long_unsigned(e,element);
1257 g_debug("out : %u in : %u", pid_out, pid_in);
1258 }
1259
1260
1261 /* Find process pid_in in the list... */
1262 process_in = lttv_state_find_process(tfs, pid_in);
1263 /* It should exist, because we are after the state update. */
1264 g_assert(process_in != NULL);
1265
1266 birth = process_in->creation_time;
1267 const gchar *name = g_quark_to_string(process_in->name);
1268
1269 if(processlist_get_process_pixels(process_list,
1270 pid_in,
1271 &birth,
1272 tfc->t_context->index,
1273 &y_in,
1274 &height,
1275 &hashed_process_data_in) == 1)
1276 {
e92eabaf 1277 g_assert(pid_in == 0 || pid_in != process_in->ppid);
b9a010a2 1278 /* Process not present */
1279 processlist_add(process_list,
1280 pid_in,
e92eabaf 1281 process_in->ppid,
b9a010a2 1282 &birth,
1283 tfc->t_context->index,
1284 name,
1285 &pl_height,
1286 &hashed_process_data_in);
1287 processlist_get_process_pixels(process_list,
1288 pid_in,
1289 &birth,
1290 tfc->t_context->index,
1291 &y_in,
1292 &height,
1293 &hashed_process_data_in);
1294 drawing_insert_square( control_flow_data->drawing, y_in, height);
1295 }
1296
1297 convert_time_to_pixels(
1298 time_window.start_time,
1299 end_time,
1300 evtime,
1301 width,
1302 &hashed_process_data_in->x);
1303 }
1304 }
1305 return 0;
1306
1307
1308
1309#if 0
1310 EventsRequest *events_request = (EventsRequest*)hook_data;
1311 ControlFlowData *control_flow_data = events_request->viewer_data;
1312
1313 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1314
1315 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1316 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
1317
a56a1ba4 1318
50439712 1319 LttEvent *e;
1320 e = tfc->e;
1321
9444deae 1322 LttTime evtime = ltt_event_time(e);
ca0f8a8e 1323 TimeWindow time_window =
1324 lttvwindow_get_time_window(control_flow_data->tab);
9444deae 1325
ca0f8a8e 1326 LttTime end_time = ltt_time_add(time_window.start_time,
1327 time_window.time_width);
9444deae 1328 //if(time < time_beg || time > time_end) return;
ca0f8a8e 1329 if(ltt_time_compare(evtime, time_window.start_time) == -1
9444deae 1330 || ltt_time_compare(evtime, end_time) == 1)
1331 return;
1332
1333
a56a1ba4 1334 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
1335 {
2a2fa4f0 1336 g_debug("schedchange!");
a56a1ba4 1337
1338 /* Add process to process list (if not present) and get drawing "y" from
1339 * process position */
1340 guint pid_out, pid_in;
1341 LttvProcessState *process_out, *process_in;
1342 LttTime birth;
1343 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
1344
1345 ProcessList *process_list =
ca0f8a8e 1346 guicontrolflow_get_process_list(control_flow_data);
a56a1ba4 1347
1348
1349 LttField *f = ltt_event_field(e);
1350 LttField *element;
1351 element = ltt_field_member(f,0);
1352 pid_out = ltt_event_get_long_unsigned(e,element);
1353 element = ltt_field_member(f,1);
1354 pid_in = ltt_event_get_long_unsigned(e,element);
2a2fa4f0 1355 //g_debug("out : %u in : %u", pid_out, pid_in);
a56a1ba4 1356
1357
1358 /* Find process pid_out in the list... */
2a2fa4f0 1359 process_out = lttv_state_find_process(tfs, pid_out);
1aff52a2 1360 if(process_out == NULL) return 0;
2a2fa4f0 1361 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
a56a1ba4 1362
1363 birth = process_out->creation_time;
1364 gchar *name = strdup(g_quark_to_string(process_out->name));
14963be0 1365 HashedProcessData *hashed_process_data_out = NULL;
a56a1ba4 1366
1367 if(processlist_get_process_pixels(process_list,
1368 pid_out,
1369 &birth,
d0cd7f09 1370 tfc->t_context->index,
a56a1ba4 1371 &y_out,
1372 &height,
14963be0 1373 &hashed_process_data_out) == 1)
a56a1ba4 1374 {
51705146 1375 /* Process not present */
1376 processlist_add(process_list,
1377 pid_out,
1378 &birth,
1379 tfc->t_context->index,
1380 name,
1381 &pl_height,
1382 &hashed_process_data_out);
1383 processlist_get_process_pixels(process_list,
1384 pid_out,
1385 &birth,
1386 tfc->t_context->index,
1387 &y_out,
1388 &height,
1389 &hashed_process_data_out);
1390 drawing_insert_square( control_flow_data->drawing, y_out, height);
a56a1ba4 1391 }
1392
1393 g_free(name);
1394
1395 /* Find process pid_in in the list... */
2a2fa4f0 1396 process_in = lttv_state_find_process(tfs, pid_in);
1aff52a2 1397 if(process_in == NULL) return 0;
2a2fa4f0 1398 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
a56a1ba4 1399
1400 birth = process_in->creation_time;
1401 name = strdup(g_quark_to_string(process_in->name));
14963be0 1402 HashedProcessData *hashed_process_data_in = NULL;
a56a1ba4 1403
1404 if(processlist_get_process_pixels(process_list,
1405 pid_in,
1406 &birth,
d0cd7f09 1407 tfc->t_context->index,
a56a1ba4 1408 &y_in,
1409 &height,
14963be0 1410 &hashed_process_data_in) == 1)
a56a1ba4 1411 {
1412 /* Process not present */
1413 processlist_add(process_list,
1414 pid_in,
1415 &birth,
d0cd7f09 1416 tfc->t_context->index,
a56a1ba4 1417 name,
1418 &pl_height,
14963be0 1419 &hashed_process_data_in);
a56a1ba4 1420 processlist_get_process_pixels(process_list,
1421 pid_in,
1422 &birth,
d0cd7f09 1423 tfc->t_context->index,
a56a1ba4 1424 &y_in,
1425 &height,
14963be0 1426 &hashed_process_data_in);
a56a1ba4 1427
ca0f8a8e 1428 drawing_insert_square( control_flow_data->drawing, y_in, height);
a56a1ba4 1429 }
1430 g_free(name);
1431
1432
1433 /* Find pixels corresponding to time of the event. If the time does
1434 * not fit in the window, show a warning, not supposed to happend. */
1435 //guint x = 0;
501d5405 1436 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
a56a1ba4 1437
1438 //LttTime time = ltt_event_time(e);
1439
224446ce 1440 //LttTime window_end = ltt_time_add(time_window->time_width,
1441 // time_window->start_time);
a56a1ba4 1442
1443
1444 //convert_time_to_pixels(
224446ce 1445 // time_window->start_time,
a56a1ba4 1446 // window_end,
1447 // time,
1448 // width,
1449 // &x);
1450
1451 //assert(x <= width);
1452
1453 /* draw what represents the event for outgoing process. */
1454
14963be0 1455 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
68997a22 1456 //draw_context_out->current->modify_over->x = x;
1457 draw_context_out->current->modify_over->y = y_out;
319e9d81 1458 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
501d5405 1459 draw_context_out->drawable = control_flow_data->drawing->pixmap;
1460 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
1461 GtkWidget *widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1462 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
d0cd7f09 1463
a56a1ba4 1464 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
501d5405 1465 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1466
1467 /*if(process_out->state->s == LTTV_STATE_RUN)
1468 {
1469 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1470 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1471 PropertiesBG prop_bg;
1472 prop_bg.color = g_new(GdkColor,1);
1473
1474 prop_bg.color->red = 0xffff;
1475 prop_bg.color->green = 0xffff;
1476 prop_bg.color->blue = 0xffff;
1477
1478 draw_bg((void*)&prop_bg, (void*)draw_context_out);
1479 g_free(prop_bg.color);
1480 gdk_gc_unref(draw_context_out->gc);
1481 }*/
1482
1483 draw_context_out->gc = widget->style->black_gc;
1484
a56a1ba4 1485 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
2df6f2bd 1486 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1487 PropertiesText prop_text_out;
1488 prop_text_out.foreground = &colorfg_out;
1489 prop_text_out.background = &colorbg_out;
cfe526b1 1490 prop_text_out.size = 6;
a56a1ba4 1491 prop_text_out.position = OVER;
1492
cfe526b1 1493 /* color of text : status of the process */
1494 if(process_out->state->s == LTTV_STATE_UNNAMED)
1495 {
1496 prop_text_out.foreground->red = 0xffff;
1497 prop_text_out.foreground->green = 0xffff;
1498 prop_text_out.foreground->blue = 0xffff;
1499 }
1500 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1501 {
1502 prop_text_out.foreground->red = 0x0fff;
d52cfc84 1503 prop_text_out.foreground->green = 0xffff;
1504 prop_text_out.foreground->blue = 0xfff0;
cfe526b1 1505 }
1506 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1507 {
2df6f2bd 1508 prop_text_out.foreground->red = 0xffff;
1509 prop_text_out.foreground->green = 0xffff;
cfe526b1 1510 prop_text_out.foreground->blue = 0x0000;
1511 }
0828099d 1512 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1513 {
1514 prop_text_out.foreground->red = 0xffff;
1515 prop_text_out.foreground->green = 0x0000;
1516 prop_text_out.foreground->blue = 0xffff;
1517 }
1518 else if(process_out->state->s == LTTV_STATE_WAIT)
1519 {
1520 prop_text_out.foreground->red = 0xffff;
1521 prop_text_out.foreground->green = 0x0000;
1522 prop_text_out.foreground->blue = 0x0000;
1523 }
1524 else if(process_out->state->s == LTTV_STATE_RUN)
1525 {
1526 prop_text_out.foreground->red = 0x0000;
1527 prop_text_out.foreground->green = 0xffff;
1528 prop_text_out.foreground->blue = 0x0000;
1529 }
1530 else
1531 {
1532 prop_text_out.foreground->red = 0xffff;
1533 prop_text_out.foreground->green = 0xffff;
1534 prop_text_out.foreground->blue = 0xffff;
1535 }
1536
a56a1ba4 1537 /* Print status of the process : U, WF, WC, E, W, R */
1538 if(process_out->state->s == LTTV_STATE_UNNAMED)
68997a22 1539 prop_text_out.text = "U";
a56a1ba4 1540 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
68997a22 1541 prop_text_out.text = "WF";
a56a1ba4 1542 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
68997a22 1543 prop_text_out.text = "WC";
0828099d 1544 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
68997a22 1545 prop_text_out.text = "E";
a56a1ba4 1546 else if(process_out->state->s == LTTV_STATE_WAIT)
68997a22 1547 prop_text_out.text = "W";
a56a1ba4 1548 else if(process_out->state->s == LTTV_STATE_RUN)
68997a22 1549 prop_text_out.text = "R";
a56a1ba4 1550 else
68997a22 1551 prop_text_out.text = "U";
a56a1ba4 1552
1553 draw_text((void*)&prop_text_out, (void*)draw_context_out);
d0cd7f09 1554
1555 //gdk_gc_unref(draw_context_out->gc);
319e9d81 1556
68997a22 1557 draw_context_out->current->middle->y = y_out+height/2;
d0cd7f09 1558 draw_context_out->current->over->y = y_out;
1559 draw_context_out->current->under->y = y_out+height;
68997a22 1560 draw_context_out->current->status = process_out->state->s;
a56a1ba4 1561
68997a22 1562 /* for pid_out : remove previous, Prev = current, new current (default) */
1563 g_free(draw_context_out->previous->modify_under);
1564 g_free(draw_context_out->previous->modify_middle);
1565 g_free(draw_context_out->previous->modify_over);
1566 g_free(draw_context_out->previous->under);
1567 g_free(draw_context_out->previous->middle);
1568 g_free(draw_context_out->previous->over);
1569 g_free(draw_context_out->previous);
1570
1571 draw_context_out->previous = draw_context_out->current;
a56a1ba4 1572
68997a22 1573 draw_context_out->current = g_new(DrawInfo,1);
1574 draw_context_out->current->over = g_new(ItemInfo,1);
1575 draw_context_out->current->over->x = -1;
1576 draw_context_out->current->over->y = -1;
1577 draw_context_out->current->middle = g_new(ItemInfo,1);
1578 draw_context_out->current->middle->x = -1;
1579 draw_context_out->current->middle->y = -1;
1580 draw_context_out->current->under = g_new(ItemInfo,1);
1581 draw_context_out->current->under->x = -1;
1582 draw_context_out->current->under->y = -1;
1583 draw_context_out->current->modify_over = g_new(ItemInfo,1);
1584 draw_context_out->current->modify_over->x = -1;
1585 draw_context_out->current->modify_over->y = -1;
1586 draw_context_out->current->modify_middle = g_new(ItemInfo,1);
1587 draw_context_out->current->modify_middle->x = -1;
1588 draw_context_out->current->modify_middle->y = -1;
1589 draw_context_out->current->modify_under = g_new(ItemInfo,1);
1590 draw_context_out->current->modify_under->x = -1;
1591 draw_context_out->current->modify_under->y = -1;
1592 draw_context_out->current->status = LTTV_STATE_UNNAMED;
a56a1ba4 1593
1594 /* Finally, update the drawing context of the pid_in. */
1595
14963be0 1596 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
68997a22 1597 //draw_context_in->current->modify_over->x = x;
1598 draw_context_in->current->modify_over->y = y_in;
319e9d81 1599 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
501d5405 1600 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1601 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1602 widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1603 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
a56a1ba4 1604
1605 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
501d5405 1606 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1607
1608 /*if(process_in->state->s == LTTV_STATE_RUN)
1609 {
1610 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1611 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1612 PropertiesBG prop_bg;
1613 prop_bg.color = g_new(GdkColor,1);
1614
1615 prop_bg.color->red = 0xffff;
1616 prop_bg.color->green = 0xffff;
1617 prop_bg.color->blue = 0xffff;
1618
1619 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1620 g_free(prop_bg.color);
1621 gdk_gc_unref(draw_context_in->gc);
1622 }*/
1623
1624 draw_context_in->gc = widget->style->black_gc;
1625
a56a1ba4 1626 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
2df6f2bd 1627 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1628 PropertiesText prop_text_in;
1629 prop_text_in.foreground = &colorfg_in;
1630 prop_text_in.background = &colorbg_in;
cfe526b1 1631 prop_text_in.size = 6;
a56a1ba4 1632 prop_text_in.position = OVER;
1633
cfe526b1 1634 /* foreground of text : status of the process */
1635 if(process_in->state->s == LTTV_STATE_UNNAMED)
1636 {
1637 prop_text_in.foreground->red = 0xffff;
1638 prop_text_in.foreground->green = 0xffff;
1639 prop_text_in.foreground->blue = 0xffff;
1640 }
1641 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1642 {
1643 prop_text_in.foreground->red = 0x0fff;
d52cfc84 1644 prop_text_in.foreground->green = 0xffff;
1645 prop_text_in.foreground->blue = 0xfff0;
cfe526b1 1646 }
1647 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1648 {
2df6f2bd 1649 prop_text_in.foreground->red = 0xffff;
1650 prop_text_in.foreground->green = 0xffff;
cfe526b1 1651 prop_text_in.foreground->blue = 0x0000;
1652 }
0828099d 1653 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1654 {
1655 prop_text_in.foreground->red = 0xffff;
1656 prop_text_in.foreground->green = 0x0000;
1657 prop_text_in.foreground->blue = 0xffff;
1658 }
1659 else if(process_in->state->s == LTTV_STATE_WAIT)
1660 {
1661 prop_text_in.foreground->red = 0xffff;
1662 prop_text_in.foreground->green = 0x0000;
1663 prop_text_in.foreground->blue = 0x0000;
1664 }
1665 else if(process_in->state->s == LTTV_STATE_RUN)
1666 {
1667 prop_text_in.foreground->red = 0x0000;
1668 prop_text_in.foreground->green = 0xffff;
1669 prop_text_in.foreground->blue = 0x0000;
1670 }
1671 else
1672 {
1673 prop_text_in.foreground->red = 0xffff;
1674 prop_text_in.foreground->green = 0xffff;
1675 prop_text_in.foreground->blue = 0xffff;
1676 }
1677
1678
a56a1ba4 1679 /* Print status of the process : U, WF, WC, E, W, R */
1680 if(process_in->state->s == LTTV_STATE_UNNAMED)
68997a22 1681 prop_text_in.text = "U";
a56a1ba4 1682 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
68997a22 1683 prop_text_in.text = "WF";
a56a1ba4 1684 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
68997a22 1685 prop_text_in.text = "WC";
0828099d 1686 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
68997a22 1687 prop_text_in.text = "E";
a56a1ba4 1688 else if(process_in->state->s == LTTV_STATE_WAIT)
68997a22 1689 prop_text_in.text = "W";
a56a1ba4 1690 else if(process_in->state->s == LTTV_STATE_RUN)
68997a22 1691 prop_text_in.text = "R";
a56a1ba4 1692 else
68997a22 1693 prop_text_in.text = "U";
a56a1ba4 1694
1695 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1696
d0cd7f09 1697
319e9d81 1698 if(process_in->state->s == LTTV_STATE_RUN)
1699 {
1700 gchar tmp[255];
1701 prop_text_in.foreground = &colorfg_in;
1702 prop_text_in.background = &colorbg_in;
1703 prop_text_in.foreground->red = 0xffff;
1704 prop_text_in.foreground->green = 0xffff;
1705 prop_text_in.foreground->blue = 0xffff;
1706 prop_text_in.size = 6;
1707 prop_text_in.position = UNDER;
1708
1709 prop_text_in.text = g_new(gchar, 260);
1710 strcpy(prop_text_in.text, "CPU ");
1711 snprintf(tmp, 255, "%u", tfc->index);
1712 strcat(prop_text_in.text, tmp);
1713
1714 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1715 g_free(prop_text_in.text);
1716 }
1717
1718
68997a22 1719 draw_context_in->current->middle->y = y_in+height/2;
d0cd7f09 1720 draw_context_in->current->over->y = y_in;
1721 draw_context_in->current->under->y = y_in+height;
68997a22 1722 draw_context_in->current->status = process_in->state->s;
1723
1724 /* for pid_in : remove previous, Prev = current, new current (default) */
1725 g_free(draw_context_in->previous->modify_under);
1726 g_free(draw_context_in->previous->modify_middle);
1727 g_free(draw_context_in->previous->modify_over);
1728 g_free(draw_context_in->previous->under);
1729 g_free(draw_context_in->previous->middle);
1730 g_free(draw_context_in->previous->over);
1731 g_free(draw_context_in->previous);
1732
1733 draw_context_in->previous = draw_context_in->current;
a56a1ba4 1734
68997a22 1735 draw_context_in->current = g_new(DrawInfo,1);
1736 draw_context_in->current->over = g_new(ItemInfo,1);
1737 draw_context_in->current->over->x = -1;
1738 draw_context_in->current->over->y = -1;
1739 draw_context_in->current->middle = g_new(ItemInfo,1);
1740 draw_context_in->current->middle->x = -1;
1741 draw_context_in->current->middle->y = -1;
1742 draw_context_in->current->under = g_new(ItemInfo,1);
1743 draw_context_in->current->under->x = -1;
1744 draw_context_in->current->under->y = -1;
1745 draw_context_in->current->modify_over = g_new(ItemInfo,1);
1746 draw_context_in->current->modify_over->x = -1;
1747 draw_context_in->current->modify_over->y = -1;
1748 draw_context_in->current->modify_middle = g_new(ItemInfo,1);
1749 draw_context_in->current->modify_middle->x = -1;
1750 draw_context_in->current->modify_middle->y = -1;
1751 draw_context_in->current->modify_under = g_new(ItemInfo,1);
1752 draw_context_in->current->modify_under->x = -1;
1753 draw_context_in->current->modify_under->y = -1;
1754 draw_context_in->current->status = LTTV_STATE_UNNAMED;
a56a1ba4 1755
1756 }
1757
1758 return 0;
b9a010a2 1759#endif //0
f0d936c0 1760}
f7afe191 1761
e92eabaf 1762/* after_fork_hook
1763 *
1764 * Create the processlist entry for the child process. Put the last
1765 * position in x at the current time value.
1766 *
1767 * @param hook_data ControlFlowData structure of the viewer.
1768 * @param call_data Event context.
1769 *
1770 * This function adds items to be drawn in a queue for each process.
1771 *
1772 */
1773int after_fork_hook(void *hook_data, void *call_data)
1774{
1775 EventsRequest *events_request = (EventsRequest*)hook_data;
1776 ControlFlowData *control_flow_data = events_request->viewer_data;
1777
1778 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1779
1780 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1781 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
1782
1783 LttEvent *e;
1784 e = tfc->e;
1785
1786 LttTime evtime = ltt_event_time(e);
1787 TimeWindow time_window =
1788 lttvwindow_get_time_window(control_flow_data->tab);
1789
1790 LttTime end_time = ltt_time_add(time_window.start_time,
1791 time_window.time_width);
1792
1793 if(ltt_time_compare(evtime, time_window.start_time) == -1
1794 || ltt_time_compare(evtime, end_time) == 1)
1795 return;
f7afe191 1796
e92eabaf 1797 guint width = control_flow_data->drawing->width;
1798
1799 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"process") == 0) {
1800
1801 guint sub_id;
1802 guint child_pid;
1803 {
1804 LttField *f = ltt_event_field(e);
1805 LttField *element;
1806 element = ltt_field_member(f,0);
1807 sub_id = ltt_event_get_long_unsigned(e,element);
1808 element = ltt_field_member(f,1);
1809 child_pid = ltt_event_get_long_unsigned(e,element);
1810 }
1811
1812 if(sub_id == 2) { /* fork */
1813
1814 /* Add process to process list (if not present) */
1815 LttvProcessState *process_child;
1816 LttTime birth;
1817 guint y_child = 0, height = 0, pl_height = 0;
1818 HashedProcessData *hashed_process_data_child = NULL;
1819
1820 ProcessList *process_list =
1821 guicontrolflow_get_process_list(control_flow_data);
1822
1823
1824 /* Find child in the list... */
1825 process_child = lttv_state_find_process(tfs, child_pid);
1826 /* It should exist, because we are after the state update. */
1827 g_assert(process_child != NULL);
1828
1829 birth = process_child->creation_time;
1830 const gchar *name = g_quark_to_string(process_child->name);
1831
1832 if(processlist_get_process_pixels(process_list,
1833 child_pid,
1834 &birth,
1835 tfc->t_context->index,
1836 &y_child,
1837 &height,
1838 &hashed_process_data_child) == 1)
1839 {
1840 g_assert(child_pid == 0 || child_pid != process_child->ppid);
1841 /* Process not present */
1842 processlist_add(process_list,
1843 child_pid,
1844 process_child->ppid,
1845 &birth,
1846 tfc->t_context->index,
1847 name,
1848 &pl_height,
1849 &hashed_process_data_child);
1850 processlist_get_process_pixels(process_list,
1851 child_pid,
1852 &birth,
1853 tfc->t_context->index,
1854 &y_child,
1855 &height,
1856 &hashed_process_data_child);
1857 drawing_insert_square( control_flow_data->drawing, y_child, height);
1858 }
1859
1860 convert_time_to_pixels(
1861 time_window.start_time,
1862 end_time,
1863 evtime,
1864 width,
1865 &hashed_process_data_child->x);
1866 }
1867 }
1868 return 0;
1869
1870}
f7afe191 1871
1872
1b238973 1873gint update_time_window_hook(void *hook_data, void *call_data)
f7afe191 1874{
a56a1ba4 1875 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
a43d67ba 1876 Drawing_t *drawing = control_flow_data->drawing;
1877
224446ce 1878 const TimeWindowNotifyData *time_window_nofify_data =
1879 ((const TimeWindowNotifyData *)call_data);
1880
14963be0 1881 TimeWindow *old_time_window =
224446ce 1882 time_window_nofify_data->old_time_window;
1883 TimeWindow *new_time_window =
1884 time_window_nofify_data->new_time_window;
a56a1ba4 1885
3cb8b205 1886 /* Update the ruler */
1887 drawing_update_ruler(control_flow_data->drawing,
1888 new_time_window);
1889
1890
a56a1ba4 1891 /* Two cases : zoom in/out or scrolling */
1892
1893 /* In order to make sure we can reuse the old drawing, the scale must
1894 * be the same and the new time interval being partly located in the
1895 * currently shown time interval. (reuse is only for scrolling)
1896 */
1897
1898 g_info("Old time window HOOK : %u, %u to %u, %u",
14963be0 1899 old_time_window->start_time.tv_sec,
1900 old_time_window->start_time.tv_nsec,
1901 old_time_window->time_width.tv_sec,
1902 old_time_window->time_width.tv_nsec);
a56a1ba4 1903
1904 g_info("New time window HOOK : %u, %u to %u, %u",
14963be0 1905 new_time_window->start_time.tv_sec,
1906 new_time_window->start_time.tv_nsec,
1907 new_time_window->time_width.tv_sec,
1908 new_time_window->time_width.tv_nsec);
a56a1ba4 1909
14963be0 1910 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
1911 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
a56a1ba4 1912 {
1913 /* Same scale (scrolling) */
1914 g_info("scrolling");
14963be0 1915 LttTime *ns = &new_time_window->start_time;
1916 LttTime *os = &old_time_window->start_time;
1917 LttTime old_end = ltt_time_add(old_time_window->start_time,
1918 old_time_window->time_width);
1919 LttTime new_end = ltt_time_add(new_time_window->start_time,
1920 new_time_window->time_width);
a56a1ba4 1921 //if(ns<os+w<ns+w)
1922 //if(ns<os+w && os+w<ns+w)
1923 //if(ns<old_end && os<ns)
1924 if(ltt_time_compare(*ns, old_end) == -1
1925 && ltt_time_compare(*os, *ns) == -1)
1926 {
1927 g_info("scrolling near right");
1928 /* Scroll right, keep right part of the screen */
1929 guint x = 0;
51705146 1930 guint width = control_flow_data->drawing->width;
a56a1ba4 1931 convert_time_to_pixels(
1932 *os,
1933 old_end,
1934 *ns,
1935 width,
1936 &x);
1937
1938 /* Copy old data to new location */
501d5405 1939 gdk_draw_drawable (control_flow_data->drawing->pixmap,
cfe526b1 1940 control_flow_data->drawing->drawing_area->style->black_gc,
501d5405 1941 control_flow_data->drawing->pixmap,
a56a1ba4 1942 x, 0,
1943 0, 0,
6395d57c 1944 control_flow_data->drawing->width-x+SAFETY, -1);
1945
1946 if(drawing->damage_begin == drawing->damage_end)
1947 drawing->damage_begin = control_flow_data->drawing->width-x;
1948 else
1949 drawing->damage_begin = 0;
1950
1951 drawing->damage_end = control_flow_data->drawing->width;
1952
a56a1ba4 1953 /* Clear the data request background, but not SAFETY */
501d5405 1954 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
6395d57c 1955 //control_flow_data->drawing->drawing_area->style->black_gc,
cfe526b1 1956 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 1957 TRUE,
6395d57c 1958 drawing->damage_begin+SAFETY, 0,
1959 drawing->damage_end - drawing->damage_begin, // do not overlap
51705146 1960 control_flow_data->drawing->height);
a43d67ba 1961
51705146 1962 gtk_widget_queue_draw_area (drawing->drawing_area,
a43d67ba 1963 0,0,
6395d57c 1964 control_flow_data->drawing->width,
a43d67ba 1965 control_flow_data->drawing->height);
1966
a56a1ba4 1967 /* Get new data for the rest. */
501d5405 1968 drawing_data_request(control_flow_data->drawing,
1969 &control_flow_data->drawing->pixmap,
6395d57c 1970 drawing->damage_begin, 0,
1971 drawing->damage_end - drawing->damage_begin,
501d5405 1972 control_flow_data->drawing->height);
a56a1ba4 1973 } else {
1974 //if(ns<os<ns+w)
1975 //if(ns<os && os<ns+w)
1976 //if(ns<os && os<new_end)
1977 if(ltt_time_compare(*ns,*os) == -1
1978 && ltt_time_compare(*os,new_end) == -1)
1979 {
1980 g_info("scrolling near left");
1981 /* Scroll left, keep left part of the screen */
1982 guint x = 0;
51705146 1983 guint width = control_flow_data->drawing->width;
a56a1ba4 1984 convert_time_to_pixels(
1985 *ns,
1986 new_end,
1987 *os,
1988 width,
1989 &x);
6395d57c 1990
1991
a56a1ba4 1992 /* Copy old data to new location */
501d5405 1993 gdk_draw_drawable (control_flow_data->drawing->pixmap,
cfe526b1 1994 control_flow_data->drawing->drawing_area->style->black_gc,
501d5405 1995 control_flow_data->drawing->pixmap,
a56a1ba4 1996 0, 0,
1997 x, 0,
1998 -1, -1);
1999
6395d57c 2000 if(drawing->damage_begin == drawing->damage_end)
2001 drawing->damage_end = x;
2002 else
2003 drawing->damage_end =
51705146 2004 control_flow_data->drawing->width;
6395d57c 2005
2006 drawing->damage_begin = 0;
2007
501d5405 2008 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
cfe526b1 2009 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 2010 TRUE,
6395d57c 2011 drawing->damage_begin, 0,
2012 drawing->damage_end - drawing->damage_begin, // do not overlap
51705146 2013 control_flow_data->drawing->height);
a43d67ba 2014
6395d57c 2015 gtk_widget_queue_draw_area (drawing->drawing_area,
2016 0,0,
2017 control_flow_data->drawing->width,
a43d67ba 2018 control_flow_data->drawing->height);
2019
6395d57c 2020
a56a1ba4 2021 /* Get new data for the rest. */
501d5405 2022 drawing_data_request(control_flow_data->drawing,
2023 &control_flow_data->drawing->pixmap,
6395d57c 2024 drawing->damage_begin, 0,
2025 drawing->damage_end - drawing->damage_begin,
501d5405 2026 control_flow_data->drawing->height);
a56a1ba4 2027
a56a1ba4 2028 } else {
a43d67ba 2029 if(ltt_time_compare(*ns,*os) == 0)
2030 {
2031 g_info("not scrolling");
2032 } else {
2033 g_info("scrolling far");
2034 /* Cannot reuse any part of the screen : far jump */
2035
2036
2037 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
2038 control_flow_data->drawing->drawing_area->style->black_gc,
2039 TRUE,
a56a1ba4 2040 0, 0,
a43d67ba 2041 control_flow_data->drawing->width+SAFETY, // do not overlap
51705146 2042 control_flow_data->drawing->height);
a43d67ba 2043
2044 gtk_widget_queue_draw_area (drawing->drawing_area,
2045 0,0,
2046 control_flow_data->drawing->width,
2047 control_flow_data->drawing->height);
2048
6395d57c 2049 drawing->damage_begin = 0;
2050 drawing->damage_end = control_flow_data->drawing->width;
2051
a43d67ba 2052 drawing_data_request(control_flow_data->drawing,
2053 &control_flow_data->drawing->pixmap,
2054 0, 0,
2055 control_flow_data->drawing->width,
2056 control_flow_data->drawing->height);
2057
2058 }
a56a1ba4 2059 }
2060 }
2061 } else {
2062 /* Different scale (zoom) */
2063 g_info("zoom");
2064
501d5405 2065 gdk_draw_rectangle (control_flow_data->drawing->pixmap,
cfe526b1 2066 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 2067 TRUE,
2068 0, 0,
501d5405 2069 control_flow_data->drawing->width+SAFETY, // do not overlap
51705146 2070 control_flow_data->drawing->height);
a56a1ba4 2071
a43d67ba 2072 gtk_widget_queue_draw_area (drawing->drawing_area,
2073 0,0,
2074 control_flow_data->drawing->width,
2075 control_flow_data->drawing->height);
a56a1ba4 2076
6395d57c 2077 drawing->damage_begin = 0;
2078 drawing->damage_end = control_flow_data->drawing->width;
2079
501d5405 2080 drawing_data_request(control_flow_data->drawing,
2081 &control_flow_data->drawing->pixmap,
a56a1ba4 2082 0, 0,
501d5405 2083 control_flow_data->drawing->width,
2084 control_flow_data->drawing->height);
a56a1ba4 2085 }
2086
3cb8b205 2087
2088
a56a1ba4 2089 return 0;
f7afe191 2090}
2091
6395d57c 2092gint traceset_notify(void *hook_data, void *call_data)
2093{
2094 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
2095 Drawing_t *drawing = control_flow_data->drawing;
2096 GtkWidget *widget = drawing->drawing_area;
2097
6395d57c 2098
b9a010a2 2099 drawing_clear(control_flow_data->drawing);
2100 processlist_clear(control_flow_data->process_list);
d9267eec 2101 redraw_notify(control_flow_data, NULL);
6395d57c 2102
d9267eec 2103 request_background_data(control_flow_data);
2104#if 0
2105 drawing->damage_begin = 0;
2106 drawing->damage_end = drawing->width;
6395d57c 2107 if(drawing->damage_begin < drawing->damage_end)
2108 {
2109 drawing_data_request(drawing,
2110 &drawing->pixmap,
2111 drawing->damage_begin,
2112 0,
2113 drawing->damage_end-drawing->damage_begin,
51705146 2114 drawing->height);
6395d57c 2115 }
2116
2117 gtk_widget_queue_draw_area(drawing->drawing_area,
2118 0,0,
2119 drawing->width,
2120 drawing->height);
d9267eec 2121#endif //0
6395d57c 2122
2123 return FALSE;
2124}
2125
ca0f8a8e 2126gint redraw_notify(void *hook_data, void *call_data)
2127{
2128 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
2129 Drawing_t *drawing = control_flow_data->drawing;
2130 GtkWidget *widget = drawing->drawing_area;
2131
2132 drawing->damage_begin = 0;
51705146 2133 drawing->damage_end = drawing->width;
ca0f8a8e 2134
2135
2136 // Clear the image
2137 gdk_draw_rectangle (drawing->pixmap,
2138 widget->style->black_gc,
2139 TRUE,
2140 0, 0,
51705146 2141 drawing->width+SAFETY,
2142 drawing->height);
ca0f8a8e 2143
2144
2145 if(drawing->damage_begin < drawing->damage_end)
2146 {
2147 drawing_data_request(drawing,
2148 &drawing->pixmap,
2149 drawing->damage_begin,
2150 0,
2151 drawing->damage_end-drawing->damage_begin,
51705146 2152 drawing->height);
ca0f8a8e 2153 }
2154
2155 gtk_widget_queue_draw_area(drawing->drawing_area,
2156 0,0,
2157 drawing->width,
2158 drawing->height);
2159
2160 return FALSE;
2161
2162}
2163
2164
2165gint continue_notify(void *hook_data, void *call_data)
a43d67ba 2166{
2167 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
ca0f8a8e 2168 Drawing_t *drawing = control_flow_data->drawing;
2169 GtkWidget *widget = drawing->drawing_area;
a43d67ba 2170
6395d57c 2171 //g_assert(widget->allocation.width == drawing->damage_end);
ca0f8a8e 2172
2173 if(drawing->damage_begin < drawing->damage_end)
2174 {
2175 drawing_data_request(drawing,
2176 &drawing->pixmap,
2177 drawing->damage_begin,
2178 0,
2179 drawing->damage_end-drawing->damage_begin,
51705146 2180 drawing->height);
ca0f8a8e 2181 }
2182
2183 return FALSE;
2184}
2185
2186
1b238973 2187gint update_current_time_hook(void *hook_data, void *call_data)
f7afe191 2188{
14963be0 2189 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
a43d67ba 2190 Drawing_t *drawing = control_flow_data->drawing;
a56a1ba4 2191
224446ce 2192 LttTime current_time = *((LttTime*)call_data);
a56a1ba4 2193
ca0f8a8e 2194 TimeWindow time_window =
2195 lttvwindow_get_time_window(control_flow_data->tab);
a56a1ba4 2196
ca0f8a8e 2197 LttTime time_begin = time_window.start_time;
2198 LttTime width = time_window.time_width;
a56a1ba4 2199 LttTime half_width = ltt_time_div(width,2.0);
2200 LttTime time_end = ltt_time_add(time_begin, width);
2201
2202 LttvTracesetContext * tsc =
ca0f8a8e 2203 lttvwindow_get_traceset_context(control_flow_data->tab);
a56a1ba4 2204
ca0f8a8e 2205 LttTime trace_start = tsc->time_span.start_time;
2206 LttTime trace_end = tsc->time_span.end_time;
a56a1ba4 2207
224446ce 2208 g_info("New current time HOOK : %u, %u", current_time.tv_sec,
2209 current_time.tv_nsec);
a56a1ba4 2210
2211
2212
2213 /* If current time is inside time interval, just move the highlight
2214 * bar */
2215
2216 /* Else, we have to change the time interval. We have to tell it
2217 * to the main window. */
2218 /* The time interval change will take care of placing the current
2219 * time at the center of the visible area, or nearest possible if we are
2220 * at one end of the trace. */
2221
2222
224446ce 2223 if(ltt_time_compare(current_time, time_begin) == -1)
a56a1ba4 2224 {
224446ce 2225 TimeWindow new_time_window;
2226
2227 if(ltt_time_compare(current_time,
a56a1ba4 2228 ltt_time_add(trace_start,half_width)) == -1)
2229 time_begin = trace_start;
2230 else
224446ce 2231 time_begin = ltt_time_sub(current_time,half_width);
a56a1ba4 2232
224446ce 2233 new_time_window.start_time = time_begin;
2234 new_time_window.time_width = width;
a56a1ba4 2235
e800cf84 2236 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
a56a1ba4 2237 }
224446ce 2238 else if(ltt_time_compare(current_time, time_end) == 1)
a56a1ba4 2239 {
224446ce 2240 TimeWindow new_time_window;
2241
2242 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) == 1)
a56a1ba4 2243 time_begin = ltt_time_sub(trace_end,width);
2244 else
224446ce 2245 time_begin = ltt_time_sub(current_time,half_width);
a56a1ba4 2246
224446ce 2247 new_time_window.start_time = time_begin;
2248 new_time_window.time_width = width;
a56a1ba4 2249
e800cf84 2250 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
a56a1ba4 2251
2252 }
a43d67ba 2253 //gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2254 gtk_widget_queue_draw_area(drawing->drawing_area,
2255 0,0,
2256 drawing->width,
2257 drawing->height);
a56a1ba4 2258
2259 return 0;
f7afe191 2260}
2261
8b90e648 2262typedef struct _ClosureData {
ca0f8a8e 2263 EventsRequest *events_request;
d0cd7f09 2264 LttvTracesetState *tss;
b9a010a2 2265 LttTime end_time;
8b90e648 2266} ClosureData;
a56a1ba4 2267
8b90e648 2268
e800cf84 2269void draw_closure(gpointer key, gpointer value, gpointer user_data)
2270{
a56a1ba4 2271 ProcessInfo *process_info = (ProcessInfo*)key;
2272 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
2273 ClosureData *closure_data = (ClosureData*)user_data;
2274
e800cf84 2275 EventsRequest *events_request = closure_data->events_request;
2276 ControlFlowData *control_flow_data = events_request->viewer_data;
2277 Drawing_t *drawing = control_flow_data->drawing;
a56a1ba4 2278
e800cf84 2279 LttvTracesetState *tss = closure_data->tss;
2280 LttvTracesetContext *tsc = (LttvTracesetContext*)closure_data->tss;
a56a1ba4 2281
e800cf84 2282 LttTime evtime = closure_data->end_time;
2283 TimeWindow time_window =
2284 lttvwindow_get_time_window(control_flow_data->tab);
ca0f8a8e 2285
e800cf84 2286 LttTime end_time = ltt_time_add(time_window.start_time,
2287 time_window.time_width);
ca0f8a8e 2288
e800cf84 2289 if(ltt_time_compare(evtime, time_window.start_time) == -1
2290 || ltt_time_compare(evtime, end_time) == 1)
2291 return;
ca0f8a8e 2292
e800cf84 2293 guint width = drawing->width;
d0cd7f09 2294
e800cf84 2295 {
2296 /* For the process */
2297 /* First, check if the current process is in the state computation
2298 * process list. If it is there, that means we must add it right now and
2299 * draw items from the beginning of the read for it. If it is not
2300 * present, it's a new process and it was not present : it will
2301 * be added after the state update. */
2302 g_assert(lttv_traceset_number(tsc->ts) > 0);
d0cd7f09 2303
e025a729 2304 /* tracefiles[0] is ok here, because we draw for every PID, and
2305 * assume CPU 0 for PID 0 //FIXME */
2306 LttvTracefileState *tfs =
2307 (LttvTracefileState*)tsc->traces[process_info->trace_num]->tracefiles[0];
a56a1ba4 2308
e800cf84 2309 LttvProcessState *process;
e025a729 2310 process = lttv_state_find_process(tfs,
2311 process_info->pid);
a56a1ba4 2312
e800cf84 2313 if(process != NULL) {
2314
2315 /* Only draw for processes that are currently in the trace states */
ad2e83ba 2316
e800cf84 2317 guint y = 0, height = 0, pl_height = 0;
2318 ProcessList *process_list =
2319 guicontrolflow_get_process_list(control_flow_data);
2320 LttTime birth = process_info->birth;
2321
2322 /* Should be alike when background info is ready */
2323 if(control_flow_data->background_info_waiting==0)
2324 g_assert(ltt_time_compare(process->creation_time,
2325 process_info->birth) == 0);
2326 const gchar *name = g_quark_to_string(process->name);
2327
2328 /* process HAS to be present */
2329 g_assert(processlist_get_process_pixels(process_list,
2330 process_info->pid,
2331 &birth,
2332 process_info->trace_num,
2333 &y,
2334 &height,
2335 &hashed_process_data) != 1);
2336
2337 /* Now, the process is in the state hash and our own process hash.
2338 * We definitely can draw the items related to the ending state.
2339 */
2340
2341 /* Check if the x position is unset. In can have been left unset by
2342 * a draw closure from a after chunk hook. This should never happen,
2343 * because it must be set by before chunk hook to the damage_begin
2344 * value.
2345 */
2346 g_assert(hashed_process_data->x != -1);
2347 {
2348 guint x;
2349 DrawContext draw_context;
a56a1ba4 2350
e800cf84 2351 convert_time_to_pixels(
2352 time_window.start_time,
2353 end_time,
2354 evtime,
2355 width,
2356 &x);
8b90e648 2357
e800cf84 2358 /* Now create the drawing context that will be used to draw
2359 * items related to the last state. */
2360 draw_context.drawable = drawing->pixmap;
2361 draw_context.gc = drawing->gc;
2362 draw_context.pango_layout = drawing->pango_layout;
2363 draw_context.drawinfo.start.x = hashed_process_data->x;
2364 draw_context.drawinfo.end.x = x;
2365
2366 draw_context.drawinfo.y.over = y;
2367 draw_context.drawinfo.y.middle = y+(height/4);
2368 draw_context.drawinfo.y.under = y+(height/2)+2;
2369
2370 draw_context.drawinfo.start.offset.over = 0;
2371 draw_context.drawinfo.start.offset.middle = 0;
2372 draw_context.drawinfo.start.offset.under = 0;
2373 draw_context.drawinfo.end.offset.over = 0;
2374 draw_context.drawinfo.end.offset.middle = 0;
2375 draw_context.drawinfo.end.offset.under = 0;
2376
2377 {
2378 /* Draw the line */
e92eabaf 2379 PropertiesLine prop_line = prepare_status_line(process);
e800cf84 2380 draw_line((void*)&prop_line, (void*)&draw_context);
2381
2382 }
2383
2384 /* special case LTTV_STATE_WAIT : CPU is unknown. */
2385
2386 /* become the last x position */
2387 hashed_process_data->x = x;
2388 }
2389 }
2390 }
2391 return;
8b90e648 2392}
2393
b9a010a2 2394int before_chunk(void *hook_data, void *call_data)
2395{
2396 EventsRequest *events_request = (EventsRequest*)hook_data;
2397 LttvTracesetState *tss = LTTV_TRACESET_STATE(call_data);
2398
2399 drawing_chunk_begin(events_request, tss);
2400
2401 return 0;
2402}
2403
2404int before_request(void *hook_data, void *call_data)
ca0f8a8e 2405{
2406 EventsRequest *events_request = (EventsRequest*)hook_data;
2407 LttvTracesetState *tss = LTTV_TRACESET_STATE(call_data);
2408
2409 drawing_data_request_begin(events_request, tss);
2410
2411 return 0;
2412}
2413
2414
8b90e648 2415/*
b9a010a2 2416 * after request is necessary in addition of after chunk in order to draw
2417 * lines until the end of the screen. after chunk just draws lines until
2418 * the last event.
2419 *
8b90e648 2420 * for each process
a56a1ba4 2421 * draw closing line
b9a010a2 2422 * expose
8b90e648 2423 */
b9a010a2 2424int after_request(void *hook_data, void *call_data)
8b90e648 2425{
ca0f8a8e 2426 EventsRequest *events_request = (EventsRequest*)hook_data;
2427 ControlFlowData *control_flow_data = events_request->viewer_data;
2428 LttvTracesetState *tss = LTTV_TRACESET_STATE(call_data);
b9a010a2 2429 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(call_data);
a56a1ba4 2430
2431 ProcessList *process_list =
ca0f8a8e 2432 guicontrolflow_get_process_list(control_flow_data);
b9a010a2 2433 LttTime end_time = events_request->end_time;
2434
2435 ClosureData closure_data;
2436 closure_data.events_request = (EventsRequest*)hook_data;
2437 closure_data.tss = tss;
2438 closure_data.end_time = end_time;
2439
2440 /* Draw last items */
2441 g_hash_table_foreach(process_list->process_hash, draw_closure,
2442 (void*)&closure_data);
2443
2444 /* Request expose */
2445 drawing_request_expose(events_request, tss, end_time);
2446 return 0;
2447}
2448
2449/*
2450 * for each process
2451 * draw closing line
e800cf84 2452 * expose
b9a010a2 2453 */
2454int after_chunk(void *hook_data, void *call_data)
2455{
2456 EventsRequest *events_request = (EventsRequest*)hook_data;
2457 ControlFlowData *control_flow_data = events_request->viewer_data;
2458 LttvTracesetState *tss = LTTV_TRACESET_STATE(call_data);
2459 LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(call_data);
2460 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
2461 LttTime end_time;
2462
2463 ProcessList *process_list =
2464 guicontrolflow_get_process_list(control_flow_data);
2465
e800cf84 2466 if(tfc != NULL)
2467 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
0c5dbe3b 2468 else /* end of traceset, or position now out of request : end */
2469 end_time = events_request->end_time;
2470
a56a1ba4 2471 ClosureData closure_data;
ca0f8a8e 2472 closure_data.events_request = (EventsRequest*)hook_data;
2473 closure_data.tss = tss;
b9a010a2 2474 closure_data.end_time = end_time;
a56a1ba4 2475
b9a010a2 2476 /* Draw last items */
14963be0 2477 g_hash_table_foreach(process_list->process_hash, draw_closure,
a56a1ba4 2478 (void*)&closure_data);
a43d67ba 2479
ca0f8a8e 2480 /* Request expose */
b9a010a2 2481 drawing_request_expose(events_request, tss, end_time);
ca0f8a8e 2482
2483 return 0;
8b90e648 2484}
2485
This page took 0.149983 seconds and 4 git commands to generate.