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