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