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