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