update stop for event list
[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 * 2005 Mathieu Desnoyers
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
17 * MA 02111-1307, USA.
18 */
19
20
21 //*! \defgroup GuiEvents libGuiEvents: The GUI Events display plugin */
22 /*\@{*/
23
24 /*! \file GuiEvents.c
25 * \brief Graphical plugin for showing events.
26 *
27 * This plugin lists all the events contained in the current time interval
28 * in a list.
29 *
30 * This plugin adds a Events Viewer functionnality to Linux TraceToolkit
31 * GUI when this plugin is loaded. The init and destroy functions add the
32 * viewer's insertion menu item and toolbar icon by calling viewer.h's
33 * API functions. Then, when a viewer's object is created, the constructor
34 * creates ans register through API functions what is needed to interact
35 * with the lttvwindow.
36 *
37 * Authors : Mathieu Desnoyers and XangXiu Yang, June to December 2003
38 * Inspired from original LTT, made by Karim Yaghmour
39 *
40 * Mostly rewritten by Mathieu Desnoyers, August 2005.
41 */
42
43 #ifdef HAVE_CONFIG_H
44 #include <config.h>
45 #endif
46
47 #include <math.h>
48
49 #include <glib.h>
50 #include <gtk/gtk.h>
51 #include <gdk/gdk.h>
52 #include <gdk/gdkx.h>
53 #include <string.h>
54
55 #include <ltt/ltt.h>
56 #include <ltt/event.h>
57 #include <ltt/type.h>
58 #include <ltt/trace.h>
59 #include <ltt/facility.h>
60 #include <lttv/module.h>
61 #include <lttv/hook.h>
62 #include <lttv/tracecontext.h>
63 #include <lttv/state.h>
64 #include <lttv/filter.h>
65 #include <lttv/print.h>
66 #include <lttvwindow/lttvwindow.h>
67 #include <lttvwindow/lttvwindowtraces.h>
68 #include <lttvwindow/lttv_plugin_tab.h>
69
70 #include "hGuiEventsInsert.xpm"
71
72 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
73
74 #ifndef g_debug
75 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
76 #endif
77
78 #define abs(a) (((a)<0)?(-a):(a))
79 #define max(a,b) ((a)>(b)?(a):(b))
80
81 /** Array containing instanced objects. Used when module is unloaded */
82 static GSList *g_event_viewer_data_list = NULL ;
83
84 typedef enum _ScrollDirection{
85 SCROLL_STEP_UP,
86 SCROLL_STEP_DOWN,
87 SCROLL_PAGE_UP,
88 SCROLL_PAGE_DOWN,
89 SCROLL_JUMP,
90 SCROLL_NONE
91 } ScrollDirection;
92
93 typedef struct _EventViewerData {
94
95 Tab * tab;
96 LttvPluginTab *ptab;
97 LttvHooks * event_hooks;
98
99 /* previous value is used to determine if it is a page up/down or
100 * step up/down, in which case we move of a certain amount of events (one or
101 * the number of events shown on the screen) instead of changing begin time.
102 */
103 double previous_value;
104
105 //scroll window containing Tree View
106 GtkWidget * scroll_win;
107
108 /* Model containing list data */
109 GtkListStore *store_m;
110
111 GPtrArray *pos; /* Array of LttvTracesetContextPosition * */
112
113 GtkWidget *top_widget;
114 GtkWidget *hbox_v;
115 /* Widget to display the data in a columned list */
116 GtkWidget *tree_v;
117 GtkAdjustment *vtree_adjust_c ;
118 GtkWidget *button; /* a button of the header, used to get the header_height */
119 gint header_height;
120
121 /* Vertical scrollbar and its adjustment */
122 GtkWidget *vscroll_vc;
123 GtkAdjustment *vadjust_c;
124
125 /* Selection handler */
126 GtkTreeSelection *select_c;
127
128 gint num_visible_events;
129
130 LttvTracesetContextPosition *currently_selected_position;
131 gboolean update_cursor; /* Speed optimisation : do not update cursor when
132 unnecessary */
133 gboolean report_position; /* do not report position when in current_time
134 update */
135
136 LttvTracesetContextPosition *first_event; /* Time of the first event shown */
137 LttvTracesetContextPosition *last_event; /* Time of the first event shown */
138
139 LttvTracesetContextPosition *current_time_get_first;
140
141 LttvFilter *main_win_filter;
142
143 gint background_info_waiting;
144
145 guint32 last_tree_update_time; /* To filter out repeat keys */
146
147 guint num_events; /* Number of events processed */
148
149 } EventViewerData ;
150
151 /** hook functions for update time interval, current time ... */
152 gboolean update_current_time(void * hook_data, void * call_data);
153 gboolean update_current_position(void * hook_data, void * call_data);
154 //gboolean show_event_detail(void * hook_data, void * call_data);
155 gboolean traceset_changed(void * hook_data, void * call_data);
156 gboolean filter_changed(void * hook_data, void * call_data);
157
158 static void request_background_data(EventViewerData *event_viewer_data);
159
160 //! Event Viewer's constructor hook
161 GtkWidget *h_gui_events(LttvPlugin *plugin);
162 //! Event Viewer's constructor
163 EventViewerData *gui_events(LttvPluginTab *ptab);
164 //! Event Viewer's destructor
165 void gui_events_destructor(EventViewerData *event_viewer_data);
166 void gui_events_free(EventViewerData *event_viewer_data);
167
168 static gboolean
169 header_size_allocate(GtkWidget *widget,
170 GtkAllocation *allocation,
171 gpointer user_data);
172
173 void tree_v_set_cursor(EventViewerData *event_viewer_data);
174 void tree_v_get_cursor(EventViewerData *event_viewer_data);
175
176 /* Prototype for selection handler callback */
177 static void tree_selection_changed_cb (GtkTreeSelection *selection,
178 gpointer data);
179 static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data);
180 static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc,
181 gpointer data);
182 static void tree_v_size_request_cb (GtkWidget *widget,
183 GtkRequisition *requisition, gpointer data);
184 static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data);
185 static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1,
186 gint arg2, gpointer data);
187 static gboolean tree_v_scroll_handler (GtkWidget *widget, GdkEventScroll *event, gpointer data);
188 static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
189 gpointer user_data);
190
191 static gint redraw_notify(void *hook_data, void *call_data);
192
193 static void get_events(double time, EventViewerData *event_viewer_data);
194
195 int event_hook(void *hook_data, void *call_data);
196
197 /* Enumeration of the columns */
198 enum
199 {
200 TRACE_NAME_COLUMN,
201 TRACEFILE_NAME_COLUMN,
202 CPUID_COLUMN,
203 EVENT_COLUMN,
204 FACILITY_COLUMN,
205 TIME_S_COLUMN,
206 TIME_NS_COLUMN,
207 PID_COLUMN,
208 EVENT_DESCR_COLUMN,
209 POSITION_COLUMN,
210 N_COLUMNS
211 };
212
213 /**
214 * Event Viewer's constructor hook
215 *
216 * This constructor is given as a parameter to the menuitem and toolbar button
217 * registration. It creates the list.
218 * @param parent_window A pointer to the parent window.
219 * @return The widget created.
220 */
221 GtkWidget *
222 h_gui_events(LttvPlugin *plugin)
223 {
224 LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
225 EventViewerData* event_viewer_data = gui_events(ptab) ;
226 if(event_viewer_data)
227 return event_viewer_data->top_widget;
228 else return NULL;
229
230 }
231
232 /**
233 * Event Viewer's constructor
234 *
235 * This constructor is used to create EventViewerData data structure.
236 * @return The Event viewer data created.
237 */
238 EventViewerData *
239 gui_events(LttvPluginTab *ptab)
240 {
241 LttTime end;
242 GtkTreeViewColumn *column;
243 GtkCellRenderer *renderer;
244 EventViewerData* event_viewer_data = g_new(EventViewerData,1) ;
245 Tab *tab = ptab->tab;
246 event_viewer_data->tab = tab;
247 event_viewer_data->ptab = ptab;
248
249 LttvTracesetContext * tsc =
250 lttvwindow_get_traceset_context(event_viewer_data->tab);
251
252
253 event_viewer_data->event_hooks = lttv_hooks_new();
254 lttv_hooks_add(event_viewer_data->event_hooks,
255 event_hook,
256 event_viewer_data,
257 LTTV_PRIO_DEFAULT);
258
259 lttvwindow_register_current_time_notify(tab,
260 update_current_time,event_viewer_data);
261 lttvwindow_register_current_position_notify(tab,
262 update_current_position,event_viewer_data);
263 lttvwindow_register_traceset_notify(tab,
264 traceset_changed,event_viewer_data);
265 lttvwindow_register_filter_notify(tab,
266 filter_changed, event_viewer_data);
267 lttvwindow_register_redraw_notify(tab,
268 redraw_notify, event_viewer_data);
269
270
271 event_viewer_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
272 gtk_widget_show (event_viewer_data->scroll_win);
273 gtk_scrolled_window_set_policy(
274 GTK_SCROLLED_WINDOW(event_viewer_data->scroll_win),
275 GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
276
277 event_viewer_data->currently_selected_position =
278 lttv_traceset_context_position_new(tsc);
279 event_viewer_data->first_event =
280 lttv_traceset_context_position_new(tsc);
281 event_viewer_data->last_event =
282 lttv_traceset_context_position_new(tsc);
283
284 event_viewer_data->main_win_filter = lttvwindow_get_filter(tab);
285
286 event_viewer_data->update_cursor = TRUE;
287 event_viewer_data->report_position = TRUE;
288
289 event_viewer_data->last_tree_update_time = 0;
290
291 /* Create a model for storing the data list */
292 event_viewer_data->store_m = gtk_list_store_new (
293 N_COLUMNS, /* Total number of columns */
294 G_TYPE_STRING, /* Trace name */
295 G_TYPE_STRING, /* Tracefile name */
296 G_TYPE_UINT, /* CPUID */
297 G_TYPE_STRING, /* Event */
298 G_TYPE_STRING, /* Facility */
299 G_TYPE_UINT, /* Time s */
300 G_TYPE_UINT, /* Time ns */
301 G_TYPE_INT, /* PID */
302 G_TYPE_STRING, /* Event's description */
303 G_TYPE_POINTER);/* Position (not shown) */
304
305 event_viewer_data->pos = g_ptr_array_sized_new(10);
306
307 /* Create the viewer widget for the columned list */
308 event_viewer_data->tree_v =
309 gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->store_m));
310
311 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-allocate",
312 G_CALLBACK (tree_v_size_allocate_cb),
313 event_viewer_data);
314 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "size-request",
315 G_CALLBACK (tree_v_size_request_cb),
316 event_viewer_data);
317
318 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "cursor-changed",
319 G_CALLBACK (tree_v_cursor_changed_cb),
320 event_viewer_data);
321
322 g_signal_connect (G_OBJECT (event_viewer_data->tree_v), "move-cursor",
323 G_CALLBACK (tree_v_move_cursor_cb),
324 event_viewer_data);
325
326 g_signal_connect (G_OBJECT(event_viewer_data->tree_v), "key-press-event",
327 G_CALLBACK(key_handler),
328 event_viewer_data);
329
330 g_signal_connect (G_OBJECT(event_viewer_data->tree_v), "scroll-event",
331 G_CALLBACK(tree_v_scroll_handler),
332 event_viewer_data);
333
334 // Use on each column!
335 //gtk_tree_view_column_set_sizing(event_viewer_data->tree_v,
336 //GTK_TREE_VIEW_COLUMN_FIXED);
337
338 /* The view now holds a reference. We can get rid of our own
339 * reference */
340 g_object_unref (G_OBJECT (event_viewer_data->store_m));
341
342
343 /* Create a column, associating the "text" attribute of the
344 * cell_renderer to the first column of the model */
345 /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */
346 renderer = gtk_cell_renderer_text_new ();
347 column = gtk_tree_view_column_new_with_attributes ("Trace",
348 renderer,
349 "text", TRACE_NAME_COLUMN,
350 NULL);
351 gtk_tree_view_column_set_alignment (column, 0.0);
352 gtk_tree_view_column_set_fixed_width (column, 120);
353 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
354 column);
355
356 event_viewer_data->button = column->button;
357
358 g_signal_connect (G_OBJECT(event_viewer_data->button),
359 "size-allocate",
360 G_CALLBACK(header_size_allocate),
361 (gpointer)event_viewer_data);
362
363
364
365 renderer = gtk_cell_renderer_text_new ();
366 column = gtk_tree_view_column_new_with_attributes ("Tracefile",
367 renderer,
368 "text", TRACEFILE_NAME_COLUMN,
369 NULL);
370 gtk_tree_view_column_set_alignment (column, 0.0);
371 gtk_tree_view_column_set_fixed_width (column, 120);
372 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
373 column);
374
375
376 renderer = gtk_cell_renderer_text_new ();
377 column = gtk_tree_view_column_new_with_attributes ("CPUID",
378 renderer,
379 "text", CPUID_COLUMN,
380 NULL);
381 gtk_tree_view_column_set_alignment (column, 0.0);
382 gtk_tree_view_column_set_fixed_width (column, 45);
383 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
384 column);
385
386 renderer = gtk_cell_renderer_text_new ();
387 column = gtk_tree_view_column_new_with_attributes ("Event",
388 renderer,
389 "text", EVENT_COLUMN,
390 NULL);
391 gtk_tree_view_column_set_alignment (column, 0.0);
392 gtk_tree_view_column_set_fixed_width (column, 120);
393 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
394 column);
395
396 renderer = gtk_cell_renderer_text_new ();
397 column = gtk_tree_view_column_new_with_attributes ("Facility",
398 renderer,
399 "text", FACILITY_COLUMN,
400 NULL);
401 gtk_tree_view_column_set_alignment (column, 0.0);
402 gtk_tree_view_column_set_fixed_width (column, 120);
403 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
404 column);
405
406 renderer = gtk_cell_renderer_text_new ();
407 column = gtk_tree_view_column_new_with_attributes ("Time (s)",
408 renderer,
409 "text", TIME_S_COLUMN,
410 NULL);
411 gtk_tree_view_column_set_alignment (column, 1.0);
412 gtk_tree_view_column_set_fixed_width (column, 120);
413 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
414 column);
415
416 renderer = gtk_cell_renderer_text_new ();
417 column = gtk_tree_view_column_new_with_attributes ("Time (ns)",
418 renderer,
419 "text", TIME_NS_COLUMN,
420 NULL);
421 gtk_tree_view_column_set_alignment (column, 1.0);
422 gtk_tree_view_column_set_fixed_width (column, 120);
423 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
424 column);
425
426
427 renderer = gtk_cell_renderer_text_new ();
428 column = gtk_tree_view_column_new_with_attributes ("PID",
429 renderer,
430 "text", PID_COLUMN,
431 NULL);
432 gtk_tree_view_column_set_alignment (column, 1.0);
433 gtk_tree_view_column_set_fixed_width (column, 45);
434 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
435 column);
436
437 renderer = gtk_cell_renderer_text_new ();
438 column = gtk_tree_view_column_new_with_attributes ("Event Description",
439 renderer,
440 "text", EVENT_DESCR_COLUMN,
441 NULL);
442 gtk_tree_view_column_set_alignment (column, 0.0);
443 gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->tree_v),
444 column);
445
446
447 /* Setup the selection handler */
448 event_viewer_data->select_c =
449 gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->tree_v));
450 gtk_tree_selection_set_mode (event_viewer_data->select_c,
451 GTK_SELECTION_SINGLE);
452 g_signal_connect (G_OBJECT (event_viewer_data->select_c), "changed",
453 G_CALLBACK (tree_selection_changed_cb),
454 event_viewer_data);
455
456 gtk_container_add (GTK_CONTAINER (event_viewer_data->scroll_win),
457 event_viewer_data->tree_v);
458
459 event_viewer_data->hbox_v = gtk_hbox_new(0, 0);
460 event_viewer_data->top_widget = event_viewer_data->hbox_v;
461 gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
462 event_viewer_data->scroll_win, TRUE, TRUE, 0);
463
464 gtk_container_set_border_width(GTK_CONTAINER(event_viewer_data->hbox_v), 1);
465
466 /* Create vertical scrollbar and pack it */
467 event_viewer_data->vscroll_vc = gtk_vscrollbar_new(NULL);
468 gtk_range_set_update_policy (GTK_RANGE(event_viewer_data->vscroll_vc),
469 GTK_UPDATE_CONTINUOUS);
470 // Changed by MD : more user friendly :)
471 //GTK_UPDATE_DISCONTINUOUS);
472 gtk_box_pack_start(GTK_BOX(event_viewer_data->hbox_v),
473 event_viewer_data->vscroll_vc, FALSE, TRUE, 0);
474
475 /* Get the vertical scrollbar's adjustment */
476 event_viewer_data->vadjust_c =
477 gtk_range_get_adjustment(GTK_RANGE(event_viewer_data->vscroll_vc));
478 event_viewer_data->vtree_adjust_c = gtk_tree_view_get_vadjustment(
479 GTK_TREE_VIEW (event_viewer_data->tree_v));
480
481 g_signal_connect (G_OBJECT (event_viewer_data->vadjust_c), "value-changed",
482 G_CALLBACK (v_scroll_cb),
483 event_viewer_data);
484 /* Set the upper bound to the last event number */
485 event_viewer_data->previous_value = 0;
486 event_viewer_data->vadjust_c->lower = 0.0;
487 //event_viewer_data->vadjust_c->upper = event_viewer_data->number_of_events;
488 event_viewer_data->vadjust_c->value = 0.0;
489 event_viewer_data->vadjust_c->step_increment = 1.0;
490 event_viewer_data->vadjust_c->page_increment = 2.0;
491 // event_viewer_data->vtree_adjust_c->upper;
492 event_viewer_data->vadjust_c->page_size = 2.0;
493 // event_viewer_data->vtree_adjust_c->upper;
494 /* Raw event trace */
495 gtk_widget_show(event_viewer_data->hbox_v);
496 gtk_widget_show(event_viewer_data->tree_v);
497 gtk_widget_show(event_viewer_data->vscroll_vc);
498
499 /* Add the object's information to the module's array */
500 g_event_viewer_data_list = g_slist_append(g_event_viewer_data_list,
501 event_viewer_data);
502
503 event_viewer_data->num_visible_events = 1;
504
505 //get the life span of the traceset and set the upper of the scroll bar
506
507 TimeInterval time_span = tsc->time_span;
508 end = ltt_time_sub(time_span.end_time, time_span.start_time);
509
510 event_viewer_data->vadjust_c->upper =
511 ltt_time_to_double(end);
512
513 /* Set the Selected Event */
514 // tree_v_set_cursor(event_viewer_data);
515
516 // event_viewer_data->current_time_updated = FALSE;
517 //
518 g_object_set_data_full(
519 G_OBJECT(event_viewer_data->hbox_v),
520 "event_viewer_data",
521 event_viewer_data,
522 (GDestroyNotify)gui_events_free);
523
524 event_viewer_data->background_info_waiting = 0;
525
526 request_background_data(event_viewer_data);
527
528
529 return event_viewer_data;
530 }
531
532
533
534 static gint background_ready(void *hook_data, void *call_data)
535 {
536 EventViewerData *event_viewer_data = (EventViewerData *)hook_data;
537 LttvTrace *trace = (LttvTrace*)call_data;
538
539 event_viewer_data->background_info_waiting--;
540
541 if(event_viewer_data->background_info_waiting == 0) {
542 g_message("event viewer : background computation data ready.");
543
544 redraw_notify(event_viewer_data, NULL);
545 }
546
547 return 0;
548 }
549
550
551 static void request_background_data(EventViewerData *event_viewer_data)
552 {
553 LttvTracesetContext * tsc =
554 lttvwindow_get_traceset_context(event_viewer_data->tab);
555 gint num_traces = lttv_traceset_number(tsc->ts);
556 gint i;
557 LttvTrace *trace;
558
559 LttvHooks *background_ready_hook =
560 lttv_hooks_new();
561 lttv_hooks_add(background_ready_hook, background_ready, event_viewer_data,
562 LTTV_PRIO_DEFAULT);
563 event_viewer_data->background_info_waiting = 0;
564
565 for(i=0;i<num_traces;i++) {
566 trace = lttv_traceset_get(tsc->ts, i);
567
568 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
569
570 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
571 trace) == FALSE) {
572 /* We first remove requests that could have been done for the same
573 * information. Happens when two viewers ask for it before servicing
574 * starts.
575 */
576 if(!lttvwindowtraces_background_request_find(trace, "state"))
577 lttvwindowtraces_background_request_queue(
578 main_window_get_widget(event_viewer_data->tab), trace, "state");
579 lttvwindowtraces_background_notify_queue(event_viewer_data,
580 trace,
581 ltt_time_infinite,
582 NULL,
583 background_ready_hook);
584 event_viewer_data->background_info_waiting++;
585 } else { /* in progress */
586
587 lttvwindowtraces_background_notify_current(event_viewer_data,
588 trace,
589 ltt_time_infinite,
590 NULL,
591 background_ready_hook);
592 event_viewer_data->background_info_waiting++;
593 }
594 } else {
595 /* Data ready. Be its nature, this viewer doesn't need to have
596 * its data ready hook called htere, because a background
597 * request is always linked with a redraw.
598 */
599 }
600
601 }
602
603 lttv_hooks_destroy(background_ready_hook);
604
605 }
606
607 static gboolean
608 header_size_allocate(GtkWidget *widget,
609 GtkAllocation *allocation,
610 gpointer user_data)
611 {
612 EventViewerData *event_viewer_data = (EventViewerData*)user_data;
613
614 event_viewer_data->header_height = allocation->height;
615
616 return 0;
617 }
618
619
620 void tree_v_set_cursor(EventViewerData *event_viewer_data)
621 {
622 GtkTreePath *path;
623
624 g_debug("set cursor cb");
625
626 #if 0
627 if(event_viewer_data->currently_selected_event != -1)
628 {
629 path = gtk_tree_path_new_from_indices(
630 event_viewer_data->currently_selected_event,
631 -1);
632
633 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
634 path, NULL, FALSE);
635 gtk_tree_path_free(path);
636 }
637 #endif //0
638 }
639
640 void tree_v_get_cursor(EventViewerData *event_viewer_data)
641 {
642 GtkTreePath *path;
643 gint *indices;
644
645 g_debug("get cursor cb");
646
647
648 #if 0
649 gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
650 &path, NULL);
651 indices = gtk_tree_path_get_indices(path);
652
653 if(indices != NULL)
654 event_viewer_data->currently_selected_event = indices[0];
655 else
656 event_viewer_data->currently_selected_event = -1;
657
658 gtk_tree_path_free(path);
659 #endif //0
660 }
661
662 /* Filter out the key repeats that come too fast */
663 static gboolean key_handler(GtkWidget *widget, GdkEventKey *event,
664 gpointer user_data)
665 {
666 EventViewerData *evd = (EventViewerData *)user_data;
667
668 g_debug("event time : %u , last time : %u", event->time,
669 evd->last_tree_update_time);
670
671 if(guint32_before(event->time, evd->last_tree_update_time))
672 return TRUE;
673 else
674 return FALSE;
675 }
676
677 void tree_v_move_cursor_cb (GtkWidget *widget,
678 GtkMovementStep arg1,
679 gint arg2,
680 gpointer data)
681 {
682 GtkTreePath *path; // = gtk_tree_path_new();
683 gint *indices;
684 gdouble value;
685 EventViewerData *event_viewer_data = (EventViewerData*)data;
686
687 g_debug("move cursor cb");
688 //gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
689 // &path, NULL);
690 //if(path == NULL)
691 //{
692 /* No prior cursor, put it at beginning of page
693 * and let the execution do */
694 // path = gtk_tree_path_new_from_indices(0, -1);
695 // gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
696 // path, NULL, FALSE);
697 //}
698
699 //indices = gtk_tree_path_get_indices(path);
700
701 //value = gtk_adjustment_get_value(event_viewer_data->vadjust_c);
702
703 /* If events request pending, do nothing*/
704 if(lttvwindow_events_request_pending(event_viewer_data->tab)) return;
705
706 /* If no prior position... */
707 #if 0
708 if(ltt_time_compare(
709 lttv_traceset_context_position_get_time(
710 event_viewer_data->currently_selected_position),
711 ltt_time_infinite) == 0) {
712
713 path = gtk_tree_path_new_from_indices(0, -1);
714 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
715 path, NULL, FALSE);
716
717 gtk_tree_path_free(path);
718 return;
719
720 }
721 #endif //0
722
723 g_debug("tree view move cursor : arg1 is %u and arg2 is %d",
724 (guint)arg1, arg2);
725
726 switch(arg1) {
727 case GTK_MOVEMENT_DISPLAY_LINES:
728 if(arg2 == 1) {
729 /* Move one line down */
730 if(event_viewer_data->pos->len > 0) {
731 LttvTracesetContextPosition *end_pos =
732 (LttvTracesetContextPosition*)g_ptr_array_index(
733 event_viewer_data->pos,
734 event_viewer_data->pos->len-1);
735 if(lttv_traceset_context_pos_pos_compare(end_pos,
736 event_viewer_data->currently_selected_position) == 0) {
737 /* Must get down one event and select the last one */
738 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
739 GTK_TREE_VIEW(event_viewer_data->tree_v)));
740 event_viewer_data->update_cursor = FALSE;
741 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
742 gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
743 event_viewer_data->update_cursor = TRUE;
744 if(event_viewer_data->pos->len > 0) {
745 path = gtk_tree_path_new_from_indices(
746 max(0, event_viewer_data->pos->len - 1), -1);
747 if(path) {
748 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
749 path, NULL, FALSE);
750 gtk_tree_path_free(path);
751 }
752 }
753 }
754 } else {
755 /* Must get down one event and select the last one */
756 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
757 GTK_TREE_VIEW(event_viewer_data->tree_v)));
758 event_viewer_data->update_cursor = FALSE;
759 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
760 gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
761 event_viewer_data->update_cursor = TRUE;
762 if(event_viewer_data->pos->len > 0) {
763 path = gtk_tree_path_new_from_indices(
764 max(0, event_viewer_data->pos->len - 1), -1);
765 if(path) {
766 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
767 path, NULL, FALSE);
768 gtk_tree_path_free(path);
769 }
770 }
771 }
772
773 } else {
774 if(event_viewer_data->pos->len > 0) {
775 /* Move one line up */
776 LttvTracesetContextPosition *begin_pos =
777 (LttvTracesetContextPosition*)g_ptr_array_index(
778 event_viewer_data->pos,
779 0);
780 if(lttv_traceset_context_pos_pos_compare(begin_pos,
781 event_viewer_data->currently_selected_position) == 0) {
782 /* Must get up one event and select the first one */
783 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
784 GTK_TREE_VIEW(event_viewer_data->tree_v)));
785 event_viewer_data->update_cursor = FALSE;
786 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
787 gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
788 event_viewer_data->update_cursor = TRUE;
789 if(event_viewer_data->pos->len > 0) {
790 path = gtk_tree_path_new_from_indices(
791 0, -1);
792 if(path) {
793 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
794 path, NULL, FALSE);
795 gtk_tree_path_free(path);
796 }
797 }
798 }
799 } else {
800 /* Must get up one event and select the first one */
801 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
802 GTK_TREE_VIEW(event_viewer_data->tree_v)));
803 event_viewer_data->update_cursor = FALSE;
804 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
805 gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
806 event_viewer_data->update_cursor = TRUE;
807 if(event_viewer_data->pos->len > 0) {
808 path = gtk_tree_path_new_from_indices(
809 0, -1);
810 if(path) {
811 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
812 path, NULL, FALSE);
813 gtk_tree_path_free(path);
814 }
815 }
816 }
817 }
818 break;
819 case GTK_MOVEMENT_PAGES:
820 if(arg2 == 1) {
821 /* Move one page down */
822 if(event_viewer_data->pos->len > 0) {
823 LttvTracesetContextPosition *end_pos =
824 (LttvTracesetContextPosition*)g_ptr_array_index(
825 event_viewer_data->pos,
826 event_viewer_data->pos->len-1);
827 if(lttv_traceset_context_pos_pos_compare(end_pos,
828 event_viewer_data->currently_selected_position) == 0) {
829 /* Must get down one page and select the last one */
830 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
831 GTK_TREE_VIEW(event_viewer_data->tree_v)));
832 event_viewer_data->update_cursor = FALSE;
833 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
834 gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 2);
835 event_viewer_data->update_cursor = TRUE;
836 if(event_viewer_data->pos->len > 0) {
837 path = gtk_tree_path_new_from_indices(
838 event_viewer_data->pos->len - 1, -1);
839 if(path) {
840 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
841 path, NULL, FALSE);
842 gtk_tree_path_free(path);
843 }
844 }
845 }
846 } else {
847 /* Must get down one page and select the last one */
848 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
849 GTK_TREE_VIEW(event_viewer_data->tree_v)));
850 event_viewer_data->update_cursor = FALSE;
851 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
852 gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 2);
853 event_viewer_data->update_cursor = TRUE;
854 if(event_viewer_data->pos->len > 0) {
855 path = gtk_tree_path_new_from_indices(
856 event_viewer_data->pos->len - 1, -1);
857 if(path) {
858 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
859 path, NULL, FALSE);
860 gtk_tree_path_free(path);
861 }
862 }
863 }
864 } else {
865 /* Move one page up */
866 if(event_viewer_data->pos->len > 0) {
867 LttvTracesetContextPosition *begin_pos =
868 (LttvTracesetContextPosition*)g_ptr_array_index(
869 event_viewer_data->pos,
870 0);
871 if(lttv_traceset_context_pos_pos_compare(begin_pos,
872 event_viewer_data->currently_selected_position) == 0) {
873 /* Must get up one page and select the first one */
874 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
875 GTK_TREE_VIEW(event_viewer_data->tree_v)));
876 event_viewer_data->update_cursor = FALSE;
877 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
878 gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 2);
879 event_viewer_data->update_cursor = TRUE;
880 if(event_viewer_data->pos->len > 0) {
881 path = gtk_tree_path_new_from_indices(
882 0, -1);
883 if(path) {
884 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
885 path, NULL, FALSE);
886 gtk_tree_path_free(path);
887 }
888 }
889 }
890 } else {
891 /* Must get up one page and select the first one */
892 gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(
893 GTK_TREE_VIEW(event_viewer_data->tree_v)));
894 event_viewer_data->update_cursor = FALSE;
895 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
896 gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 2);
897 event_viewer_data->update_cursor = TRUE;
898 if(event_viewer_data->pos->len > 0) {
899 path = gtk_tree_path_new_from_indices(
900 0, -1);
901 if(path) {
902 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
903 path, NULL, FALSE);
904 gtk_tree_path_free(path);
905 }
906 }
907 }
908 }
909 break;
910 default:
911 break;
912 }
913
914 //gtk_tree_path_free(path);
915
916 #if 0
917 if(arg1 == GTK_MOVEMENT_DISPLAY_LINES)
918 {
919 /* Move one line */
920 if(arg2 == 1)
921 {
922 /* move one line down */
923 if(indices[0]) // Do we need an empty field here (before first)?
924 {
925 if(value + event_viewer_data->num_visible_events <=
926 event_viewer_data->number_of_events -1)
927 {
928 event_viewer_data->currently_selected_event += 1;
929 // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value+1);
930 //gtk_tree_path_free(path);
931 //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
932 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
933 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
934 }
935 }
936 } else {
937 /* Move one line up */
938 if(indices[0] == 0)
939 {
940 if(value - 1 >= 0 )
941 {
942 event_viewer_data->currently_selected_event -= 1;
943 // gtk_adjustment_set_value(event_viewer_data->vadjust_c, value-1);
944 //gtk_tree_path_free(path);
945 //path = gtk_tree_path_new_from_indices(0, -1);
946 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
947 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
948 }
949 }
950 }
951 }
952
953 if(arg1 == GTK_MOVEMENT_PAGES)
954 {
955 /* Move one page */
956 if(arg2 == 1)
957 {
958 if(event_viewer_data->num_visible_events == 1)
959 value += 1 ;
960 /* move one page down */
961 if(value + event_viewer_data->num_visible_events-1 <=
962 event_viewer_data->number_of_events )
963 {
964 event_viewer_data->currently_selected_event +=
965 event_viewer_data->num_visible_events-1;
966 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
967 // value+(event_viewer_data->num_visible_events-1));
968 //gtk_tree_path_free(path);
969 //path = gtk_tree_path_new_from_indices(0, -1);
970 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
971 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
972 }
973 } else {
974 /* Move one page up */
975 if(event_viewer_data->num_visible_events == 1)
976 value -= 1 ;
977
978 if(indices[0] < event_viewer_data->num_visible_events - 2 )
979 {
980 if(value - (event_viewer_data->num_visible_events-1) >= 0)
981 {
982 event_viewer_data->currently_selected_event -=
983 event_viewer_data->num_visible_events-1;
984
985 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
986 // value-(event_viewer_data->num_visible_events-1));
987 //gtk_tree_path_free(path);
988 //path = gtk_tree_path_new_from_indices(0, -1);
989 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
990 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
991
992 } else {
993 /* Go to first Event */
994 event_viewer_data->currently_selected_event == 0 ;
995 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
996 // 0);
997 //gtk_tree_path_free(path);
998 //path = gtk_tree_path_new_from_indices(0, -1);
999 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
1000 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
1001
1002 }
1003 }
1004 }
1005 }
1006
1007 if(arg1 == GTK_MOVEMENT_BUFFER_ENDS)
1008 {
1009 /* Move to the ends of the buffer */
1010 if(arg2 == 1)
1011 {
1012 /* move end of buffer */
1013 event_viewer_data->currently_selected_event =
1014 event_viewer_data->number_of_events-1 ;
1015 // gtk_adjustment_set_value(event_viewer_data->vadjust_c,
1016 // event_viewer_data->number_of_events -
1017 // event_viewer_data->num_visible_events);
1018 //gtk_tree_path_free(path);
1019 //path = gtk_tree_path_new_from_indices(event_viewer_data->num_visible_events-1, -1);
1020 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
1021 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
1022 } else {
1023 /* Move beginning of buffer */
1024 event_viewer_data->currently_selected_event = 0 ;
1025 // gtk_adjustment_set_value(event_viewer_data->vadjust_c, 0);
1026 //gtk_tree_path_free(path);
1027 //path = gtk_tree_path_new_from_indices(0, -1);
1028 //gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), path, NULL, FALSE);
1029 g_signal_stop_emission_by_name(G_OBJECT(widget), "move-cursor");
1030 }
1031 }
1032 #endif //0
1033 }
1034
1035
1036 gboolean tree_v_scroll_handler (GtkWidget *widget, GdkEventScroll *event, gpointer data)
1037 {
1038 EventViewerData *event_viewer_data = (EventViewerData*) data;
1039 Tab *tab = event_viewer_data->tab;
1040
1041 switch(event->direction) {
1042 case GDK_SCROLL_UP:
1043 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
1044 gtk_adjustment_get_value(event_viewer_data->vadjust_c) - 1);
1045 break;
1046 case GDK_SCROLL_DOWN:
1047 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
1048 gtk_adjustment_get_value(event_viewer_data->vadjust_c) + 1);
1049 break;
1050 default:
1051 g_error("Only scroll up and down expected");
1052 }
1053 return TRUE;
1054 }
1055
1056 void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data)
1057 {
1058 EventViewerData *event_viewer_data = (EventViewerData*) data;
1059 Tab *tab = event_viewer_data->tab;
1060 GtkTreeIter iter;
1061 GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
1062 GtkTreePath *path;
1063 LttvTracesetContextPosition *pos;
1064
1065 g_debug("cursor changed cb");
1066
1067 /* On cursor change, modify the currently selected event by calling
1068 * the right API function */
1069 if(event_viewer_data->report_position) {
1070 if(event_viewer_data->pos->len > 0) {
1071 gtk_tree_view_get_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
1072 &path, NULL);
1073 if(path) {
1074 if(gtk_tree_model_get_iter(model,&iter,path)){
1075 gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
1076
1077 if(lttv_traceset_context_pos_pos_compare(pos,
1078 event_viewer_data->currently_selected_position) != 0)
1079 lttvwindow_report_current_position(tab, pos);
1080 }else{
1081 g_warning("Can not get iter\n");
1082 }
1083 gtk_tree_path_free(path);
1084 }
1085 }
1086 }
1087 }
1088
1089
1090 static void tree_selection_changed_cb (GtkTreeSelection *selection,
1091 gpointer data)
1092 {
1093 g_debug("tree sel changed cb");
1094 EventViewerData *event_viewer_data = (EventViewerData*) data;
1095 #if 0
1096 /* Set the cursor to currently selected event */
1097 GtkTreeModel* model = GTK_TREE_MODEL(event_viewer_data->store_m);
1098 GtkTreeIter iter;
1099 LttvTracesetContextPosition *pos;
1100 guint i;
1101 GtkTreePath *tree_path;
1102
1103 for(i=0;i<event_viewer_data->num_visible_events;i++) {
1104 tree_path = gtk_tree_path_new_from_indices(
1105 i,
1106 -1);
1107 if(gtk_tree_model_get_iter(model,&iter,tree_path)){
1108 gtk_tree_model_get(model, &iter, POSITION_COLUMN, &pos, -1);
1109
1110 if(lttv_traceset_context_pos_pos_compare(pos,
1111 event_viewer_data->currently_selected_position) == 0) {
1112 /* Match! */
1113 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
1114 tree_path, NULL, FALSE);
1115 break;
1116 }
1117
1118 }else{
1119 g_warning("Can not get iter\n");
1120 }
1121 gtk_tree_path_free(tree_path);
1122 }
1123 #endif //0
1124 }
1125
1126 #if 0
1127 static gint key_snooper(GtkWidget *grab_widget, GdkEventKey *event,
1128 gpointer func_data)
1129 {
1130 return TRUE;
1131 }
1132 #endif //0
1133
1134 /* This callback may be recalled after a step up/down, but we don't want to lose
1135 * the exact position : what we do is that we only set the value if it has
1136 * changed : a step up/down that doesn't change the time value of the first
1137 * event won't trigger a scrollbar change. */
1138
1139 void v_scroll_cb (GtkAdjustment *adjustment, gpointer data)
1140 {
1141 EventViewerData *event_viewer_data = (EventViewerData*)data;
1142 LttvTracesetStats *tss =
1143 lttvwindow_get_traceset_stats(event_viewer_data->tab);
1144 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
1145 g_debug("SCROLL begin");
1146 g_debug("SCROLL values : %g , %g, %g",
1147 adjustment->value, event_viewer_data->previous_value,
1148 (adjustment->value - event_viewer_data->previous_value));
1149
1150 LttTime new_time_off = ltt_time_from_double(adjustment->value);
1151 LttTime old_time_off = ltt_time_from_double(event_viewer_data->previous_value);
1152 g_debug("SCROLL time values %lu.%lu, %lu.%lu", new_time_off.tv_sec,
1153 new_time_off.tv_nsec, old_time_off.tv_sec, old_time_off.tv_nsec);
1154 /* If same value : nothing to update */
1155 if(ltt_time_compare(new_time_off, old_time_off) == 0)
1156 return;
1157
1158 //LttTime old_time = event_viewer_data->first_event;
1159
1160
1161 //gint snoop = gtk_key_snooper_install(key_snooper, NULL);
1162
1163 get_events(adjustment->value, event_viewer_data);
1164
1165 //gtk_key_snooper_remove(snoop);
1166 #if 0
1167 LttTime time = ltt_time_sub(event_viewer_data->first_event,
1168 tsc->time_span.start_time);
1169 double value = ltt_time_to_double(time);
1170 gtk_adjustment_set_value(event_viewer_data->vadjust_c, value);
1171
1172 if(event_viewer_data->currently_selected_event != -1) {
1173
1174 tree_path = gtk_tree_path_new_from_indices(
1175 event_viewer_data->currently_selected_event,
1176 -1);
1177
1178 // gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v), tree_path,
1179 // NULL, FALSE);
1180 gtk_tree_path_free(tree_path);
1181 }
1182 #endif //0
1183 g_debug("SCROLL end");
1184 }
1185
1186 static __inline gint get_cell_height(GtkTreeView *TreeView)
1187 {
1188 gint height;
1189 GtkTreeViewColumn *column = gtk_tree_view_get_column(TreeView, 0);
1190
1191 gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, NULL, &height);
1192
1193 gint vertical_separator;
1194 gtk_widget_style_get (GTK_WIDGET (TreeView),
1195 "vertical-separator", &vertical_separator,
1196 NULL);
1197
1198 height += vertical_separator;
1199
1200 return height;
1201 }
1202
1203 void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data)
1204 {
1205 EventViewerData *event_viewer_data = (EventViewerData*)data;
1206 gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
1207 gint last_num_visible_events = event_viewer_data->num_visible_events;
1208 gdouble exact_num_visible;
1209
1210 exact_num_visible = ( alloc->height -
1211 event_viewer_data->header_height )
1212 / (double)cell_height ;
1213
1214 event_viewer_data->num_visible_events = ceil(exact_num_visible) ;
1215
1216 /*
1217 event_viewer_data->vadjust_c->page_increment =
1218 floor(exact_num_visible);
1219 event_viewer_data->vadjust_c->page_size =
1220 floor(exact_num_visible);
1221 */
1222
1223 g_debug("size allocate : last_num_visible_events : %d,\
1224 num_visible_events : %d",
1225 last_num_visible_events,
1226 event_viewer_data->num_visible_events);
1227 if(event_viewer_data->num_visible_events != last_num_visible_events)
1228 {
1229 get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
1230 }
1231
1232
1233 }
1234
1235 void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data)
1236 {
1237 gint h;
1238 EventViewerData *event_viewer_data = (EventViewerData*)data;
1239 gint cell_height = get_cell_height(GTK_TREE_VIEW(event_viewer_data->tree_v));
1240
1241 h = cell_height + event_viewer_data->header_height;
1242 requisition->height = h;
1243
1244 }
1245
1246 #if 0
1247 gboolean show_event_detail(void * hook_data, void * call_data)
1248 {
1249 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1250 LttvTracesetContext * tsc = lttvwindow_get_traceset_context(event_viewer_data->tab);
1251
1252 if(event_viewer_data->event_fields_queue_tmp->length == 0 &&
1253 event_viewer_data->event_fields_queue->length == 0){
1254 event_viewer_data->shown = FALSE;
1255 return FALSE;
1256 }
1257
1258 if(event_viewer_data->shown == FALSE){
1259 event_viewer_data->shown = TRUE;
1260 update_raw_data_array(event_viewer_data,
1261 event_viewer_data->event_fields_queue_tmp->length);
1262
1263 get_data(event_viewer_data->vadjust_c->value,
1264 event_viewer_data->num_visible_events,
1265 event_viewer_data);
1266
1267 remove_context_hooks(event_viewer_data,tsc);
1268 }
1269
1270 return FALSE;
1271 }
1272 #endif //0
1273
1274
1275
1276
1277
1278
1279
1280 static void get_events(double new_value, EventViewerData *event_viewer_data)
1281 {
1282 GtkTreePath *tree_path;
1283 LttvTracesetStats *tss =
1284 lttvwindow_get_traceset_stats(event_viewer_data->tab);
1285 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
1286 guint i;
1287 gboolean seek_by_time;
1288
1289 double value = new_value - event_viewer_data->previous_value;
1290
1291 /* Set stop button status for foreground processing */
1292 event_viewer_data->tab->stop_foreground = FALSE;
1293 lttvwindow_events_request_disable();
1294
1295 /* See where we have to scroll... */
1296 ScrollDirection direction;
1297 gint relative_position;
1298
1299 if(value < -0.8) {
1300 if(value >= -1.0) direction = SCROLL_STEP_UP;
1301 else {
1302 if(value >= -2.0) direction = SCROLL_PAGE_UP;
1303 else direction = SCROLL_JUMP;
1304 }
1305 } else if(value > 0.8) {
1306 if(value <= 1.0) direction = SCROLL_STEP_DOWN;
1307 else {
1308 if(value <= 2.0) direction = SCROLL_PAGE_DOWN;
1309 else direction = SCROLL_JUMP;
1310 }
1311 } else direction = SCROLL_NONE; /* 0.0 */
1312
1313
1314 switch(direction) {
1315 case SCROLL_STEP_UP:
1316 g_debug("get_events : SCROLL_STEP_UP");
1317 relative_position = -1;
1318 seek_by_time = 0;
1319 break;
1320 case SCROLL_STEP_DOWN:
1321 g_debug("get_events : SCROLL_STEP_DOWN");
1322 relative_position = 1;
1323 seek_by_time = 0;
1324 break;
1325 case SCROLL_PAGE_UP:
1326 g_debug("get_events : SCROLL_PAGE_UP");
1327 relative_position = -(event_viewer_data->num_visible_events);
1328 seek_by_time = 0;
1329 break;
1330 case SCROLL_PAGE_DOWN:
1331 g_debug("get_events : SCROLL_PAGE_DOWN");
1332 relative_position = event_viewer_data->num_visible_events;
1333 seek_by_time = 0;
1334 break;
1335 case SCROLL_JUMP:
1336 g_debug("get_events : SCROLL_JUMP");
1337 seek_by_time = 1;
1338 break;
1339 case SCROLL_NONE:
1340 g_debug("get_events : SCROLL_NONE");
1341 relative_position = 0;
1342 seek_by_time = 0;
1343 break;
1344 }
1345
1346 LttTime time = ltt_time_from_double(new_value);
1347 time = ltt_time_add(tsc->time_span.start_time, time);
1348
1349 if(!seek_by_time) {
1350
1351 LttvTracesetContextPosition *pos =
1352 lttv_traceset_context_position_new(tsc);
1353
1354 /* Remember the beginning position */
1355 if(event_viewer_data->pos->len > 0) {
1356 LttvTracesetContextPosition *first_pos =
1357 (LttvTracesetContextPosition*)g_ptr_array_index(
1358 event_viewer_data->pos,
1359 0);
1360 lttv_traceset_context_position_copy(pos, first_pos);
1361
1362 if(relative_position >= 0) {
1363 LttTime first_event_time =
1364 lttv_traceset_context_position_get_time(
1365 pos);
1366 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
1367 first_event_time);
1368 lttv_process_traceset_middle(tsc, ltt_time_infinite,
1369 G_MAXUINT,
1370 pos);
1371
1372 } else if(relative_position < 0) {
1373 g_assert(lttv_process_traceset_seek_position(tsc, pos) == 0);
1374 }
1375 } else {
1376 /* There is nothing in the list : simply seek to the time value. */
1377 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
1378 time);
1379 lttv_process_traceset_middle(tsc, time, G_MAXUINT,
1380 NULL);
1381 }
1382
1383 /* Note that, as we mess with the tsc position, this function CANNOT be called
1384 * from a hook inside the lttv_process_traceset_middle. */
1385 /* As the lttvwindow API keeps a sync_position inside the tsc to go back at
1386 * the right spot after being interrupted, it's ok to change the tsc position,
1387 * as long as we do not touch the sync_position. */
1388
1389 /* Get the beginning position of the read (with seek backward or seek forward)
1390 */
1391 if(relative_position > 0) {
1392 guint count;
1393 count = lttv_process_traceset_seek_n_forward(tsc, relative_position,
1394 event_viewer_data->main_win_filter);
1395 } else if(relative_position < 0) {
1396 guint count;
1397
1398 /* Get an idea of currently shown event dispersion */
1399 LttTime first_event_time =
1400 lttv_traceset_context_position_get_time(event_viewer_data->first_event);
1401 LttTime last_event_time =
1402 lttv_traceset_context_position_get_time(event_viewer_data->last_event);
1403 LttTime time_diff = ltt_time_sub(last_event_time, first_event_time);
1404 if(ltt_time_compare(time_diff, ltt_time_zero) == 0)
1405 time_diff = seek_back_default_offset;
1406 count = lttv_process_traceset_seek_n_backward(tsc, abs(relative_position),
1407 time_diff,
1408 (seek_time_fct)lttv_state_traceset_seek_time_closest,
1409 event_viewer_data->main_win_filter);
1410 } /* else 0 : do nothing : we are already at the beginning position */
1411
1412 lttv_traceset_context_position_destroy(pos);
1413
1414 /* Save the first event position */
1415 lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
1416
1417 time = lttv_traceset_context_position_get_time(
1418 event_viewer_data->first_event);
1419 //if(ltt_time_compare(time, tsc->time_span.end_time) > 0)
1420 // time = tsc->time_span.end_time;
1421
1422 LttTime time_val = ltt_time_sub(time,
1423 tsc->time_span.start_time);
1424 event_viewer_data->previous_value = ltt_time_to_double(time_val);
1425
1426 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc, time);
1427 lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT,
1428 event_viewer_data->first_event);
1429
1430 } else {
1431 /* Seek by time */
1432 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
1433 time);
1434 lttv_process_traceset_middle(tsc, time, G_MAXUINT,
1435 NULL);
1436 LttTime time_val = ltt_time_sub(time,
1437 tsc->time_span.start_time);
1438 event_viewer_data->previous_value = ltt_time_to_double(time_val);
1439 lttv_traceset_context_position_save(tsc, event_viewer_data->first_event);
1440 }
1441
1442 /* Clear the model (don't forget to free the TCS positions!) */
1443 gtk_list_store_clear(event_viewer_data->store_m);
1444 for(i=0;i<event_viewer_data->pos->len;i++) {
1445 LttvTracesetContextPosition *cur_pos =
1446 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
1447 i);
1448 lttv_traceset_context_position_destroy(cur_pos);
1449 }
1450 g_ptr_array_set_size(event_viewer_data->pos, 0);
1451
1452
1453 /* Mathieu :
1454 * I make the choice not to use the mainwindow lttvwindow API here : the idle
1455 * loop might have a too low priority, and we want good update while
1456 * scrolling. However, we call the gdk loop to get events periodically so the
1457 * processing can be stopped.
1458 */
1459
1460 lttv_process_traceset_begin(tsc,
1461 NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
1462
1463 event_viewer_data->num_events = 0;
1464
1465 lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
1466
1467 lttv_process_traceset_end(tsc,
1468 NULL, NULL, NULL, event_viewer_data->event_hooks, NULL);
1469
1470 /* Get the end position */
1471 if(event_viewer_data->pos->len > 0) {
1472 LttvTracesetContextPosition *cur_pos =
1473 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
1474 event_viewer_data->pos->len - 1);
1475 lttv_traceset_context_position_copy(event_viewer_data->last_event,
1476 cur_pos);
1477 } else
1478 lttv_traceset_context_position_save(tsc, event_viewer_data->last_event);
1479
1480 gtk_adjustment_set_value(event_viewer_data->vadjust_c,
1481 event_viewer_data->previous_value);
1482
1483 //g_signal_emit_by_name(G_OBJECT (event_viewer_data->select_c),
1484 // "changed");
1485
1486 event_viewer_data->last_tree_update_time =
1487 gdk_x11_get_server_time(
1488 gtk_widget_get_parent_window(event_viewer_data->tree_v));
1489
1490 lttvwindow_events_request_enable();
1491
1492 return;
1493 }
1494
1495
1496
1497 int event_hook(void *hook_data, void *call_data)
1498 {
1499 EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
1500 LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
1501 LttvTracefileState *tfs = (LttvTracefileState*)call_data;
1502 LttEvent *e = ltt_tracefile_get_event(tfc->tf);
1503
1504 if(event_viewer_data->num_events % CHECK_GDK_INTERVAL == 0) {
1505 gtk_main_iteration();
1506 if(event_viewer_data->tab->stop_foreground)
1507 return TRUE;
1508 }
1509 event_viewer_data->num_events++;
1510
1511 LttvFilter *filter = event_viewer_data->main_win_filter;
1512 if(filter != NULL && filter->head != NULL)
1513 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1514 tfc->t_context->t,tfc))
1515 return FALSE;
1516
1517 LttFacility *facility = ltt_event_facility(e);
1518 LttEventType *event_type = ltt_event_eventtype(e);
1519 LttTime time = ltt_event_time(e);
1520
1521 guint cpu = tfs->cpu;
1522 LttvTraceState *ts = (LttvTraceState*)tfc->t_context;
1523 LttvProcessState *process = ts->running_process[cpu];
1524
1525 GtkTreeIter iter;
1526
1527 GString *desc = g_string_new("");
1528
1529 LttvTracesetContextPosition *pos =
1530 lttv_traceset_context_position_new(tfc->t_context->ts_context);
1531
1532 lttv_traceset_context_position_save(tfc->t_context->ts_context, pos);
1533
1534 lttv_event_to_string(e, desc, TRUE, TRUE, (LttvTracefileState*)tfc);
1535
1536 g_info("detail : %s", desc->str);
1537
1538 gtk_list_store_append (event_viewer_data->store_m, &iter);
1539 gtk_list_store_set (event_viewer_data->store_m, &iter,
1540 TRACE_NAME_COLUMN, g_quark_to_string(ltt_trace_name(tfc->t_context->t)),
1541 TRACEFILE_NAME_COLUMN, g_quark_to_string(ltt_tracefile_name(tfc->tf)),
1542 CPUID_COLUMN, cpu,
1543 FACILITY_COLUMN, g_quark_to_string(ltt_facility_name(facility)),
1544 EVENT_COLUMN, g_quark_to_string(ltt_eventtype_name(event_type)),
1545 TIME_S_COLUMN, time.tv_sec,
1546 TIME_NS_COLUMN, time.tv_nsec,
1547 PID_COLUMN, process->pid,
1548 EVENT_DESCR_COLUMN, desc->str,
1549 POSITION_COLUMN, pos,
1550 -1);
1551
1552 g_ptr_array_add(event_viewer_data->pos, pos);
1553
1554 g_string_free(desc, TRUE);
1555
1556 if(event_viewer_data->update_cursor) {
1557 if(lttv_traceset_context_pos_pos_compare(pos,
1558 event_viewer_data->currently_selected_position) == 0) {
1559 GtkTreePath *path = gtk_tree_path_new_from_indices(
1560 event_viewer_data->pos->len - 1, -1);
1561 if(path) {
1562 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
1563 path, NULL, FALSE);
1564 gtk_tree_path_free(path);
1565 }
1566 }
1567 }
1568
1569 if(event_viewer_data->pos->len >= event_viewer_data->num_visible_events )
1570 return TRUE;
1571 else
1572 return FALSE;
1573 }
1574
1575
1576
1577 static void event_update_selection(EventViewerData *event_viewer_data)
1578 {
1579 guint i;
1580 GPtrArray *positions = event_viewer_data->pos;
1581 g_info("event_update_selection");
1582
1583 for(i=0;i<positions->len;i++) {
1584 LttvTracesetContextPosition *cur_pos =
1585 (LttvTracesetContextPosition*)g_ptr_array_index(positions, i);
1586 if(lttv_traceset_context_pos_pos_compare(cur_pos,
1587 event_viewer_data->currently_selected_position) == 0) {
1588 GtkTreePath *path = gtk_tree_path_new_from_indices(i, -1);
1589 if(path) {
1590 gtk_tree_view_set_cursor(GTK_TREE_VIEW(event_viewer_data->tree_v),
1591 path, NULL, FALSE);
1592 gtk_tree_path_free(path);
1593 }
1594 }
1595 }
1596 }
1597
1598 static int current_time_get_first_event_hook(void *hook_data, void *call_data)
1599 {
1600 EventViewerData *event_viewer_data = (EventViewerData*)hook_data;
1601 LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
1602 LttEvent *e = ltt_tracefile_get_event(tfc->tf);
1603
1604 LttvFilter *filter = event_viewer_data->main_win_filter;
1605 if(filter != NULL && filter->head != NULL)
1606 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1607 tfc->t_context->t,tfc))
1608 return FALSE;
1609
1610 lttv_traceset_context_position_save(tfc->t_context->ts_context,
1611 event_viewer_data->current_time_get_first);
1612 return TRUE;
1613 }
1614
1615
1616 gboolean update_current_time(void * hook_data, void * call_data)
1617 {
1618 g_info("update_current_time");
1619 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1620 const LttTime * current_time = (LttTime*)call_data;
1621 LttvTracesetContext * tsc =
1622 lttvwindow_get_traceset_context(event_viewer_data->tab);
1623 GtkTreePath *path;
1624
1625 /* If the currently selected event time != current time, set the first event
1626 * with this time as currently selected. */
1627 LttTime pos_time = lttv_traceset_context_position_get_time(
1628 event_viewer_data->currently_selected_position);
1629 if(ltt_time_compare(pos_time, *current_time) != 0) {
1630
1631 lttv_state_traceset_seek_time_closest((LttvTracesetState*)tsc,
1632 *current_time);
1633 lttv_process_traceset_middle(tsc, *current_time, G_MAXUINT,
1634 NULL);
1635
1636 /* Get the first event that passes in the filter */
1637 event_viewer_data->current_time_get_first =
1638 lttv_traceset_context_position_new(tsc);
1639 LttvHooks *hooks = lttv_hooks_new();
1640 lttv_hooks_add(hooks,
1641 current_time_get_first_event_hook,
1642 event_viewer_data,
1643 LTTV_PRIO_DEFAULT);
1644
1645 lttv_process_traceset_begin(tsc,
1646 NULL, NULL, NULL, hooks, NULL);
1647
1648 lttv_process_traceset_middle(tsc, ltt_time_infinite, G_MAXUINT, NULL);
1649
1650 lttv_process_traceset_end(tsc,
1651 NULL, NULL, NULL, hooks, NULL);
1652
1653 lttv_hooks_destroy(hooks);
1654
1655 lttv_traceset_context_position_copy(
1656 event_viewer_data->currently_selected_position,
1657 event_viewer_data->current_time_get_first);
1658 lttv_traceset_context_position_destroy(
1659 event_viewer_data->current_time_get_first);
1660 pos_time = lttv_traceset_context_position_get_time(
1661 event_viewer_data->currently_selected_position);
1662 }
1663
1664 LttTime time = ltt_time_sub(pos_time, tsc->time_span.start_time);
1665 double new_value = ltt_time_to_double(time);
1666
1667 event_viewer_data->report_position = FALSE;
1668 /* Change the viewed area if does not match */
1669 if(lttv_traceset_context_pos_pos_compare(
1670 event_viewer_data->currently_selected_position,
1671 event_viewer_data->first_event) < 0
1672 ||
1673 lttv_traceset_context_pos_pos_compare(
1674 event_viewer_data->currently_selected_position,
1675 event_viewer_data->last_event) > 0) {
1676 gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
1677 } else {
1678 /* Simply update the current time : it is in the list */
1679 event_update_selection(event_viewer_data);
1680 }
1681 event_viewer_data->report_position = TRUE;
1682
1683 return FALSE;
1684 }
1685
1686 gboolean update_current_position(void * hook_data, void * call_data)
1687 {
1688 g_info("update_current_position");
1689 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1690 const LttvTracesetContextPosition *current_pos =
1691 (LttvTracesetContextPosition*)call_data;
1692 LttvTracesetContext * tsc =
1693 lttvwindow_get_traceset_context(event_viewer_data->tab);
1694
1695 if(lttv_traceset_context_pos_pos_compare(
1696 event_viewer_data->currently_selected_position, current_pos) != 0) {
1697 lttv_traceset_context_position_copy(
1698 event_viewer_data->currently_selected_position, current_pos);
1699
1700 /* Change the viewed area if does not match */
1701 if(lttv_traceset_context_pos_pos_compare(
1702 event_viewer_data->currently_selected_position,
1703 event_viewer_data->first_event) < 0
1704 ||
1705 lttv_traceset_context_pos_pos_compare(
1706 event_viewer_data->currently_selected_position,
1707 event_viewer_data->last_event) > 0) {
1708 LttTime time = lttv_traceset_context_position_get_time(current_pos);
1709 time = ltt_time_sub(time, tsc->time_span.start_time);
1710 double new_value = ltt_time_to_double(time);
1711 gtk_adjustment_set_value(event_viewer_data->vadjust_c, new_value);
1712 } else {
1713 /* Simply update the current time : it is in the list */
1714 event_update_selection(event_viewer_data);
1715 }
1716
1717 }
1718
1719
1720 return FALSE;
1721 }
1722
1723
1724
1725 gboolean traceset_changed(void * hook_data, void * call_data)
1726 {
1727 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1728 LttvTracesetContext * tsc =
1729 lttvwindow_get_traceset_context(event_viewer_data->tab);
1730 TimeInterval time_span = tsc->time_span;
1731
1732 LttTime end;
1733 gtk_list_store_clear(event_viewer_data->store_m);
1734 g_ptr_array_set_size(event_viewer_data->pos, 0);
1735
1736 end = ltt_time_sub(time_span.end_time, time_span.start_time);
1737 event_viewer_data->vadjust_c->upper = ltt_time_to_double(end);
1738
1739 /* Reset the positions */
1740 lttv_traceset_context_position_destroy(
1741 event_viewer_data->currently_selected_position);
1742 lttv_traceset_context_position_destroy(
1743 event_viewer_data->first_event);
1744 lttv_traceset_context_position_destroy(
1745 event_viewer_data->last_event);
1746
1747 event_viewer_data->currently_selected_position =
1748 lttv_traceset_context_position_new(tsc);
1749 event_viewer_data->first_event =
1750 lttv_traceset_context_position_new(tsc);
1751 event_viewer_data->last_event =
1752 lttv_traceset_context_position_new(tsc);
1753
1754 get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
1755 // event_viewer_data->vadjust_c->value = 0;
1756
1757 request_background_data(event_viewer_data);
1758
1759 return FALSE;
1760 }
1761
1762 gboolean filter_changed(void * hook_data, void * call_data)
1763 {
1764 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1765 LttvTracesetContext * tsc =
1766 lttvwindow_get_traceset_context(event_viewer_data->tab);
1767
1768 event_viewer_data->main_win_filter =
1769 (LttvFilter*)call_data;
1770 get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
1771
1772 return FALSE;
1773 }
1774
1775
1776 gint redraw_notify(void *hook_data, void *call_data)
1777 {
1778 EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
1779
1780 get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
1781 return 0;
1782 }
1783
1784 void gui_events_free(EventViewerData *event_viewer_data)
1785 {
1786 Tab *tab = event_viewer_data->tab;
1787 guint i;
1788
1789 if(event_viewer_data){
1790 lttv_hooks_remove(event_viewer_data->event_hooks,event_hook);
1791 lttv_hooks_destroy(event_viewer_data->event_hooks);
1792
1793 for(i=0;i<event_viewer_data->pos->len;i++) {
1794 LttvTracesetContextPosition *cur_pos =
1795 (LttvTracesetContextPosition*)g_ptr_array_index(event_viewer_data->pos,
1796 i);
1797 lttv_traceset_context_position_destroy(cur_pos);
1798 }
1799 lttv_traceset_context_position_destroy(
1800 event_viewer_data->currently_selected_position);
1801 lttv_traceset_context_position_destroy(
1802 event_viewer_data->first_event);
1803 lttv_traceset_context_position_destroy(
1804 event_viewer_data->last_event);
1805 g_ptr_array_free(event_viewer_data->pos, TRUE);
1806
1807 lttvwindow_unregister_current_time_notify(tab,
1808 update_current_time, event_viewer_data);
1809 lttvwindow_unregister_current_position_notify(tab,
1810 update_current_position, event_viewer_data);
1811 //lttvwindow_unregister_show_notify(tab,
1812 // show_event_detail, event_viewer_data);
1813 lttvwindow_unregister_traceset_notify(tab,
1814 traceset_changed, event_viewer_data);
1815 lttvwindow_unregister_filter_notify(tab,
1816 filter_changed, event_viewer_data);
1817 lttvwindow_unregister_redraw_notify(tab,
1818 redraw_notify, event_viewer_data);
1819
1820 lttvwindowtraces_background_notify_remove(event_viewer_data);
1821
1822 g_event_viewer_data_list = g_slist_remove(g_event_viewer_data_list,
1823 event_viewer_data);
1824 g_free(event_viewer_data);
1825 }
1826 }
1827
1828
1829
1830 void gui_events_destructor(EventViewerData *event_viewer_data)
1831 {
1832 /* May already been done by GTK window closing */
1833 if(GTK_IS_WIDGET(event_viewer_data->hbox_v)){
1834 gtk_widget_destroy(event_viewer_data->hbox_v);
1835 }
1836 }
1837
1838
1839
1840 /**
1841 * plugin's init function
1842 *
1843 * This function initializes the Event Viewer functionnality through the
1844 * gtkTraceSet API.
1845 */
1846 static void init() {
1847
1848 lttvwindow_register_constructor("guievents",
1849 "/",
1850 "Insert Event Viewer",
1851 hGuiEventsInsert_xpm,
1852 "Insert Event Viewer",
1853 h_gui_events);
1854 }
1855
1856 void event_destroy_walk(gpointer data, gpointer user_data)
1857 {
1858 gui_events_destructor((EventViewerData*)data);
1859 }
1860
1861 /**
1862 * plugin's destroy function
1863 *
1864 * This function releases the memory reserved by the module and unregisters
1865 * everything that has been registered in the gtkTraceSet API.
1866 */
1867 static void destroy() {
1868
1869 g_slist_foreach(g_event_viewer_data_list, event_destroy_walk, NULL );
1870 g_slist_free(g_event_viewer_data_list);
1871
1872 lttvwindow_unregister_constructor(h_gui_events);
1873
1874 }
1875
1876
1877
1878
1879 LTTV_MODULE("guievents", "Detailed events view", \
1880 "Graphical module to display a detailed event list", \
1881 init, destroy, "lttvwindow", "print")
This page took 0.070271 seconds and 4 git commands to generate.