filter starts to work
[lttv.git] / ltt / branches / poly / lttv / modules / gui / detailedevents / events.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers and XangXiu Yang
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
20 //*! \defgroup GuiEvents libGuiEvents: The GUI Events display plugin */
21 /*\@{*/
22
23 /*! \file GuiEvents.c
24 * \brief Graphical plugin for showing events.
25 *
26 * This plugin lists all the events contained in the current time interval
27 * in a list.
28 *
29 * This plugin adds a Events Viewer functionnality to Linux TraceToolkit
30 * GUI when this plugin is loaded. The init and destroy functions add the
31 * viewer's insertion menu item and toolbar icon by calling viewer.h's
32 * API functions. Then, when a viewer's object is created, the constructor
33 * creates ans register through API functions what is needed to interact
34 * with the lttvwindow.
35 *
36 * Authors : Mathieu Desnoyers and XangXiu Yang, June to December 2003
37 * Inspired from original LTT, made by Karim Yaghmour
38 */
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
43
44 #include <math.h>
45
46 #include <glib.h>
47 #include <gtk/gtk.h>
48 #include <gdk/gdk.h>
49 #include <string.h>
50
51 #include <ltt/ltt.h>
52 #include <ltt/event.h>
53 #include <ltt/type.h>
54 #include <ltt/trace.h>
55 #include <ltt/facility.h>
56 #include <lttv/module.h>
57 #include <lttv/hook.h>
58 #include <lttv/tracecontext.h>
59 #include <lttv/state.h>
60 #include <lttv/filter.h>
61 #include <lttv/print.h>
62 #include <lttvwindow/lttvwindow.h>
63
64 #include "hGuiEventsInsert.xpm"
65
66 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
67
68 #ifndef g_debug
69 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
70 #endif
71
72 #define abs(a) (((a)<0)?(-a):(a))
73
74
75 /** Array containing instanced objects. Used when module is unloaded */
76 static GSList *g_event_viewer_data_list = NULL ;
77
78 typedef enum _ScrollDirection{
79 SCROLL_STEP_UP,
80 SCROLL_STEP_DOWN,
81 SCROLL_PAGE_UP,
82 SCROLL_PAGE_DOWN,
83 SCROLL_JUMP,
84 SCROLL_NONE
85 } ScrollDirection;
86
87 typedef struct _EventViewerData {
88
89 Tab * tab;
90 LttvHooks * event_hooks;
91
92 /* previous value is used to determine if it is a page up/down or
93 * step up/down, in which case we move of a certain amount of events (one or
94 * the number of events shown on the screen) instead of changing begin time.
95 */
96 double previous_value;
97
98 //scroll window containing Tree View
99 GtkWidget * scroll_win;
100
101 /* Model containing list data */
102 GtkListStore *store_m;
103
104 GPtrArray *pos; /* Array of LttvTracesetContextPosition * */
105
106 GtkWidget *top_widget;
107 GtkWidget *hbox_v;
108 /* Widget to display the data in a columned list */
109 GtkWidget *tree_v;
110 GtkAdjustment *vtree_adjust_c ;
111 GtkWidget *button; /* a button of the header, used to get the header_height */
112 gint header_height;
113
114 /* Vertical scrollbar and its adjustment */
115 GtkWidget *vscroll_vc;
116 GtkAdjustment *vadjust_c;
117
118 /* Selection handler */
119 GtkTreeSelection *select_c;
120
121 gint num_visible_events;
122
123 LttvTracesetContextPosition *currently_selected_position;
124
125 LttvTracesetContextPosition *first_event; /* Time of the first event shown */
126 LttvTracesetContextPosition *last_event; /* Time of the first event shown */
127
128 LttvFilter *main_win_filter;
129
130 } EventViewerData ;
131
132 /** hook functions for update time interval, current time ... */
133 gboolean update_current_time(void * hook_data, void * call_data);
134 gboolean update_current_position(void * hook_data, void * call_data);
135 //gboolean show_event_detail(void * hook_data, void * call_data);
136 gboolean traceset_changed(void * hook_data, void * call_data);
137 gboolean filter_changed(void * hook_data, void * call_data);
138
139 //! Event Viewer's constructor hook
140 GtkWidget *h_gui_events(Tab *tab);
141 //! Event Viewer's constructor
142 EventViewerData *gui_events(Tab *tab);
143 //! Event Viewer's destructor
144 void gui_events_destructor(EventViewerData *event_viewer_data);
145 void gui_events_free(EventViewerData *event_viewer_data);
146
147 static gboolean
148 header_size_allocate(GtkWidget *widget,
149 GtkAllocation *allocation,
150 gpointer user_data);
151
152 void tree_v_set_cursor(EventViewerData *event_viewer_data);
153 void tree_v_get_cursor(EventViewerData *event_viewer_data);
154
155 /* Prototype for selection handler callback */
156 static void tree_selection_changed_cb (GtkTreeSelection *selection,
157 gpointer data);
158 static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data);
159 static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc,
160 gpointer data);
161 static void tree_v_size_request_cb (GtkWidget *widget,
162 GtkRequisition *requisition, gpointer data);
163 static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data);
164 static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1,
165 gint arg2, gpointer data);
166
167
168 static void get_events(double time, EventViewerData *event_viewer_data);
169
170 int event_hook(void *hook_data, void *call_data);
171
172 /* Enumeration of the columns */
173 enum
174 {
175 TRACE_NAME_COLUMN,
176 TRACEFILE_NAME_COLUMN,
177 CPUID_COLUMN,
178 EVENT_COLUMN,
179 FACILITY_COLUMN,
180 TIME_S_COLUMN,
181 TIME_NS_COLUMN,
182 PID_COLUMN,
183 EVENT_DESCR_COLUMN,
184 POSITION_COLUMN,
185 N_COLUMNS
186 };
187
188 /**
189 * Event Viewer's constructor hook
190 *
191 * This constructor is given as a parameter to the menuitem and toolbar button
192 * registration. It creates the list.
193 * @param parent_window A pointer to the parent window.
194 * @return The widget created.
195 */
196 GtkWidget *
197 h_gui_events(Tab * tab)
198 {
199 EventViewerData* event_viewer_data = gui_events(tab) ;
200 if(event_viewer_data)
201 return event_viewer_data->top_widget;
202 else return NULL;
203
204 }
205
206 /**
207 * Event Viewer's constructor
208 *
209 * This constructor is used to create EventViewerData data structure.
210 * @return The Event viewer data created.
211 */
212 EventViewerData *
213 gui_events(Tab *tab)
214 {
215 LttTime end;
216 GtkTreeViewColumn *column;
217 GtkCellRenderer *renderer;
218 EventViewerData* event_viewer_data = g_new(EventViewerData,1) ;
219
220 event_viewer_data->tab = tab;
221
222 LttvTracesetContext * tsc =
223 lttvwindow_get_traceset_context(event_viewer_data->tab);
224
225
226 event_viewer_data->event_hooks = lttv_hooks_new();
227 lttv_hooks_add(event_viewer_data->event_hooks,
228 event_hook,
229 event_viewer_data,
230 LTTV_PRIO_DEFAULT);
231
232 lttvwindow_register_current_time_notify(tab,
233 update_current_time,event_viewer_data);
234 lttvwindow_register_current_position_notify(tab,
235 update_current_position,event_viewer_data);
236 lttvwindow_register_traceset_notify(tab,
237 traceset_changed,event_viewer_data);
238 lttvwindow_register_filter_notify(tab,
239 filter_changed, event_viewer_data);
240
241 event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
242 gtk_widget_show (event_viewer_data->scroll_win);
243 gtk_scrolled_window_set_policy(
244 GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win),
245 GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
246
247 event_viewer_data->currently_selected_position =
248 lttv_traceset_context_position_new(tsc);
249 event_viewer_data->first_event =
250 lttv_traceset_context_position_new(tsc);
251 event_viewer_data->last_event =
252 lttv_traceset_context_position_new(tsc);
253
254 event_viewer_data->main_win_filter = NULL;
255
256 /* Create a model for storing the data list */
257 event_viewer_data->store_m = gtk_list_store_new (
258 N_COLUMNS, /* Total number of columns */
259 G_TYPE_STRING, /* Trace name */
260 G_TYPE_STRING, /* Tracefile name */
261 G_TYPE_UINT, /* CPUID */
262 G_TYPE_STRING, /* Event */
263 G_TYPE_STRING, /* Facility */
264 G_TYPE_UINT, /* Time s */
265 G_TYPE_UINT, /* Time ns */
266 G_TYPE_INT, /* PID */
267 G_TYPE_STRING, /* Event's description */
268 G_TYPE_POINTER);/* Position (not shown) */
269
270 event_viewer_data->pos = g_ptr_array_sized_new(10);
271
272 /* Create the viewer widget for the columned list */
273 event_viewer_data->tree_v =
274 gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m));
275
276 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-allocate",
277 G_CALLBACK (tree_v_size_allocate_cb),
278 event_viewer_data);
279 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-request",
280 G_CALLBACK (tree_v_size_request_cb),
281 event_viewer_data);
282
283 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "cursor-changed",
284 G_CALLBACK (tree_v_cursor_changed_cb),
285 event_viewer_data);
286
287 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "move-cursor",
288 G_CALLBACK (tree_v_move_cursor_cb),
289 event_viewer_data);
290
291 // Use on each column!
292 //gtk_tree_view_column_set_sizing(event_viewer_data->tree_v,
293 //GTK_TREE_VIEW_COLUMN_FIXED);
294
295 /* The view now holds a reference. We can get rid of our own
296 * reference */
297 g_object_unref (G_OBJECT (event_viewer_data->store_m));
298
299
300 /* Create a column, associating the "text" attribute of the
301 * cell_renderer to the first column of the model */
302 /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */
303 renderer = gtk_cell_renderer_text_new ();
304 column = gtk_tree_view_column_new_with_attributes ("Trace",
305 renderer,
306 "text", TRACE_NAME_COLUMN,
307 NULL);
308 gtk_tree_view_column_set_alignment (column, 0.0);
309 gtk_tree_view_column_set_fixed_width (column, 120);
310 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
311 column);
312
313 event_viewer_data->button = column->button;
314
315 g_signal_connect (G_OBJECT(event_viewer_data->button),
316 "size-allocate",
317 G_CALLBACK(header_size_allocate),
318 (gpointer)event_viewer_data);
319
320
321
322 renderer = gtk_cell_renderer_text_new ();
323 column = gtk_tree_view_column_new_with_attributes ("Tracefile",
324 renderer,
325 "text", TRACEFILE_NAME_COLUMN,
326 NULL);
327 gtk_tree_view_column_set_alignment (column, 0.0);
328 gtk_tree_view_column_set_fixed_width (column, 120);
329 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
330 column);
331
332
333 renderer = gtk_cell_renderer_text_new ();
334 column = gtk_tree_view_column_new_with_attributes ("CPUID",
335 renderer,
336 "text", CPUID_COLUMN,
337 NULL);
338 gtk_tree_view_column_set_alignment (column, 0.0);
339 gtk_tree_view_column_set_fixed_width (column, 45);
340 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
341 column);
342
343 renderer = gtk_cell_renderer_text_new ();
344 column = gtk_tree_view_column_new_with_attributes ("Event",
345 renderer,
346 "text", EVENT_COLUMN,
347 NULL);
348 gtk_tree_view_column_set_alignment (column, 0.0);
349 gtk_tree_view_column_set_fixed_width (column, 120);
350 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
351 column);
352
353 renderer = gtk_cell_renderer_text_new ();
354 column = gtk_tree_view_column_new_with_attributes ("Facility",
355 renderer,
356 "text", FACILITY_COLUMN,
357 NULL);
358 gtk_tree_view_column_set_alignment (column, 0.0);
359 gtk_tree_view_column_set_fixed_width (column, 120);
360 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
361 column);
362
363 renderer = gtk_cell_renderer_text_new ();
364 column = gtk_tree_view_column_new_with_attributes ("Time (s)",
365 renderer,
366 "text", TIME_S_COLUMN,
367 NULL);
368 gtk_tree_view_column_set_alignment (column, 1.0);
369 gtk_tree_view_column_set_fixed_width (column, 120);
370 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
371 column);
372
373 renderer = gtk_cell_renderer_text_new ();
374 column = gtk_tree_view_column_new_with_attributes ("Time (ns)",
375 renderer,
376 "text", TIME_NS_COLUMN,
377 NULL);
378 gtk_tree_view_column_set_alignment (column, 1.0);
379 gtk_tree_view_column_set_fixed_width (column, 120);
380 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
381 column);
382
383
384 renderer = gtk_cell_renderer_text_new ();
385 column = gtk_tree_view_column_new_with_attributes ("PID",
386 renderer,
387 "text", PID_COLUMN,
388 NULL);
389 gtk_tree_view_column_set_alignment (column, 1.0);
390 gtk_tree_view_column_set_fixed_width (column, 45);
391 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
392 column);
393
394 renderer = gtk_cell_renderer_text_new ();
395 column = gtk_tree_view_column_new_with_attributes ("Event Description",
396 renderer,
397 "text", EVENT_DESCR_COLUMN,
398 NULL);
399 gtk_tree_view_column_set_alignment (column, 0.0);
400 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
401 column);
402
403
404 /* Setup the selection handler */
405 event_viewer_data->select_c =
406 gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v));
407 gtk_tree_selection_set_mode (event_viewer_data->select_c,
408 GTK_SELECTION_SINGLE);
409 g_signal_connect (G_OBJECT (event_viewer_data->select_c), "changed",
410 G_CALLBACK (tree_selection_changed_cb),
411 event_viewer_data);
412
413 gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win),
414 event_viewer_data->tree_v);
415
416 event_viewer_data->hbox_v = gtk_hbox_new(0, 0);
417 event_viewer_data->top_widget = event_viewer_data->hbox_v;
418 gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
419 event_viewer_data->scroll_win, TRUE, TRUE, 0);
420
421 /* Create vertical scrollbar and pack it */
422 event_viewer_data->vscroll_vc = gtk_vscrollbar_new(NULL);
423 gtk_range_set_update_policy (GTK_RANGE(event_viewer_data->vscroll_vc),
424 GTK_UPDATE_CONTINUOUS);
425 // Changed by MD : more user friendly :)
426 //GTK_UPDATE_DISCONTINUOUS);
427 gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
428 event_viewer_data->vscroll_vc, FALSE, TRUE, 0);
429
430 /* Get the vertical scrollbar's adjustment */
431 event_viewer_data->vadjust_c =
432 gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc));
433 event_viewer_data->vtree_adjust_c = gtk_tree_view_get_vadjustment(
434 GTK_TREE_VIEW (event_viewer_data->tree_v));
435
436 g_signal_connect (G_OBJECT (event_viewer_data->vadjust_c), "value-changed",
437 G_CALLBACK (v_scroll_cb),
438 event_viewer_data);
439 /* Set the upper bound to the last event number */
440 event_viewer_data->previous_value = 0;
441 event_viewer_data->vadjust_c->lower = 0.0;
442 //event_viewer_data->vadjust_c->upper = event_viewer_data->number_of_events;
443 event_viewer_data->vadjust_c->value = 0.0;
444 event_viewer_data->vadjust_c->step_increment = 1.0;
445 event_viewer_data->vadjust_c->page_increment = 2.0;
446 // event_viewer_data->vtree_adjust_c->upper;
447 event_viewer_data->vadjust_c->page_size = 2.0;
448 // event_viewer_data->vtree_adjust_c->upper;
449 /* Raw event trace */
450 gtk_widget_show(event_viewer_data->hbox_v);
451 gtk_widget_show(event_viewer_data->tree_v);
452 gtk_widget_show(event_viewer_data->vscroll_vc);
453
454 /* Add the object's information to the module's array */
455 g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list,
456 event_viewer_data);
457
458 event_viewer_data->num_visible_events = 1;
459
460 //get the life span of the traceset and set the upper of the scroll bar
461
462 TimeInterval time_span = tsc->time_span;
463 end = ltt_time_sub(time_span.end_time, time_span.start_time);
464
465 event_viewer_data->vadjust_c->upper =
466 ltt_time_to_double(end);
467
468 /* Set the Selected Event */
469 // tree_v_set_cursor(event_viewer_data);
470
471 // event_viewer_data->current_time_updated = FALSE;
472 //
473 g_object_set_data_full(
474 G_OBJECT(event_viewer_data->hbox_v),
475 "event_viewer_data",
476 event_viewer_data,
477 (GDestroyNotify)gui_events_free);
478
479
480 return event_viewer_data;
481 }
482
483
484
485 static gboolean
486 header_size_allocate(GtkWidget *widget,
487 GtkAllocation *allocation,
488 gpointer user_data)
489 {
490 EventViewerData *event_viewer_data = (EventViewerData*)user_data;
491
492 event_viewer_data->header_height = allocation->height;
493
494 return 0;
495 }
496
497
498 void tree_v_set_cursor(EventViewerData *event_viewer_data)
499 {
500 GtkTreePath *path;
501
502 g_debug("set cursor cb");
503
504 #if 0
505 if(event_viewer_data->currently_selected_event != -1)
506 {
507 path = gtk_tree_path_new_from_indices(
508 event_viewer_data->currently_selected_event,
509 -1);
510
511 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
512 path, NULL, FALSE);
513 gtk_tree_path_free(path);
514 }
515 #endif //0
516 }
517
518 void tree_v_get_cursor(EventViewerData *event_viewer_data)
519 {
520 GtkTreePath *path;
521 gint *indices;
522
523 g_debug("get cursor cb");
524
525
526 #if 0
527 gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
528 &path, NULL);
529 indices = gtk_tree_path_get_indices(path);
530
531 if(indices != NULL)
532 event_viewer_data->currently_selected_event = indices[0];
533 else
534 event_viewer_data->currently_selected_event = -1;
535
536 gtk_tree_path_free(path);
537 #endif //0
538 }
539
540
541
542 void tree_v_move_cursor_cb (GtkWidget *widget,
543 GtkMovementStep arg1,
544 gint arg2,
545 gpointer data)
546 {
547 GtkTreePath *path; // = gtk_tree_path_new();
548 gint *indices;
549 gdouble value;
550 EventViewerData *event_viewer_data = (EventViewerData*)data;
551
552 g_debug("move cursor cb");
553 gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
554 &path, NULL);
555 if(path == NULL)
556 {
557 /* No prior cursor, put it at beginning of page
558 * and let the execution do */
559 path = gtk_tree_path_new_from_indices(0, -1);
560 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
561 path, NULL, FALSE);
562 }
563
564 indices = gtk_tree_path_get_indices(path);
565
566 value = gtk_adjustment_get_value(event_viewer_data->vadjust_c);
567
568 g_debug("tree view move cursor : arg1 is %u and arg2 is %d",
569 (guint)arg1, arg2);
570
571 #if 0
572 if(arg1 == GTK_MOVEMENT_DISPLAY_LINES)
573 {
574 /* Move one line */
575 if(arg2 == 1)
576 {
577 /* move one line down */
578 if(indices[0]) // Do we need an empty field here (before first)?
579 {
580 if(value + event_viewer_data->num_visible_events <=
581 event_viewer_data->number_of_events -1)
582 {
583 event_viewer_data->currently_selected_event += 1;
584 // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1);
585 //gtk_tree_path_free(path);
586 //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
587 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
588 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
589 }
590 }
591 } else {
592 /* Move one line up */
593 if(indices[0] == 0)
594 {
595 if(value - 1 >= 0 )
596 {
597 event_viewer_data->currently_selected_event -= 1;
598 // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1);
599 //gtk_tree_path_free(path);
600 //path = gtk_tree_path_new_from_indices(0, -1);
601 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
602 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
603 }
604 }
605 }
606 }
607
608 if(arg1 == GTK_MOVEMENT_PAGES)
609 {
610 /* Move one page */
611 if(arg2 == 1)
612 {
613 if(event_viewer_data->num_visible_events == 1)
614 value += 1 ;
615 /* move one page down */
616 if(value + event_viewer_data->num_visible_events-1 <=
617 event_viewer_data->number_of_events )
618 {
619 event_viewer_data->currently_selected_event +=
620 event_viewer_data->num_visible_events-1;
621 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
622 // value+(event_viewer_data->num_visible_events-1));
623 //gtk_tree_path_free(path);
624 //path = gtk_tree_path_new_from_indices(0, -1);
625 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
626 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
627 }
628 } else {
629 /* Move one page up */
630 if(event_viewer_data->num_visible_events == 1)
631 value -= 1 ;
632
633 if(indices[0] < event_viewer_data->num_visible_events - 2 )
634 {
635 if(value - (event_viewer_data->num_visible_events-1) >= 0)
636 {
637 event_viewer_data->currently_selected_event -=
638 event_viewer_data->num_visible_events-1;
639
640 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
641 // value-(event_viewer_data->num_visible_events-1));
642 //gtk_tree_path_free(path);
643 //path = gtk_tree_path_new_from_indices(0, -1);
644 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
645 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
646
647 } else {
648 /* Go to first Event */
649 event_viewer_data->currently_selected_event == 0 ;
650 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
651 // 0);
652 //gtk_tree_path_free(path);
653 //path = gtk_tree_path_new_from_indices(0, -1);
654 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
655 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
656
657 }
658 }
659 }
660 }
661
662 if(arg1 == GTK_MOVEMENT_BUFFER_ENDS)
663 {
664 /* Move to the ends of the buffer */
665 if(arg2 == 1)
666 {
667 /* move end of buffer */
668 event_viewer_data->currently_selected_event =
669 event_viewer_data->number_of_events-1 ;
670 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
671 // event_viewer_data->number_of_events -
672 // event_viewer_data->num_visible_events);
673 //gtk_tree_path_free(path);
674 //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
675 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
676 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
677 } else {
678 /* Move beginning of buffer */
679 event_viewer_data->currently_selected_event = 0 ;
680 // gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0);
681 //gtk_tree_path_free(path);
682 //path = gtk_tree_path_new_from_indices(0, -1);
683 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
684 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
685 }
686 }
687 #endif //0
688 gtk_tree_path_free(path);
689 }
690
691 void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data)
692 {
693 EventViewerData *event_viewer_data = (EventViewerData*) data;
694 Tab *tab = event_viewer_data->tab;
695 GtkTreeIter iter;
696 GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
697 GtkTreePath *path;
698 LttvTracesetContextPosition *pos;
699
700 g_debug("cursor changed cb");
701
702 #if 0
703 /* On cursor change, modify the currently selected event by calling
704 * the right API function */
705 tree_v_get_cursor(event_viewer_data);
706
707 gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
708 &path, NULL);
709 if(gtk_tree_model_get_iter(model,&iter,path)){
710 gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
711
712 lttvwindow_report_current_position(tab, pos);
713 }else{
714 g_warning("Can not get iter\n");
715 }
716 #endif //0
717 }
718
719
720 static void tree_selection_changed_cb (GtkTreeSelection *selection,
721 gpointer data)
722 {
723 g_debug("tree sel changed cb");
724 EventViewerData *event_viewer_data = (EventViewerData*) data;
725 #if 0
726 /* Set the cursor to currently selected event */
727 GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
728 GtkTreeIter iter;
729 LttvTracesetContextPosition *pos;
730 guint i;
731 GtkTreePath *tree_path;
732
733 for(i=0;i<event_viewer_data->num_visible_events;i++) {
734 tree_path = gtk_tree_path_new_from_indices(
735 i,
736 -1);
737 if(gtk_tree_model_get_iter(model,&iter,tree_path)){
738 gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
739
740 if(lttv_traceset_context_pos_pos_compare(pos,
741 event_viewer_data->currently_selected_position) == 0) {
742 /* Match! */
743 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
744 tree_path, NULL, FALSE);
745 break;
746 }
747
748 }else{
749 g_warning("Can not get iter\n");
750 }
751 gtk_tree_path_free(tree_path);
752 }
753 #endif //0
754 }
755
756
757
758 /* This callback may be recalled after a step up/down, but we don't want to lose
759 * the exact position : what we do is that we only set the value if it has
760 * changed : a step up/down that doesn't change the time value of the first
761 * event won't trigger a scrollbar change. */
762
763 void v_scroll_cb (GtkAdjustment *adjustment, gpointer data)
764 {
765 EventViewerData *event_viewer_data = (EventViewerData*)data;
766 LttvTracesetStats *tss =
767 lttvwindow_get_traceset_stats(event_viewer_data->tab);
768 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
769 g_debug("SCROLL begin");
770 g_debug("SCROLL values : %g , %g, %g",
771 adjustment->value, event_viewer_data->previous_value,
772 (adjustment->value - event_viewer_data->previous_value));
773
774 LttTime new_time_off = ltt_time_from_double(adjustment->value);
775 LttTime old_time_off = ltt_time_from_double(event_viewer_data->previous_value);
776 g_debug("SCROLL time values %lu.%lu, %lu.%lu", new_time_off.tv_sec,
777 new_time_off.tv_nsec, old_time_off.tv_sec, old_time_off.tv_nsec);
778 /* If same value : nothing to update */
779 if(ltt_time_compare(new_time_off, old_time_off) == 0)
780 return;
781
782 //LttTime old_time = event_viewer_data->first_event;
783
784 get_events(adjustment->value, event_viewer_data);
785 #if 0
786 LttTime time = ltt_time_sub(event_viewer_data->first_event,
787 tsc->time_span.start_time);
788 double value = ltt_time_to_double(time);
789 gtk_adjustment_set_value(event_viewer_data->vadjust_c, value);
790
791 if(event_viewer_data->currently_selected_event != -1) {
792
793 tree_path = gtk_tree_path_new_from_indices(
794 event_viewer_data->currently_selected_event,
795 -1);
796
797 // gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), tree_path,
798 // NULL, FALSE);
799 gtk_tree_path_free(tree_path);
800 }
801 #endif //0
802 g_debug("SCROLL end");
803 }
804
805 static __inline gint get_cell_height(GtkTreeView *TreeView)
806 {
807 gint height;
808 GtkTreeViewColumn *column = gtk_tree_view_get_column(TreeView, 0);
809
810 gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height);
811
812 return height;
813 }
814
815 void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data)
816 {
817 EventViewerData *event_viewer_data = (EventViewerData*)data;
818 gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
819 gint last_num_visible_events = event_viewer_data->num_visible_events;
820 gdouble exact_num_visible;
821
822 exact_num_visible = ( alloc->height -
823 event_viewer_data->header_height )
824 / (double)cell_height ;
825
826 event_viewer_data->num_visible_events = ceil(exact_num_visible) ;
827
828 /*
829 event_viewer_data->vadjust_c->page_increment =
830 floor(exact_num_visible);
831 event_viewer_data->vadjust_c->page_size =
832 floor(exact_num_visible);
833 */
834
835 g_debug("size allocate : last_num_visible_events : %d,\
836 num_visible_events : %d",
837 last_num_visible_events,
838 event_viewer_data->num_visible_events);
839 if(event_viewer_data->num_visible_events != last_num_visible_events)
840 {
841 get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
842 }
843
844
845 }
846
847 void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data)
848 {
849 gint h;
850 EventViewerData *event_viewer_data = (EventViewerData*)data;
851 gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
852
853 h = cell_height + event_viewer_data->header_height;
854 requisition->height = h;
855
856 }
857
858 #if 0
859 gboolean show_event_detail(void * hook_data, void * call_data)
860 {
861 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
862 LttvTracesetContext * tsc = lttvwindow_get_traceset_context(event_viewer_data->tab);
863
864 if(event_viewer_data->event_fields_queue_tmp->length == 0 &&
865 event_viewer_data->event_fields_queue->length == 0){
866 event_viewer_data->shown = FALSE;
867 return FALSE;
868 }
869
870 if(event_viewer_data->shown == FALSE){
871 event_viewer_data->shown = TRUE;
872 update_raw_data_array(event_viewer_data,
873 event_viewer_data->event_fields_queue_tmp->length);
874
875 get_data(event_viewer_data->vadjust_c->value,
876 event_viewer_data->num_visible_events,
877 event_viewer_data);
878
879 remove_context_hooks(event_viewer_data,tsc);
880 }
881
882 return FALSE;
883 }
884 #endif //0
885
886
887
888
889
890
891
892 static void get_events(double new_value, EventViewerData *event_viewer_data)
893 {
894 GtkTreePath *tree_path;
895 LttvTracesetStats *tss =
896 lttvwindow_get_traceset_stats(event_viewer_data->tab);
897 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
898 guint i;
899 gboolean seek_by_time;
900
901 double value = new_value - event_viewer_data->previous_value;
902
903 /* See where we have to scroll... */
904 ScrollDirection direction;
905 gint relative_position;
906
907 if(value < 0.0) {
908 if(value >= -1.0) direction = SCROLL_STEP_UP;
909 else {
910 if(value >= -2.0) direction = SCROLL_PAGE_UP;
911 else direction = SCROLL_JUMP;
912 }
913 } else if(value > 0.0) {
914 if(value <= 1.0) direction = SCROLL_STEP_DOWN;
915 else {
916 if(value <= 2.0) direction = SCROLL_PAGE_DOWN;
917 else direction = SCROLL_JUMP;
918 }
919 } else direction = SCROLL_NONE; /* 0.0 */
920
921
922 switch(direction) {
923 case SCROLL_STEP_UP:
924 g_debug("get_events : SCROLL_STEP_UP");
925 relative_position = -1;
926 seek_by_time = 0;
927 break;
928 case SCROLL_STEP_DOWN:
929 g_debug("get_events : SCROLL_STEP_DOWN");
930 relative_position = 1;
931 seek_by_time = 0;
932 break;
933 case SCROLL_PAGE_UP:
934 g_debug("get_events : SCROLL_PAGE_UP");
935 relative_position = -(event_viewer_data->num_visible_events);
936 seek_by_time = 0;
937 break;
938 case SCROLL_PAGE_DOWN:
939 g_debug("get_events : SCROLL_PAGE_DOWN");
940 relative_position = event_viewer_data->num_visible_events;
941 seek_by_time = 0;
942 break;
943 case SCROLL_JUMP:
944 g_debug("get_events : SCROLL_JUMP");
945 seek_by_time = 1;
946 break;
947 case SCROLL_NONE:
948 g_debug("get_events : SCROLL_NONE");
949 relative_position = 0;
950 seek_by_time = 0;
951 break;
952 }
953
954 LttTime time = ltt_time_from_double(new_value);
955 time = ltt_time_add(tsc->time_span.start_time, time);
956
957 if(!seek_by_time) {
958
959 LttvTracesetContextPosition *pos =
960 lttv_traceset_context_position_new(tsc);
961
962 /* Remember the beginning position */
963 if(event_viewer_data->pos->len > 0) {
964 LttvTracesetContextPosition *first_pos =
965 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
966 0);
967 lttv_traceset_context_position_copy(pos, first_pos);
968 g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0);
969 } else {
970 /* There is nothing in the list : simply seek to the time value. */
971 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
972 time);
973 lttv_process_traceset_middle(tsc, time, G_MAXUINT,
974 NULL);
975 }
976
977 /* Note that, as we mess with the tsc position, this function CANNOT be called
978 * from a hook inside the lttv_process_traceset_middle. */
979 /* As the lttvwindow API keeps a sync_position inside the tsc to go back at
980 * the right spot after being interrupted, it's ok to change the tsc position,
981 * as long as we do not touch the sync_position. */
982
983 /* Get the beginning position of the read (with seek backward or seek forward)
984 */
985 if(relative_position > 0) {
986 guint count;
987 count = lttv_process_traceset_seek_n_forward(tsc, relative_position,
988 event_viewer_data->main_win_filter);
989 } else if(relative_position < 0) {
990 guint count;
991
992 /* Get an idea of currently shown event dispersion */
993 LttTime first_event_time =
994 lttv_traceset_context_position_get_time(event_viewer_data->first_event);
995 LttTime last_event_time =
996 lttv_traceset_context_position_get_time(event_viewer_data->last_event);
997 LttTime time_diff = ltt_time_sub(last_event_time, first_event_time);
998 if(ltt_time_compare(time_diff, ltt_time_zero) == 0)
999 time_diff = seek_back_default_offset;
1000 count = lttv_process_traceset_seek_n_backward(tsc, abs(relative_position),
1001 time_diff,
1002 (seek_time_fct)lttv_state_traceset_seek_time_closest,
1003 event_viewer_data->main_win_filter);
1004 } /* else 0 : do nothing : we are already at the beginning position */
1005
1006 lttv_traceset_context_position_destroy(pos);
1007
1008 /* Save the first event position */
1009 lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
1010
1011 time = lttv_traceset_context_position_get_time(
1012 event_viewer_data->first_event);
1013 LttTime time_val = ltt_time_sub(time,
1014 tsc->time_span.start_time);
1015 event_viewer_data->previous_value = ltt_time_to_double(time_val);
1016
1017 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, time);
1018 lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT,
1019 event_viewer_data->first_event);
1020
1021 } else {
1022 /* Seek by time */
1023 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
1024 time);
1025 lttv_process_traceset_middle(tsc, time, G_MAXUINT,
1026 NULL);
1027 LttTime time_val = ltt_time_sub(time,
1028 tsc->time_span.start_time);
1029 event_viewer_data->previous_value = ltt_time_to_double(time_val);
1030 lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
1031 }
1032
1033 /* Clear the model (don't forget to free the TCS positions!) */
1034 gtk_list_store_clear(event_viewer_data->store_m);
1035 for(i=0;i<event_viewer_data->pos->len;i++) {
1036 LttvTracesetContextPosition *cur_pos =
1037 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
1038 i);
1039 lttv_traceset_context_position_destroy(cur_pos);
1040 }
1041 g_ptr_array_set_size(event_viewer_data->pos, 0);
1042
1043
1044 /* Mathieu :
1045 * I make the choice not to use the mainwindow lttvwindow API here : it will
1046 * be faster to read the events ourself from lttv_process_traceset_middle, as
1047 * we are already at the right read position. It would be costier to use the
1048 * seek time closest for nothing, as we only have few events to read.
1049 */
1050 /* FIXME : use seek time closest and middle to have a good state. */
1051
1052 lttv_process_traceset_begin(tsc,
1053 NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
1054
1055 lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
1056
1057 lttv_process_traceset_end(tsc,
1058 NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
1059
1060 /* Get the end position */
1061 if(event_viewer_data->pos->len > 0) {
1062 LttvTracesetContextPosition *cur_pos =
1063 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
1064 event_viewer_data->pos->len - 1);
1065 lttv_traceset_context_position_copy(event_viewer_data->last_event,
1066 cur_pos);
1067 } else
1068 lttv_traceset_context_position_save(tsc, event_viewer_data->last_event);
1069
1070 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
1071 event_viewer_data->previous_value);
1072
1073 //g_signal_emit_by_name(G_OBJECT (event_viewer_data->select_c),
1074 // "changed");
1075
1076
1077 return;
1078 }
1079
1080
1081
1082 int event_hook(void *hook_data, void *call_data)
1083 {
1084 EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
1085 LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
1086 LttEvent *e = ltt_tracefile_get_event(tfc->tf);
1087
1088 LttvFilter *filter = event_viewer_data->main_win_filter;
1089 if(filter != NULL && filter->head != NULL)
1090 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1091 tfc->t_context->t,tfc))
1092 return FALSE;
1093
1094 LttFacility *facility = ltt_event_facility(e);
1095 LttEventType *event_type = ltt_event_eventtype(e);
1096 LttField *field = ltt_event_field(e);
1097 LttTime time = ltt_event_time(e);
1098
1099 guint cpu = ltt_tracefile_num(tfc->tf);
1100 LttvTraceState *ts = (LttvTraceState*)tfc->t_context;
1101 LttvProcessState *process = ts->running_process[cpu];
1102
1103 GtkTreeIter iter;
1104
1105 GString *desc = g_string_new("");
1106
1107 LttvTracesetContextPosition *pos =
1108 lttv_traceset_context_position_new(tfc->t_context->ts_context);
1109
1110 lttv_traceset_context_position_save(tfc->t_context->ts_context, pos);
1111
1112 if(field)
1113 lttv_print_field(e, field, desc, TRUE);
1114
1115 g_info("field : %s", desc->str);
1116
1117 gtk_list_store_append (event_viewer_data->store_m, &iter);
1118 gtk_list_store_set (event_viewer_data->store_m, &iter,
1119 TRACE_NAME_COLUMN, g_quark_to_string(ltt_trace_name(tfc->t_context->t)),
1120 TRACEFILE_NAME_COLUMN, g_quark_to_string(ltt_tracefile_name(tfc->tf)),
1121 CPUID_COLUMN, cpu,
1122 FACILITY_COLUMN, g_quark_to_string(ltt_facility_name(facility)),
1123 EVENT_COLUMN, g_quark_to_string(ltt_eventtype_name(event_type)),
1124 TIME_S_COLUMN, time.tv_sec,
1125 TIME_NS_COLUMN, time.tv_nsec,
1126 PID_COLUMN, process->pid,
1127 EVENT_DESCR_COLUMN, desc->str,
1128 POSITION_COLUMN, pos,
1129 -1);
1130
1131 g_ptr_array_add(event_viewer_data->pos, pos);
1132
1133 g_string_free(desc, TRUE);
1134
1135 if(event_viewer_data->pos->len >= event_viewer_data->num_visible_events)
1136 return TRUE;
1137 else
1138 return FALSE;
1139 }
1140
1141
1142
1143
1144 gboolean update_current_time(void * hook_data, void * call_data)
1145 {
1146 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1147 const LttTime * current_time = (LttTime*)call_data;
1148 LttvTracesetContext * tsc =
1149 lttvwindow_get_traceset_context(event_viewer_data->tab);
1150
1151 /* If the currently selected event time != current time, set the first event
1152 * with this time as currently selected. */
1153 LttTime pos_time = lttv_traceset_context_position_get_time(
1154 event_viewer_data->currently_selected_position);
1155 if(ltt_time_compare(pos_time, *current_time) != 0) {
1156
1157 lttv_process_traceset_seek_time(tsc, *current_time);
1158 lttv_traceset_context_position_save(tsc,
1159 event_viewer_data->currently_selected_position);
1160 pos_time = lttv_traceset_context_position_get_time(
1161 event_viewer_data->currently_selected_position);
1162 }
1163
1164 LttTime time = ltt_time_sub(pos_time, tsc->time_span.start_time);
1165 double new_value = ltt_time_to_double(time);
1166
1167 /* Change the viewed area if does not match */
1168 if(lttv_traceset_context_pos_pos_compare(
1169 event_viewer_data->currently_selected_position,
1170 event_viewer_data->first_event) < 0
1171 ||
1172 lttv_traceset_context_pos_pos_compare(
1173 event_viewer_data->currently_selected_position,
1174 event_viewer_data->last_event) > 0)
1175 gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
1176
1177 return FALSE;
1178 }
1179
1180 gboolean update_current_position(void * hook_data, void * call_data)
1181 {
1182 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1183 const LttvTracesetContextPosition *current_pos =
1184 (LttvTracesetContextPosition*)call_data;
1185 LttvTracesetContext * tsc =
1186 lttvwindow_get_traceset_context(event_viewer_data->tab);
1187
1188 if(lttv_traceset_context_pos_pos_compare(
1189 event_viewer_data->currently_selected_position, current_pos) != 0) {
1190 lttv_traceset_context_position_copy(
1191 event_viewer_data->currently_selected_position, current_pos);
1192
1193
1194 /* Change the viewed area if does not match */
1195 if(lttv_traceset_context_pos_pos_compare(
1196 event_viewer_data->currently_selected_position,
1197 event_viewer_data->first_event) < 0
1198 ||
1199 lttv_traceset_context_pos_pos_compare(
1200 event_viewer_data->currently_selected_position,
1201 event_viewer_data->last_event) > 0) {
1202 LttTime time = lttv_traceset_context_position_get_time(current_pos);
1203 time = ltt_time_sub(time, tsc->time_span.start_time);
1204 double new_value = ltt_time_to_double(time);
1205 gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
1206 }
1207
1208 }
1209
1210
1211 return FALSE;
1212 }
1213
1214
1215
1216 gboolean traceset_changed(void * hook_data, void * call_data)
1217 {
1218 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1219 LttvTracesetContext * tsc =
1220 lttvwindow_get_traceset_context(event_viewer_data->tab);
1221 TimeInterval time_span = tsc->time_span;
1222
1223 LttTime end;
1224 gtk_list_store_clear(event_viewer_data->store_m);
1225 g_ptr_array_set_size(event_viewer_data->pos, 0);
1226
1227 end = ltt_time_sub(time_span.end_time, time_span.start_time);
1228 event_viewer_data->vadjust_c->upper = ltt_time_to_double(end);
1229 g_signal_emit_by_name(event_viewer_data->vadjust_c, "value-changed");
1230 // event_viewer_data->vadjust_c->value = 0;
1231
1232 return FALSE;
1233 }
1234
1235 gboolean filter_changed(void * hook_data, void * call_data)
1236 {
1237 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1238 LttvTracesetContext * tsc =
1239 lttvwindow_get_traceset_context(event_viewer_data->tab);
1240
1241 event_viewer_data->main_win_filter =
1242 (LttvFilter*)call_data;
1243 g_signal_emit_by_name(event_viewer_data->vadjust_c, "value-changed");
1244
1245 return FALSE;
1246 }
1247
1248
1249
1250
1251
1252 void gui_events_free(EventViewerData *event_viewer_data)
1253 {
1254 Tab *tab = event_viewer_data->tab;
1255 guint i;
1256
1257 if(event_viewer_data){
1258 lttv_hooks_remove(event_viewer_data->event_hooks,event_hook);
1259 lttv_hooks_destroy(event_viewer_data->event_hooks);
1260
1261 for(i=0;i<event_viewer_data->pos->len;i++) {
1262 LttvTracesetContextPosition *cur_pos =
1263 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
1264 i);
1265 lttv_traceset_context_position_destroy(cur_pos);
1266 }
1267 lttv_traceset_context_position_destroy(
1268 event_viewer_data->currently_selected_position);
1269 lttv_traceset_context_position_destroy(
1270 event_viewer_data->first_event);
1271 lttv_traceset_context_position_destroy(
1272 event_viewer_data->last_event);
1273 g_ptr_array_free(event_viewer_data->pos, TRUE);
1274
1275 lttvwindow_unregister_current_time_notify(tab,
1276 update_current_time, event_viewer_data);
1277 lttvwindow_unregister_current_position_notify(tab,
1278 update_current_position, event_viewer_data);
1279 //lttvwindow_unregister_show_notify(tab,
1280 // show_event_detail, event_viewer_data);
1281 lttvwindow_unregister_traceset_notify(tab,
1282 traceset_changed, event_viewer_data);
1283 lttvwindow_unregister_filter_notify(tab,
1284 filter_changed, event_viewer_data);
1285
1286 g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list,
1287 event_viewer_data);
1288 g_free(event_viewer_data);
1289 }
1290 }
1291
1292
1293
1294 void gui_events_destructor(EventViewerData *event_viewer_data)
1295 {
1296 /* May already been done by GTK window closing */
1297 if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){
1298 gtk_widget_destroy(event_viewer_data->hbox_v);
1299 }
1300 }
1301
1302
1303
1304 /**
1305 * plugin's init function
1306 *
1307 * This function initializes the Event Viewer functionnality through the
1308 * gtkTraceSet API.
1309 */
1310 static void init() {
1311
1312 lttvwindow_register_constructor("guievents",
1313 "/",
1314 "Insert Event Viewer",
1315 hGuiEventsInsert_xpm,
1316 "Insert Event Viewer",
1317 h_gui_events);
1318 }
1319
1320 void event_destroy_walk(gpointer data, gpointer user_data)
1321 {
1322 gui_events_destructor((EventViewerData*)data);
1323 }
1324
1325 /**
1326 * plugin's destroy function
1327 *
1328 * This function releases the memory reserved by the module and unregisters
1329 * everything that has been registered in the gtkTraceSet API.
1330 */
1331 static void destroy() {
1332
1333 g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL );
1334 g_slist_free(g_event_viewer_data_list);
1335
1336 lttvwindow_unregister_constructor(h_gui_events);
1337
1338 }
1339
1340
1341
1342
1343 LTTV_MODULE("guievents", "Detailed events view", \
1344 "Graphical module to display a detailed event list", \
1345 init, destroy, "lttvwindow", "print")
This page took 0.056352 seconds and 4 git commands to generate.