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