1 /*! \defgroup guiEvents libguiEvents: The GUI Events display plugin */
5 * \brief Graphical plugin for showing events.
7 * This plugin lists all the events contained in the current time interval
10 * This plugin adds a Events Viewer functionnality to Linux TraceToolkit
11 * GUI when this plugin is loaded. The init and destroy functions add the
12 * viewer's insertion menu item and toolbar icon by calling gtkTraceSet's
13 * API functions. Then, when a viewer's object is created, the constructor
14 * creates ans register through API functions what is needed to interact
15 * with the TraceSet window.
17 * Author : Karim Yaghmour
18 * Integrated to LTTng by Mathieu Desnoyers, June 2003
26 #include <lttv/module.h>
28 #include "icons/guiEventsInsert.xpm"
30 /** Array containing instanced objects. Used when module is unloaded */
31 static GPtrArray
*RawTracesArray
= NULL
;
33 //! Event Viewer's constructor
34 GtkWidget
*guiEvents(GtkWidget
*ParentWindow
);
37 * plugin's init function
39 * This function initializes the Event Viewer functionnality through the
42 G_MODULE_EXPORT
void init() {
43 g_critical("GUI Event Viewer init()");
45 /* Register the toolbar insert button */
46 ToolbarItemReg(guiEventsInsert_xpm
, "Insert Event Viewer", guiEvent
);
48 /* Register the menu item insert entry */
49 MenuItemReg("/", "Insert Event Viewer", guiEvent
);
51 RawTracesArray
= g_ptr_array_new();
55 * plugin's destroy function
57 * This function releases the memory reserved by the module and unregisters
58 * everything that has been registered in the gtkTraceSet API.
60 G_MODULE_EXPORT
void destroy() {
63 g_critical("GUI Event Viewer destroy()");
65 for(i
=0 ; i
<RawTracesArray
->len
; i
++) {
66 gtk_widget_destroy((Widget
*)g_ptr_array_index(RawTracesArray
,i
));
69 g_ptr_array_free(RawTracesArray
);
71 /* Unregister the toolbar insert button */
72 ToolbarItemUnreg(guiEvent
);
74 /* Unregister the menu item insert entry */
75 MenuItemUnreg(guiEvents
);
79 * Event Viewer's constructor
81 * This constructor is given as a parameter to the menuitem and toolbar button
82 * registration. It creates the drawing widget.
83 * @param ParentWindow A pointer to the parent window.
84 * @return The widget created.
87 guiEvents(GtkWidget
*ParentWindow
)
91 /* Create raw trace list and pack it */
92 pWindow
->RTCList
= gtk_clist_new_with_titles(RTCLIST_NB_COLUMNS
, RTCListTitles
);
93 gtk_clist_set_selection_mode(GTK_CLIST(pWindow
->RTCList
), GTK_SELECTION_SINGLE
);
94 gtk_box_pack_start(GTK_BOX(pWindow
->RTHBox
), pWindow
->RTCList
, TRUE
, TRUE
, 0);
96 /* Create vertical scrollbar and pack it */
97 pWindow
->RTVScroll
= gtk_vscrollbar_new(NULL
);
98 gtk_box_pack_start(GTK_BOX(pWindow
->RTHBox
), pWindow
->RTVScroll
, FALSE
, TRUE
, 0);
100 /* Get the vertical scrollbar's adjustment */
101 pWindow
->RTVAdjust
= gtk_range_get_adjustment(GTK_RANGE(pWindow
->RTVScroll
));
103 /* Configure the columns of the list */
104 gtk_clist_set_column_justification(GTK_CLIST(pWindow
->RTCList
), 0, GTK_JUSTIFY_LEFT
);
105 gtk_clist_set_column_justification(GTK_CLIST(pWindow
->RTCList
), 1, GTK_JUSTIFY_LEFT
);
106 gtk_clist_set_column_justification(GTK_CLIST(pWindow
->RTCList
), 2, GTK_JUSTIFY_RIGHT
);
107 gtk_clist_set_column_justification(GTK_CLIST(pWindow
->RTCList
), 3, GTK_JUSTIFY_RIGHT
);
108 gtk_clist_set_column_justification(GTK_CLIST(pWindow
->RTCList
), 4, GTK_JUSTIFY_RIGHT
);
109 gtk_clist_set_column_justification(GTK_CLIST(pWindow
->RTCList
), 5, GTK_JUSTIFY_LEFT
);
110 gtk_clist_set_column_width(GTK_CLIST(pWindow
->RTCList
), 0, 45);
111 gtk_clist_set_column_width(GTK_CLIST(pWindow
->RTCList
), 1, 120);
112 gtk_clist_set_column_width(GTK_CLIST(pWindow
->RTCList
), 2, 120);
113 gtk_clist_set_column_width(GTK_CLIST(pWindow
->RTCList
), 3, 45);
114 gtk_clist_set_column_width(GTK_CLIST(pWindow
->RTCList
), 4, 60);
118 /* Raw event trace */
119 gtk_widget_show(pmWindow
->RTHBox
);
120 gtk_widget_show(pmWindow
->RTCList
);
121 gtk_widget_show(pmWindow
->RTVScroll
);
127 ~guiEvents(GtkWidget
*guiEvents
)
129 /* Clear raw event trace */
130 gtk_clist_clear(GTK_CLIST(pSysView
->Window
->RTCList
));
131 gtk_widget_queue_resize(pSysView
->Window
->RTCList
);
133 /* Reset the CList adjustment */
134 pSysView
->Window
->RTVAdjust
->lower
= 0;
135 pSysView
->Window
->RTVAdjust
->upper
= 0;
136 pSysView
->Window
->RTVAdjust
->step_increment
= 0;
137 pSysView
->Window
->RTVAdjust
->page_increment
= 0;
138 pSysView
->Window
->RTVAdjust
->page_size
= 0;
139 gtk_adjustment_changed(GTK_ADJUSTMENT(pSysView
->Window
->RTVAdjust
));
144 /* Imported code from LTT 0.9.6pre2 tracevisualizer */
147 /******************************************************************
149 * WDI_gtk_clist_set_last_row_data_full()
151 * Appends data to the last row of a GtkClist.
156 * J.H.D., 27/08/99, Initial typing.
158 * Based on gtk_clist_set_row_data_full() version 1.2.3.
159 * Much faster than using gtk_clist_set_row_data_full().
160 ******************************************************************/
161 void WDI_gtk_clist_set_last_row_data_full(GtkCList
* pmClist
,
163 GtkDestroyNotify pmDestroy
)
165 GtkCListRow
*pClistRow
;
167 g_return_if_fail (pmClist
!= NULL
);
168 g_return_if_fail (GTK_IS_CLIST (pmClist
));
169 g_return_if_fail (pmClist
->row_list_end
!= NULL
);
171 pClistRow
= pmClist
->row_list_end
->data
;
172 pClistRow
->data
= pmData
;
173 pClistRow
->destroy
= pmDestroy
;
177 /******************************************************************
185 ******************************************************************/
186 void SHRTEventSelect(GtkWidget
* pmCList
,
189 GdkEventButton
* pmEvent
,
192 systemView
* pSysView
; /* The system being displayed */
194 /* Do we have anything meaningfull */
195 if((pSysView
= (systemView
*) pmData
) == NULL
)
198 /* Store the selected event */
199 pSysView
->Window
->LastSelectedEvent
= *(event
*) gtk_clist_get_row_data(GTK_CLIST(pmCList
), pmRow
);
200 pSysView
->Window
->EventSelected
= TRUE
;
203 /******************************************************************
205 * SHRTEventButtonPress()
211 ******************************************************************/
212 void SHRTEventButtonPress(GtkWidget
* pmCList
,
213 GdkEventButton
* pmEvent
,
216 systemView
* pSysView
; /* The system being displayed */
217 gint row
, column
; /* The clicked row and column */
219 /* Do we have anything meaningfull */
220 if((pSysView
= (systemView
*) pmData
) == NULL
)
223 /* if we have a right-click event */
224 if(pmEvent
->button
== 3)
225 /* If we clicked on an item, get its row and column values */
226 if(gtk_clist_get_selection_info(GTK_CLIST(pmCList
), pmEvent
->x
, pmEvent
->y
, &row
, &column
))
228 /* Highlight the selected row */
229 gtk_clist_select_row(GTK_CLIST(pmCList
), row
, column
);
231 /* Store the selected event */
232 pSysView
->Window
->LastSelectedEvent
= *(event
*) gtk_clist_get_row_data(GTK_CLIST(pmCList
), row
);
233 pSysView
->Window
->EventSelected
= TRUE
;
235 /* Display the popup menu */
236 gtk_menu_popup(GTK_MENU(pSysView
->Window
->RawEventPopup
),
237 NULL
, NULL
, NULL
, NULL
,
238 pmEvent
->button
, GDK_CURRENT_TIME
);
243 /******************************************************************
245 * SHRTVAdjustValueChanged()
251 ******************************************************************/
252 void SHRTVAdjustValueChanged(GtkAdjustment
* pmVAdjust
,
255 event lEvent
; /* Event used for searching */
256 guint32 lPosition
; /* The position to scroll to */
257 systemView
* pSysView
; /* The system being displayed */
259 /* Do we have anything meaningfull */
260 if((pSysView
= (systemView
*) pmData
) == NULL
)
263 /* Is there an event database? */
264 if(pSysView
->EventDB
== NULL
)
267 /* Set the pointer to the first event */
268 if(pSysView
->EventDB
->TraceStart
== NULL
)
271 /* Are we closer to the beginning? */
272 if((pmVAdjust
->value
- (pmVAdjust
->upper
/ 2)) < 0)
274 /* Set the navigation pointer to the beginning of the list */
275 lEvent
= pSysView
->EventDB
->FirstEvent
;
277 /* Calculate distance from beginning */
278 lPosition
= (guint32
) pmVAdjust
->value
;
280 /* Find the event in the event database */
284 if(DBEventNext(pSysView
->EventDB
, &lEvent
) != TRUE
)
290 /* Set the navigation pointer to the end of the list */
291 lEvent
= pSysView
->EventDB
->LastEvent
;
293 /* Calculate distance from end */
294 lPosition
= (guint32
) (pmVAdjust
->upper
- pmVAdjust
->value
);
296 /* Find the event in the event database */
300 if(DBEventPrev(pSysView
->EventDB
, &lEvent
) != TRUE
)
305 /* Fill the event list according to what was found */
306 WDFillEventList(pSysView
->Window
->RTCList
,
310 &(pSysView
->Window
->LastSelectedEvent
));
315 /******************************************************************
319 * Attaches signal handlers to the window items.
321 * pmSysView, System view for which signals have to be connected
326 * This function attaches a pointer to the main window during
327 * the connect. This means that the handlers will get a pointer
328 * to the window in the data argument.
329 ******************************************************************/
330 void WDConnectSignals(systemView
* pmSysView
)
332 /* Raw event Popup menu */
333 gtk_signal_connect(GTK_OBJECT(pmSysView
->Window
->RawGotoProcess
),
335 GTK_SIGNAL_FUNC(SHGotoProcAnalysis
),
337 gtk_signal_connect(GTK_OBJECT(pmSysView
->Window
->RawViewEvent
),
339 GTK_SIGNAL_FUNC(SHViewEventInEG
),
342 /* Set event list callbacks */
343 gtk_signal_connect(GTK_OBJECT(pmSysView
->Window
->RTCList
),
345 GTK_SIGNAL_FUNC(SHRTEventSelect
),
347 gtk_signal_connect(GTK_OBJECT(pmSysView
->Window
->RTCList
),
348 "button-press-event",
349 GTK_SIGNAL_FUNC(SHRTEventButtonPress
),
351 gtk_signal_connect(GTK_OBJECT(pmSysView
->Window
->RTVAdjust
),
353 GTK_SIGNAL_FUNC(SHRTVAdjustValueChanged
),
360 /******************************************************************
364 * Fills the window's event list using the trace database.
366 * pmList, The list to be filled.
367 * pmTraceDB, The database of events.
368 * pmSystem, The system to which this list belongs.
369 * pmEvent, Event from which we start drawing.
370 * pmSelectedEvent, Event selected if any.
374 * K.Y., 18/06/99, Initial typing.
376 ******************************************************************/
377 void WDFillEventList(GtkWidget
* pmList
,
379 systemInfo
* pmSystem
,
381 event
* pmSelectedEvent
)
383 gint i
= 0; /* Generic index */
384 event lEvent
; /* Generic event */
385 gchar lTimeStr
[TIME_STR_LEN
]; /* Time of event */
386 static gchar
* lString
[RTCLIST_NB_COLUMNS
]={'\0'}; /* Strings describing event */
387 process
* pProcess
; /* Generic process pointer */
389 RTAItask
* pTask
= NULL
; /* Generic task pointer */
390 #endif /* SUPP_RTAI */
391 eventDescription lEventDesc
; /* Description of event */
393 /* Did we allocate space for strings */
394 if(lString
[0] == NULL
)
395 /* Allocate space for strings */
396 for (i
= 0; i
< RTCLIST_NB_COLUMNS
- 1; i
++)
397 lString
[i
] = (char*) g_malloc(MW_DEFAULT_STRLEN
);
399 /* Allocate space for description string */
400 lString
[RTCLIST_NB_COLUMNS
- 1] = (char*) g_malloc(MW_LONG_STRLEN
);
402 /* If no event was supplied, start at the beginning */
404 lEvent
= pmTraceDB
->FirstEvent
;
408 /* Freeze and clear clist */
409 gtk_clist_freeze(GTK_CLIST(pmList
));
410 gtk_clist_clear(GTK_CLIST(pmList
));
415 /* Go through the event list */
418 /* Get the event description */
419 DBEventDescription(pmTraceDB
, &lEvent
, TRUE
, &lEventDesc
);
421 /* Get the event's process */
422 pProcess
= DBEventProcess(pmTraceDB
, &lEvent
, pmSystem
, FALSE
);
425 /* Does this trace contain RTAI information */
426 if(pmTraceDB
->SystemType
== TRACE_SYS_TYPE_RTAI_LINUX
)
427 /* Get the RTAI task to which this event belongs */
428 pTask
= RTAIDBEventTask(pmTraceDB
, &lEvent
, pmSystem
, FALSE
);
429 #endif /* SUPP_RTAI */
431 /* Set the event's entry in the list of raw events displayed */
432 sRawEventsDisplayed
[i
] = lEvent
;
434 /* Add text describing the event */
436 if(pmTraceDB
->LogCPUID
== TRUE
)
437 snprintf(lString
[0], MW_DEFAULT_STRLEN
, "%d", lEventDesc
.CPUID
);
439 snprintf(lString
[0], MW_DEFAULT_STRLEN
, "0");
442 snprintf(lString
[1], MW_DEFAULT_STRLEN
, "%s", pmTraceDB
->EventString(pmTraceDB
, lEventDesc
.ID
, &lEvent
));
444 /* The event's time of occurence */
445 DBFormatTimeInReadableString(lTimeStr
,
446 lEventDesc
.Time
.tv_sec
,
447 lEventDesc
.Time
.tv_usec
);
448 snprintf(lString
[2], MW_DEFAULT_STRLEN
, "%s", lTimeStr
);
450 /* Is this an RT event */
451 if(lEventDesc
.ID
<= TRACE_MAX
)
453 /* The PID of the process to which the event belongs */
455 snprintf(lString
[3], MW_DEFAULT_STRLEN
, "%d", pProcess
->PID
);
457 snprintf(lString
[3], MW_DEFAULT_STRLEN
, "N/A");
462 /* The TID of the task to which the event belongs */
464 snprintf(lString
[3], MW_DEFAULT_STRLEN
, "RT:%d", pTask
->TID
);
466 snprintf(lString
[3], MW_DEFAULT_STRLEN
, "RT:N/A");
468 #endif /* SUPP_RTAI */
470 /* The size of the entry */
471 snprintf(lString
[4], MW_DEFAULT_STRLEN
, "%d", lEventDesc
.Size
);
473 /* The string describing the event */
474 snprintf(lString
[5], MW_LONG_STRLEN
, "%s", lEventDesc
.String
);
476 /* Insert the entry into the list */
477 gtk_clist_append(GTK_CLIST(pmList
), lString
);
479 /* Set the row's data to point to the current event */
480 WDI_gtk_clist_set_last_row_data_full(GTK_CLIST(pmList
), (gpointer
) &(sRawEventsDisplayed
[i
]), NULL
);
482 /* Was this the last selected event */
483 if(DBEventsEqual(lEvent
, (*pmSelectedEvent
)))
484 gtk_clist_select_row(GTK_CLIST(pmList
), i
, 0);
488 } while((DBEventNext(pmTraceDB
, &lEvent
) == TRUE
) && (i
< RTCLIST_NB_ROWS
));
490 /* Resize the list's length */
491 gtk_widget_queue_resize(pmList
);
494 gtk_clist_thaw(GTK_CLIST(pmList
));