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