new version of the reading API
[lttv.git] / ltt / branches / poly / lttv / modules / guiEvents.c
CommitLineData
5c7463ed 1/*! \defgroup guiEvents libguiEvents: The GUI Events display plugin */
2/*\@{*/
3
4/*! \file guiEvents.c
5 * \brief Graphical plugin for showing events.
6 *
17abcce3 7 * This plugin lists all the events contained in the current time interval
8 * in a list.
9 *
5c7463ed 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.
16 *
fcdf0ec2 17 * Author : Karim Yaghmour
18 * Integrated to LTTng by Mathieu Desnoyers, June 2003
5c7463ed 19 */
20
21#include <glib.h>
22#include <gmodule.h>
23#include <gtk.h>
24#include <gdk.h>
25
26#include <lttv/module.h>
27
5c7463ed 28#include "icons/guiEventsInsert.xpm"
29
fcdf0ec2 30/** Array containing instanced objects. Used when module is unloaded */
31static GPtrArray *RawTracesArray = NULL;
32
5c7463ed 33//! Event Viewer's constructor
34GtkWidget *guiEvents(GtkWidget *ParentWindow);
35
5c7463ed 36/**
37 * plugin's init function
38 *
39 * This function initializes the Event Viewer functionnality through the
40 * gtkTraceSet API.
41 */
42G_MODULE_EXPORT void init() {
43 g_critical("GUI Event Viewer init()");
44
45 /* Register the toolbar insert button */
46 ToolbarItemReg(guiEventsInsert_xpm, "Insert Event Viewer", guiEvent);
47
48 /* Register the menu item insert entry */
49 MenuItemReg("/", "Insert Event Viewer", guiEvent);
50
fcdf0ec2 51 RawTracesArray = g_ptr_array_new();
5c7463ed 52}
53
54/**
55 * plugin's destroy function
56 *
57 * This function releases the memory reserved by the module and unregisters
58 * everything that has been registered in the gtkTraceSet API.
59 */
60G_MODULE_EXPORT void destroy() {
fcdf0ec2 61 int i;
62
5c7463ed 63 g_critical("GUI Event Viewer destroy()");
64
fcdf0ec2 65 for(i=0 ; i<RawTracesArray->len ; i++) {
66 gtk_widget_destroy((Widget *)g_ptr_array_index(RawTracesArray,i));
67 }
68
69 g_ptr_array_free(RawTracesArray);
70
5c7463ed 71 /* Unregister the toolbar insert button */
72 ToolbarItemUnreg(guiEvent);
73
74 /* Unregister the menu item insert entry */
75 MenuItemUnreg(guiEvents);
76}
77
78/**
79 * Event Viewer's constructor
80 *
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.
85 */
86static GtkWidget *
87guiEvents(GtkWidget *ParentWindow)
5c7463ed 88{
fcdf0ec2 89
90
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);
95
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);
99
100 /* Get the vertical scrollbar's adjustment */
101 pWindow->RTVAdjust = gtk_range_get_adjustment(GTK_RANGE(pWindow->RTVScroll));
102
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);
115
116
117
118 /* Raw event trace */
119 gtk_widget_show(pmWindow->RTHBox);
120 gtk_widget_show(pmWindow->RTCList);
121 gtk_widget_show(pmWindow->RTVScroll);
122
123
124}
125
126static GtkWidget
127~guiEvents(GtkWidget *guiEvents)
128{
129 /* Clear raw event trace */
130 gtk_clist_clear(GTK_CLIST(pSysView->Window->RTCList));
131 gtk_widget_queue_resize(pSysView->Window->RTCList);
132
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));
140
141}
142
143
144/* Imported code from LTT 0.9.6pre2 tracevisualizer */
145
146
147/******************************************************************
148 * Function :
149 * WDI_gtk_clist_set_last_row_data_full()
150 * Description :
151 * Appends data to the last row of a GtkClist.
152 * Parameters :
153 * Return values :
154 * NONE.
155 * History :
156 * J.H.D., 27/08/99, Initial typing.
157 * Note :
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 ******************************************************************/
161void WDI_gtk_clist_set_last_row_data_full(GtkCList* pmClist,
162 gpointer pmData,
163 GtkDestroyNotify pmDestroy)
164{
165 GtkCListRow *pClistRow;
5c7463ed 166
fcdf0ec2 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);
5c7463ed 170
fcdf0ec2 171 pClistRow = pmClist->row_list_end->data;
172 pClistRow->data = pmData;
173 pClistRow->destroy = pmDestroy;
5c7463ed 174}
175
176
fcdf0ec2 177/******************************************************************
178 * Function :
179 * SHRTEventSelect()
180 * Description :
181 * Parameters :
182 * Return values :
183 * History :
184 * Note :
185 ******************************************************************/
186void SHRTEventSelect(GtkWidget* pmCList,
187 gint pmRow,
188 gint pmColumn,
189 GdkEventButton* pmEvent,
190 gpointer pmData)
191{
192 systemView* pSysView; /* The system being displayed */
193
194 /* Do we have anything meaningfull */
195 if((pSysView = (systemView*) pmData) == NULL)
196 return;
197
198 /* Store the selected event */
199 pSysView->Window->LastSelectedEvent = *(event*) gtk_clist_get_row_data(GTK_CLIST(pmCList), pmRow);
200 pSysView->Window->EventSelected = TRUE;
201}
202
203/******************************************************************
204 * Function :
205 * SHRTEventButtonPress()
206 * Description :
207 * Parameters :
208 * Return values :
209 * History :
210 * Note :
211 ******************************************************************/
212void SHRTEventButtonPress(GtkWidget* pmCList,
213 GdkEventButton* pmEvent,
214 gpointer pmData)
215{
216 systemView* pSysView; /* The system being displayed */
217 gint row, column; /* The clicked row and column */
218
219 /* Do we have anything meaningfull */
220 if((pSysView = (systemView*) pmData) == NULL)
221 return;
222
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))
227 {
228 /* Highlight the selected row */
229 gtk_clist_select_row(GTK_CLIST(pmCList), row, column);
230
231 /* Store the selected event */
232 pSysView->Window->LastSelectedEvent = *(event*) gtk_clist_get_row_data(GTK_CLIST(pmCList), row);
233 pSysView->Window->EventSelected = TRUE;
234
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);
239 }
240}
241
242
243/******************************************************************
244 * Function :
245 * SHRTVAdjustValueChanged()
246 * Description :
247 * Parameters :
248 * Return values :
249 * History :
250 * Note :
251 ******************************************************************/
252void SHRTVAdjustValueChanged(GtkAdjustment* pmVAdjust,
253 gpointer pmData)
254{
255 event lEvent; /* Event used for searching */
256 guint32 lPosition; /* The position to scroll to */
257 systemView* pSysView; /* The system being displayed */
258
259 /* Do we have anything meaningfull */
260 if((pSysView = (systemView*) pmData) == NULL)
261 return;
262
263 /* Is there an event database? */
264 if(pSysView->EventDB == NULL)
265 return;
266
267 /* Set the pointer to the first event */
268 if(pSysView->EventDB->TraceStart == NULL)
269 return;
270
271 /* Are we closer to the beginning? */
272 if((pmVAdjust->value - (pmVAdjust->upper / 2)) < 0)
273 {
274 /* Set the navigation pointer to the beginning of the list */
275 lEvent = pSysView->EventDB->FirstEvent;
276
277 /* Calculate distance from beginning */
278 lPosition = (guint32) pmVAdjust->value;
279
280 /* Find the event in the event database */
281 while(lPosition > 0)
282 {
283 lPosition--;
284 if(DBEventNext(pSysView->EventDB, &lEvent) != TRUE)
285 break;
286 }
287 }
288 else
289 {
290 /* Set the navigation pointer to the end of the list */
291 lEvent = pSysView->EventDB->LastEvent;
292
293 /* Calculate distance from end */
294 lPosition = (guint32) (pmVAdjust->upper - pmVAdjust->value);
295
296 /* Find the event in the event database */
297 while(lPosition > 0)
298 {
299 lPosition--;
300 if(DBEventPrev(pSysView->EventDB, &lEvent) != TRUE)
301 break;
302 }
303 }
304
305 /* Fill the event list according to what was found */
306 WDFillEventList(pSysView->Window->RTCList,
307 pSysView->EventDB,
308 pSysView->System,
309 &lEvent,
310 &(pSysView->Window->LastSelectedEvent));
311}
312
313
314
315/******************************************************************
316 * Function :
317 * WDConnectSignals()
318 * Description :
319 * Attaches signal handlers to the window items.
320 * Parameters :
321 * pmSysView, System view for which signals have to be connected
322 * Return values :
323 * NONE
324 * History :
325 * Note :
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 ******************************************************************/
330void WDConnectSignals(systemView* pmSysView)
331{
332 /* Raw event Popup menu */
333 gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RawGotoProcess),
334 "activate",
335 GTK_SIGNAL_FUNC(SHGotoProcAnalysis),
336 pmSysView);
337 gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RawViewEvent),
338 "activate",
339 GTK_SIGNAL_FUNC(SHViewEventInEG),
340 pmSysView);
341
342 /* Set event list callbacks */
343 gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RTCList),
344 "select_row",
345 GTK_SIGNAL_FUNC(SHRTEventSelect),
346 pmSysView);
347 gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RTCList),
348 "button-press-event",
349 GTK_SIGNAL_FUNC(SHRTEventButtonPress),
350 pmSysView);
351 gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RTVAdjust),
352 "value-changed",
353 GTK_SIGNAL_FUNC(SHRTVAdjustValueChanged),
354 pmSysView);
355
356
357}
358
359
360/******************************************************************
361 * Function :
362 * WDFillEventList()
363 * Description :
364 * Fills the window's event list using the trace database.
365 * Parameters :
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.
371 * Return values :
372 * NONE.
373 * History :
374 * K.Y., 18/06/99, Initial typing.
375 * Note :
376 ******************************************************************/
377void WDFillEventList(GtkWidget* pmList,
378 db* pmTraceDB,
379 systemInfo* pmSystem,
380 event* pmEvent,
381 event* pmSelectedEvent)
382{
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 */
388#if SUPP_RTAI
389 RTAItask* pTask = NULL; /* Generic task pointer */
390#endif /* SUPP_RTAI */
391 eventDescription lEventDesc; /* Description of event */
392
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);
398
399 /* Allocate space for description string */
400 lString[RTCLIST_NB_COLUMNS - 1] = (char*) g_malloc(MW_LONG_STRLEN);
401
402 /* If no event was supplied, start at the beginning */
403 if(pmEvent == NULL)
404 lEvent = pmTraceDB->FirstEvent;
405 else
406 lEvent = *pmEvent;
407
408 /* Freeze and clear clist */
409 gtk_clist_freeze(GTK_CLIST(pmList));
410 gtk_clist_clear(GTK_CLIST(pmList));
411
412 /* Reset index */
413 i = 0;
414
415 /* Go through the event list */
416 do
417 {
418 /* Get the event description */
419 DBEventDescription(pmTraceDB, &lEvent, TRUE, &lEventDesc);
420
421 /* Get the event's process */
422 pProcess = DBEventProcess(pmTraceDB, &lEvent, pmSystem, FALSE);
423
424#if SUPP_RTAI
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 */
430
431 /* Set the event's entry in the list of raw events displayed */
432 sRawEventsDisplayed[i] = lEvent;
433
434 /* Add text describing the event */
435 /* The CPU ID */
436 if(pmTraceDB->LogCPUID == TRUE)
437 snprintf(lString[0], MW_DEFAULT_STRLEN, "%d", lEventDesc.CPUID);
438 else
439 snprintf(lString[0], MW_DEFAULT_STRLEN, "0");
440
441 /* The event ID */
442 snprintf(lString[1], MW_DEFAULT_STRLEN, "%s", pmTraceDB->EventString(pmTraceDB, lEventDesc.ID, &lEvent));
443
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);
449
450 /* Is this an RT event */
451 if(lEventDesc.ID <= TRACE_MAX)
452 {
453 /* The PID of the process to which the event belongs */
454 if(pProcess != NULL)
455 snprintf(lString[3], MW_DEFAULT_STRLEN, "%d", pProcess->PID);
456 else
457 snprintf(lString[3], MW_DEFAULT_STRLEN, "N/A");
458 }
459#if SUPP_RTAI
460 else
461 {
462 /* The TID of the task to which the event belongs */
463 if(pTask != NULL)
464 snprintf(lString[3], MW_DEFAULT_STRLEN, "RT:%d", pTask->TID);
465 else
466 snprintf(lString[3], MW_DEFAULT_STRLEN, "RT:N/A");
467 }
468#endif /* SUPP_RTAI */
469
470 /* The size of the entry */
471 snprintf(lString[4], MW_DEFAULT_STRLEN, "%d", lEventDesc.Size);
472
473 /* The string describing the event */
474 snprintf(lString[5], MW_LONG_STRLEN, "%s", lEventDesc.String);
475
476 /* Insert the entry into the list */
477 gtk_clist_append(GTK_CLIST(pmList), lString);
478
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);
481
482 /* Was this the last selected event */
483 if(DBEventsEqual(lEvent, (*pmSelectedEvent)))
484 gtk_clist_select_row(GTK_CLIST(pmList), i, 0);
485
486 /* Go to next row */
487 i++;
488 } while((DBEventNext(pmTraceDB, &lEvent) == TRUE) && (i < RTCLIST_NB_ROWS));
489
490 /* Resize the list's length */
491 gtk_widget_queue_resize(pmList);
492
493 /* Thaw the clist */
494 gtk_clist_thaw(GTK_CLIST(pmList));
495}
496
497
498
17abcce3 499
5c7463ed 500/*\@}*/
This page took 0.041792 seconds and 4 git commands to generate.