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