fbbb2697 |
1 | //*! \defgroup GuiEvents libGuiEvents: The GUI Events display plugin */ |
5c7463ed |
2 | /*\@{*/ |
3 | |
fbbb2697 |
4 | /*! \file GuiEvents.c |
5c7463ed |
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 | * |
fbbb2697 |
17 | * Coding standard : |
18 | * pm : parameter |
19 | * l : local |
20 | * g : global |
21 | * s : static |
22 | * h : hook |
23 | * |
fcdf0ec2 |
24 | * Author : Karim Yaghmour |
25 | * Integrated to LTTng by Mathieu Desnoyers, June 2003 |
5c7463ed |
26 | */ |
27 | |
28 | #include <glib.h> |
29 | #include <gmodule.h> |
fbbb2697 |
30 | #include <gtk/gtk.h> |
31 | #include <gdk/gdk.h> |
5c7463ed |
32 | |
33 | #include <lttv/module.h> |
fbbb2697 |
34 | //#include <lttv/gtkTraceSet.h> |
35 | #include "mw_api.h" |
5c7463ed |
36 | |
fbbb2697 |
37 | #include "icons/hGuiEventsInsert.xpm" |
5c7463ed |
38 | |
fcdf0ec2 |
39 | /** Array containing instanced objects. Used when module is unloaded */ |
fbbb2697 |
40 | static GSList *sEvent_Viewer_Data_List = NULL ; |
41 | |
42 | typedef struct _EventViewerData { |
43 | |
44 | /* Model containing list data */ |
45 | GtkListStore *Store_M; |
46 | |
47 | GtkWidget *HBox_V; |
48 | /* Widget to display the data in a columned list */ |
49 | GtkWidget *Tree_V; |
50 | GtkAdjustment *VTree_Adjust_C ; |
51 | GdkWindow *TreeWindow ; |
52 | |
53 | /* Vertical scrollbar and it's adjustment */ |
54 | GtkWidget *VScroll_VC; |
55 | GtkAdjustment *VAdjust_C ; |
56 | |
57 | /* Selection handler */ |
58 | GtkTreeSelection *Select_C; |
59 | |
60 | guint Visible_Events; |
fcdf0ec2 |
61 | |
fbbb2697 |
62 | } EventViewerData ; |
63 | |
64 | //! Event Viewer's constructor hook |
65 | GtkWidget *hGuiEvents(GtkWidget *pmParentWindow); |
5c7463ed |
66 | //! Event Viewer's constructor |
fbbb2697 |
67 | EventViewerData *GuiEvents(void); |
68 | //! Event Viewer's destructor |
69 | void GuiEvents_Destructor(EventViewerData *Event_Viewer_Data); |
70 | |
71 | /* Prototype for selection handler callback */ |
72 | static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data); |
73 | static void v_scroll_cb (GtkAdjustment *adjustment, gpointer data); |
74 | static void Tree_V_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data); |
75 | static void Tree_V_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data); |
76 | |
77 | |
78 | void add_test_data(EventViewerData *Event_Viewer_Data); |
79 | |
80 | /* TEST DATA, TO BE READ FROM THE TRACE */ |
81 | static int Number_Of_Events = 1000; |
82 | |
83 | //FIXME: use the size of the widget to get number of rows. |
84 | static int Number_Of_Rows = 50 ; |
85 | //FIXME |
86 | static int Cell_Height = 52; |
5c7463ed |
87 | |
5c7463ed |
88 | /** |
89 | * plugin's init function |
90 | * |
91 | * This function initializes the Event Viewer functionnality through the |
92 | * gtkTraceSet API. |
93 | */ |
94 | G_MODULE_EXPORT void init() { |
95 | g_critical("GUI Event Viewer init()"); |
96 | |
97 | /* Register the toolbar insert button */ |
fbbb2697 |
98 | //ToolbarItemReg(hGuiEventsInsert_xpm, "Insert Event Viewer", hGuiEvents); |
5c7463ed |
99 | |
100 | /* Register the menu item insert entry */ |
fbbb2697 |
101 | //MenuItemReg("/", "Insert Event Viewer", hGuiEvents); |
102 | } |
5c7463ed |
103 | |
fbbb2697 |
104 | void destroy_walk(gpointer data, gpointer user_data) |
105 | { |
106 | GuiEvents_Destructor((EventViewerData*)data); |
5c7463ed |
107 | } |
108 | |
109 | /** |
110 | * plugin's destroy function |
111 | * |
112 | * This function releases the memory reserved by the module and unregisters |
113 | * everything that has been registered in the gtkTraceSet API. |
114 | */ |
115 | G_MODULE_EXPORT void destroy() { |
fcdf0ec2 |
116 | int i; |
fbbb2697 |
117 | |
118 | EventViewerData *Event_Viewer_Data; |
fcdf0ec2 |
119 | |
5c7463ed |
120 | g_critical("GUI Event Viewer destroy()"); |
121 | |
fbbb2697 |
122 | g_slist_foreach(sEvent_Viewer_Data_List, destroy_walk, NULL ); |
fcdf0ec2 |
123 | |
5c7463ed |
124 | /* Unregister the toolbar insert button */ |
fbbb2697 |
125 | //ToolbarItemUnreg(hGuiEvents); |
5c7463ed |
126 | |
127 | /* Unregister the menu item insert entry */ |
fbbb2697 |
128 | //MenuItemUnreg(hGuiEvents); |
5c7463ed |
129 | } |
130 | |
fbbb2697 |
131 | /* Enumeration of the columns */ |
132 | enum |
133 | { |
134 | CPUID_COLUMN, |
135 | EVENT_COLUMN, |
136 | TIME_COLUMN, |
137 | PID_COLUMN, |
138 | ENTRY_LEN_COLUMN, |
139 | EVENT_DESCR_COLUMN, |
140 | N_COLUMNS |
141 | }; |
142 | |
143 | |
5c7463ed |
144 | /** |
fbbb2697 |
145 | * Event Viewer's constructor hook |
5c7463ed |
146 | * |
147 | * This constructor is given as a parameter to the menuitem and toolbar button |
fbbb2697 |
148 | * registration. It creates the list. |
149 | * @param pmParentWindow A pointer to the parent window. |
5c7463ed |
150 | * @return The widget created. |
151 | */ |
fbbb2697 |
152 | GtkWidget * |
153 | hGuiEvents(GtkWidget *pmParentWindow) |
154 | { |
155 | EventViewerData* Event_Viewer_Data = GuiEvents() ; |
156 | |
157 | return Event_Viewer_Data->HBox_V ; |
158 | |
159 | } |
160 | |
161 | /** |
162 | * Event Viewer's constructor |
163 | * |
164 | * This constructor is used to create EventViewerData data structure. |
165 | * @return The Event viewer data created. |
166 | */ |
167 | EventViewerData * |
168 | GuiEvents(void) |
5c7463ed |
169 | { |
fbbb2697 |
170 | GtkTreeViewColumn *column; |
171 | GtkCellRenderer *renderer; |
172 | EventViewerData* Event_Viewer_Data = g_new(EventViewerData,1) ; |
173 | gint width, height; |
174 | /* Create a model for storing the data list */ |
175 | Event_Viewer_Data->Store_M = gtk_list_store_new (N_COLUMNS, /* Total number of columns */ |
176 | G_TYPE_INT, /* CPUID */ |
177 | G_TYPE_STRING, /* Event */ |
178 | G_TYPE_INT, /* Time */ |
179 | G_TYPE_INT, /* PID */ |
180 | G_TYPE_INT, /* Entry length */ |
181 | G_TYPE_STRING); /* Event's description */ |
182 | |
183 | /* Create the viewer widget for the columned list */ |
184 | Event_Viewer_Data->Tree_V = gtk_tree_view_new_with_model (GTK_TREE_MODEL (Event_Viewer_Data->Store_M)); |
185 | |
186 | g_signal_connect (G_OBJECT (Event_Viewer_Data->Tree_V), "size-allocate", |
187 | G_CALLBACK (Tree_V_size_allocate_cb), |
188 | Event_Viewer_Data); |
189 | g_signal_connect (G_OBJECT (Event_Viewer_Data->Tree_V), "size-request", |
190 | G_CALLBACK (Tree_V_size_request_cb), |
191 | Event_Viewer_Data); |
192 | |
193 | |
194 | // Use on each column! |
195 | //gtk_tree_view_column_set_sizing(Event_Viewer_Data->Tree_V, GTK_TREE_VIEW_COLUMN_FIXED); |
196 | |
197 | /* The view now holds a reference. We can get rid of our own |
198 | * reference */ |
199 | g_object_unref (G_OBJECT (Event_Viewer_Data->Store_M)); |
fcdf0ec2 |
200 | |
201 | |
fbbb2697 |
202 | /* Create a column, associating the "text" attribute of the |
203 | * cell_renderer to the first column of the model */ |
204 | /* Columns alignment : 0.0 : Left 0.5 : Center 1.0 : Right */ |
205 | renderer = gtk_cell_renderer_text_new (); |
206 | column = gtk_tree_view_column_new_with_attributes ("CPUID", |
207 | renderer, |
208 | "text", CPUID_COLUMN, |
209 | NULL); |
210 | gtk_tree_view_column_set_alignment (column, 0.0); |
211 | gtk_tree_view_column_set_fixed_width (column, 45); |
212 | gtk_tree_view_append_column (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V), column); |
213 | |
214 | renderer = gtk_cell_renderer_text_new (); |
215 | column = gtk_tree_view_column_new_with_attributes ("Event", |
216 | renderer, |
217 | "text", EVENT_COLUMN, |
218 | NULL); |
219 | gtk_tree_view_column_set_alignment (column, 0.0); |
220 | gtk_tree_view_column_set_fixed_width (column, 120); |
221 | gtk_tree_view_append_column (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V), column); |
222 | |
223 | renderer = gtk_cell_renderer_text_new (); |
224 | column = gtk_tree_view_column_new_with_attributes ("Time", |
225 | renderer, |
226 | "text", TIME_COLUMN, |
227 | NULL); |
228 | gtk_tree_view_column_set_alignment (column, 1.0); |
229 | gtk_tree_view_column_set_fixed_width (column, 120); |
230 | gtk_tree_view_append_column (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V), column); |
231 | |
232 | renderer = gtk_cell_renderer_text_new (); |
233 | column = gtk_tree_view_column_new_with_attributes ("PID", |
234 | renderer, |
235 | "text", PID_COLUMN, |
236 | NULL); |
237 | gtk_tree_view_column_set_alignment (column, 1.0); |
238 | gtk_tree_view_column_set_fixed_width (column, 45); |
239 | gtk_tree_view_append_column (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V), column); |
240 | |
241 | renderer = gtk_cell_renderer_text_new (); |
242 | column = gtk_tree_view_column_new_with_attributes ("Entry Length", |
243 | renderer, |
244 | "text", ENTRY_LEN_COLUMN, |
245 | NULL); |
246 | gtk_tree_view_column_set_alignment (column, 1.0); |
247 | gtk_tree_view_column_set_fixed_width (column, 60); |
248 | gtk_tree_view_append_column (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V), column); |
249 | |
250 | renderer = gtk_cell_renderer_text_new (); |
251 | column = gtk_tree_view_column_new_with_attributes ("Event's Description", |
252 | renderer, |
253 | "text", EVENT_DESCR_COLUMN, |
254 | NULL); |
255 | gtk_tree_view_column_set_alignment (column, 0.0); |
256 | gtk_tree_view_append_column (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V), column); |
257 | |
258 | |
259 | gtk_cell_renderer_get_size(renderer, GTK_WIDGET(Event_Viewer_Data->Tree_V), NULL, NULL, NULL, &width, &height); |
260 | g_critical("first size h : %i",height); |
261 | /* Setup the selection handler */ |
262 | Event_Viewer_Data->Select_C = gtk_tree_view_get_selection (GTK_TREE_VIEW (Event_Viewer_Data->Tree_V)); |
263 | gtk_tree_selection_set_mode (Event_Viewer_Data->Select_C, GTK_SELECTION_SINGLE); |
264 | g_signal_connect (G_OBJECT (Event_Viewer_Data->Select_C), "changed", |
265 | G_CALLBACK (tree_selection_changed_cb), |
266 | NULL); |
267 | |
268 | Event_Viewer_Data->HBox_V = gtk_hbox_new(0, 0); |
269 | gtk_box_pack_start(GTK_BOX(Event_Viewer_Data->HBox_V), Event_Viewer_Data->Tree_V, TRUE, TRUE, 0); |
fcdf0ec2 |
270 | |
271 | /* Create vertical scrollbar and pack it */ |
fbbb2697 |
272 | Event_Viewer_Data->VScroll_VC = gtk_vscrollbar_new(NULL); |
273 | gtk_box_pack_start(GTK_BOX(Event_Viewer_Data->HBox_V), Event_Viewer_Data->VScroll_VC, FALSE, TRUE, 0); |
274 | |
fcdf0ec2 |
275 | /* Get the vertical scrollbar's adjustment */ |
fbbb2697 |
276 | Event_Viewer_Data->VAdjust_C = gtk_range_get_adjustment(GTK_RANGE(Event_Viewer_Data->VScroll_VC)); |
277 | Event_Viewer_Data->VTree_Adjust_C = gtk_tree_view_get_vadjustment( |
278 | GTK_TREE_VIEW (Event_Viewer_Data->Tree_V)); |
279 | |
280 | g_signal_connect (G_OBJECT (Event_Viewer_Data->VAdjust_C), "value-changed", |
281 | G_CALLBACK (v_scroll_cb), |
282 | Event_Viewer_Data); |
283 | /* Set the upper bound to the last event number */ |
284 | Event_Viewer_Data->VAdjust_C->lower = 0; |
285 | Event_Viewer_Data->VAdjust_C->upper = Number_Of_Events; |
286 | Event_Viewer_Data->VAdjust_C->value = 0; |
287 | Event_Viewer_Data->VAdjust_C->step_increment = 1; |
288 | Event_Viewer_Data->VAdjust_C->page_increment = |
289 | Event_Viewer_Data->VTree_Adjust_C->upper; |
290 | //FIXME change page size dynamically to fit event list size |
291 | Event_Viewer_Data->VAdjust_C->page_size = |
292 | Event_Viewer_Data->VTree_Adjust_C->upper; |
293 | g_critical("value : %u",Event_Viewer_Data->VTree_Adjust_C->upper); |
294 | /* Raw event trace */ |
295 | gtk_widget_show(Event_Viewer_Data->HBox_V); |
296 | gtk_widget_show(Event_Viewer_Data->Tree_V); |
297 | gtk_widget_show(Event_Viewer_Data->VScroll_VC); |
298 | |
299 | /* Add the object's information to the module's array */ |
300 | g_slist_append(sEvent_Viewer_Data_List, Event_Viewer_Data); |
301 | |
302 | /* Test data */ |
303 | add_test_data(Event_Viewer_Data); |
304 | |
305 | return Event_Viewer_Data; |
306 | } |
fcdf0ec2 |
307 | |
fbbb2697 |
308 | void v_scroll_cb (GtkAdjustment *adjustment, gpointer data) |
309 | { |
310 | g_critical("DEBUG : scroll signal"); |
311 | |
312 | } |
fcdf0ec2 |
313 | |
fbbb2697 |
314 | void Tree_V_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data) |
315 | { |
316 | EventViewerData *Event_Viewer_Data = (EventViewerData*)data; |
fcdf0ec2 |
317 | |
fbbb2697 |
318 | g_critical("size-allocate"); |
fcdf0ec2 |
319 | |
fbbb2697 |
320 | Event_Viewer_Data->Visible_Events = alloc->y ; |
321 | g_critical("num of event shown : %u",Event_Viewer_Data->Visible_Events); |
322 | |
323 | |
324 | } |
325 | |
326 | void Tree_V_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data) |
327 | { |
328 | gint w, h; |
329 | gint height, width; |
fcdf0ec2 |
330 | |
fbbb2697 |
331 | EventViewerData *Event_Viewer_Data = (EventViewerData*)data; |
332 | GtkTreeViewColumn *Column = gtk_tree_view_get_column(GTK_TREE_VIEW(Event_Viewer_Data->Tree_V), 1); |
333 | GList *Render_List = gtk_tree_view_column_get_cell_renderers(Column); |
334 | GtkCellRenderer *Renderer = g_list_first(Render_List)->data; |
335 | |
336 | g_critical("size-request"); |
337 | |
338 | //gtk_tree_view_column_cell_get_size(Column, NULL, NULL, NULL, &width, &height); |
339 | //h = height; |
340 | //gtk_cell_renderer_get_size(Renderer, GTK_WIDGET(Event_Viewer_Data->Tree_V), NULL, NULL, NULL, &width, &height); |
341 | //h += height; |
342 | //gtk_cell_renderer_get_fixed_size(Renderer,w,h); |
343 | |
344 | gtk_tree_view_tree_to_widget_coords(GTK_TREE_VIEW(Event_Viewer_Data->Tree_V), |
345 | 1,1,&width, &height); |
346 | w = width; |
347 | h = height; |
348 | //requisition->height = Cell_Height; |
349 | requisition->height = 46; |
350 | g_critical("width : %i height : %i", w, h); |
351 | |
352 | |
fcdf0ec2 |
353 | } |
354 | |
fbbb2697 |
355 | |
356 | void add_test_data(EventViewerData *Event_Viewer_Data) |
fcdf0ec2 |
357 | { |
fbbb2697 |
358 | GtkTreeIter iter; |
359 | int i; |
360 | |
361 | for(i=0; i<10; i++) |
362 | { |
363 | /* Add a new row to the model */ |
364 | gtk_list_store_append (Event_Viewer_Data->Store_M, &iter); |
365 | gtk_list_store_set (Event_Viewer_Data->Store_M, &iter, |
366 | CPUID_COLUMN, 0, |
367 | EVENT_COLUMN, "event irq", |
368 | TIME_COLUMN, i, |
369 | PID_COLUMN, 100, |
370 | ENTRY_LEN_COLUMN, 17, |
371 | EVENT_DESCR_COLUMN, "Detailed information", |
372 | -1); |
373 | } |
374 | |
375 | } |
376 | |
fcdf0ec2 |
377 | |
fbbb2697 |
378 | void |
379 | GuiEvents_Destructor(EventViewerData *Event_Viewer_Data) |
380 | { |
381 | guint index; |
382 | |
383 | /* May already been done by GTK window closing */ |
384 | if(GTK_IS_WIDGET(Event_Viewer_Data->HBox_V)) |
385 | gtk_widget_destroy(Event_Viewer_Data->HBox_V); |
386 | |
387 | /* Destroy the Tree View */ |
388 | //gtk_widget_destroy(Event_Viewer_Data->Tree_V); |
389 | |
390 | /* Clear raw event list */ |
391 | //gtk_list_store_clear(Event_Viewer_Data->Store_M); |
392 | //gtk_widget_destroy(GTK_WIDGET(Event_Viewer_Data->Store_M)); |
393 | |
394 | g_slist_remove(sEvent_Viewer_Data_List,Event_Viewer_Data); |
fcdf0ec2 |
395 | } |
396 | |
fbbb2697 |
397 | //FIXME : call hGuiEvents_Destructor for corresponding data upon widget destroy |
398 | |
399 | static void |
400 | tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data) |
401 | { |
402 | GtkTreeIter iter; |
403 | GtkTreeModel *model; |
404 | gchar *Event; |
405 | |
406 | if (gtk_tree_selection_get_selected (selection, &model, &iter)) |
407 | { |
408 | gtk_tree_model_get (model, &iter, EVENT_COLUMN, &Event, -1); |
409 | |
410 | g_print ("Event selected : %s\n", Event); |
411 | |
412 | g_free (Event); |
413 | } |
414 | } |
fcdf0ec2 |
415 | |
fcdf0ec2 |
416 | |
417 | |
fbbb2697 |
418 | |
419 | /* Imported code from LTT 0.9.6pre2 tracevisualizer */ |
420 | #ifdef DEBUG |
421 | |
fcdf0ec2 |
422 | /****************************************************************** |
423 | * Function : |
424 | * WDI_gtk_clist_set_last_row_data_full() |
425 | * Description : |
426 | * Appends data to the last row of a GtkClist. |
427 | * Parameters : |
428 | * Return values : |
429 | * NONE. |
430 | * History : |
431 | * J.H.D., 27/08/99, Initial typing. |
432 | * Note : |
433 | * Based on gtk_clist_set_row_data_full() version 1.2.3. |
434 | * Much faster than using gtk_clist_set_row_data_full(). |
435 | ******************************************************************/ |
fbbb2697 |
436 | static void WDI_gtk_clist_set_last_row_data_full(GtkCList* pmClist, |
fcdf0ec2 |
437 | gpointer pmData, |
438 | GtkDestroyNotify pmDestroy) |
439 | { |
440 | GtkCListRow *pClistRow; |
5c7463ed |
441 | |
fcdf0ec2 |
442 | g_return_if_fail (pmClist != NULL); |
443 | g_return_if_fail (GTK_IS_CLIST (pmClist)); |
444 | g_return_if_fail (pmClist->row_list_end != NULL); |
5c7463ed |
445 | |
fcdf0ec2 |
446 | pClistRow = pmClist->row_list_end->data; |
447 | pClistRow->data = pmData; |
448 | pClistRow->destroy = pmDestroy; |
5c7463ed |
449 | } |
450 | |
451 | |
fcdf0ec2 |
452 | /****************************************************************** |
453 | * Function : |
454 | * SHRTEventSelect() |
455 | * Description : |
456 | * Parameters : |
457 | * Return values : |
458 | * History : |
459 | * Note : |
460 | ******************************************************************/ |
fbbb2697 |
461 | static void SHRTEventSelect(GtkWidget* pmCList, |
fcdf0ec2 |
462 | gint pmRow, |
463 | gint pmColumn, |
464 | GdkEventButton* pmEvent, |
465 | gpointer pmData) |
466 | { |
467 | systemView* pSysView; /* The system being displayed */ |
468 | |
469 | /* Do we have anything meaningfull */ |
470 | if((pSysView = (systemView*) pmData) == NULL) |
471 | return; |
472 | |
473 | /* Store the selected event */ |
474 | pSysView->Window->LastSelectedEvent = *(event*) gtk_clist_get_row_data(GTK_CLIST(pmCList), pmRow); |
475 | pSysView->Window->EventSelected = TRUE; |
476 | } |
477 | |
478 | /****************************************************************** |
479 | * Function : |
480 | * SHRTEventButtonPress() |
481 | * Description : |
482 | * Parameters : |
483 | * Return values : |
484 | * History : |
485 | * Note : |
486 | ******************************************************************/ |
fbbb2697 |
487 | static void SHRTEventButtonPress(GtkWidget* pmCList, |
fcdf0ec2 |
488 | GdkEventButton* pmEvent, |
489 | gpointer pmData) |
490 | { |
491 | systemView* pSysView; /* The system being displayed */ |
492 | gint row, column; /* The clicked row and column */ |
493 | |
494 | /* Do we have anything meaningfull */ |
495 | if((pSysView = (systemView*) pmData) == NULL) |
496 | return; |
497 | |
498 | /* if we have a right-click event */ |
499 | if(pmEvent->button == 3) |
500 | /* If we clicked on an item, get its row and column values */ |
501 | if(gtk_clist_get_selection_info(GTK_CLIST(pmCList), pmEvent->x, pmEvent->y, &row, &column)) |
502 | { |
503 | /* Highlight the selected row */ |
504 | gtk_clist_select_row(GTK_CLIST(pmCList), row, column); |
505 | |
506 | /* Store the selected event */ |
507 | pSysView->Window->LastSelectedEvent = *(event*) gtk_clist_get_row_data(GTK_CLIST(pmCList), row); |
508 | pSysView->Window->EventSelected = TRUE; |
509 | |
510 | /* Display the popup menu */ |
511 | gtk_menu_popup(GTK_MENU(pSysView->Window->RawEventPopup), |
512 | NULL, NULL, NULL, NULL, |
513 | pmEvent->button, GDK_CURRENT_TIME); |
514 | } |
515 | } |
516 | |
517 | |
518 | /****************************************************************** |
519 | * Function : |
520 | * SHRTVAdjustValueChanged() |
521 | * Description : |
522 | * Parameters : |
523 | * Return values : |
524 | * History : |
525 | * Note : |
526 | ******************************************************************/ |
fbbb2697 |
527 | static void SHRTVAdjustValueChanged(GtkAdjustment* pmVAdjust, |
fcdf0ec2 |
528 | gpointer pmData) |
529 | { |
530 | event lEvent; /* Event used for searching */ |
531 | guint32 lPosition; /* The position to scroll to */ |
532 | systemView* pSysView; /* The system being displayed */ |
533 | |
534 | /* Do we have anything meaningfull */ |
535 | if((pSysView = (systemView*) pmData) == NULL) |
536 | return; |
537 | |
538 | /* Is there an event database? */ |
539 | if(pSysView->EventDB == NULL) |
540 | return; |
541 | |
542 | /* Set the pointer to the first event */ |
543 | if(pSysView->EventDB->TraceStart == NULL) |
544 | return; |
545 | |
546 | /* Are we closer to the beginning? */ |
547 | if((pmVAdjust->value - (pmVAdjust->upper / 2)) < 0) |
548 | { |
549 | /* Set the navigation pointer to the beginning of the list */ |
550 | lEvent = pSysView->EventDB->FirstEvent; |
551 | |
552 | /* Calculate distance from beginning */ |
553 | lPosition = (guint32) pmVAdjust->value; |
554 | |
555 | /* Find the event in the event database */ |
556 | while(lPosition > 0) |
557 | { |
558 | lPosition--; |
559 | if(DBEventNext(pSysView->EventDB, &lEvent) != TRUE) |
560 | break; |
561 | } |
562 | } |
563 | else |
564 | { |
565 | /* Set the navigation pointer to the end of the list */ |
566 | lEvent = pSysView->EventDB->LastEvent; |
567 | |
568 | /* Calculate distance from end */ |
569 | lPosition = (guint32) (pmVAdjust->upper - pmVAdjust->value); |
570 | |
571 | /* Find the event in the event database */ |
572 | while(lPosition > 0) |
573 | { |
574 | lPosition--; |
575 | if(DBEventPrev(pSysView->EventDB, &lEvent) != TRUE) |
576 | break; |
577 | } |
578 | } |
579 | |
580 | /* Fill the event list according to what was found */ |
581 | WDFillEventList(pSysView->Window->RTCList, |
582 | pSysView->EventDB, |
583 | pSysView->System, |
584 | &lEvent, |
585 | &(pSysView->Window->LastSelectedEvent)); |
586 | } |
587 | |
588 | |
589 | |
590 | /****************************************************************** |
591 | * Function : |
592 | * WDConnectSignals() |
593 | * Description : |
594 | * Attaches signal handlers to the window items. |
595 | * Parameters : |
596 | * pmSysView, System view for which signals have to be connected |
597 | * Return values : |
598 | * NONE |
599 | * History : |
600 | * Note : |
601 | * This function attaches a pointer to the main window during |
602 | * the connect. This means that the handlers will get a pointer |
603 | * to the window in the data argument. |
604 | ******************************************************************/ |
fbbb2697 |
605 | static void WDConnectSignals(systemView* pmSysView) |
fcdf0ec2 |
606 | { |
607 | /* Raw event Popup menu */ |
608 | gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RawGotoProcess), |
609 | "activate", |
610 | GTK_SIGNAL_FUNC(SHGotoProcAnalysis), |
611 | pmSysView); |
612 | gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RawViewEvent), |
613 | "activate", |
614 | GTK_SIGNAL_FUNC(SHViewEventInEG), |
615 | pmSysView); |
616 | |
617 | /* Set event list callbacks */ |
618 | gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RTCList), |
619 | "select_row", |
620 | GTK_SIGNAL_FUNC(SHRTEventSelect), |
621 | pmSysView); |
622 | gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RTCList), |
623 | "button-press-event", |
624 | GTK_SIGNAL_FUNC(SHRTEventButtonPress), |
625 | pmSysView); |
626 | gtk_signal_connect(GTK_OBJECT(pmSysView->Window->RTVAdjust), |
627 | "value-changed", |
628 | GTK_SIGNAL_FUNC(SHRTVAdjustValueChanged), |
629 | pmSysView); |
630 | |
631 | |
632 | } |
633 | |
634 | |
635 | /****************************************************************** |
636 | * Function : |
637 | * WDFillEventList() |
638 | * Description : |
639 | * Fills the window's event list using the trace database. |
640 | * Parameters : |
641 | * pmList, The list to be filled. |
642 | * pmTraceDB, The database of events. |
643 | * pmSystem, The system to which this list belongs. |
644 | * pmEvent, Event from which we start drawing. |
645 | * pmSelectedEvent, Event selected if any. |
646 | * Return values : |
647 | * NONE. |
648 | * History : |
649 | * K.Y., 18/06/99, Initial typing. |
650 | * Note : |
651 | ******************************************************************/ |
fbbb2697 |
652 | static void WDFillEventList(GtkWidget* pmList, |
fcdf0ec2 |
653 | db* pmTraceDB, |
654 | systemInfo* pmSystem, |
655 | event* pmEvent, |
656 | event* pmSelectedEvent) |
657 | { |
658 | gint i = 0; /* Generic index */ |
659 | event lEvent; /* Generic event */ |
660 | gchar lTimeStr[TIME_STR_LEN]; /* Time of event */ |
661 | static gchar* lString[RTCLIST_NB_COLUMNS]={'\0'}; /* Strings describing event */ |
662 | process* pProcess; /* Generic process pointer */ |
663 | #if SUPP_RTAI |
664 | RTAItask* pTask = NULL; /* Generic task pointer */ |
665 | #endif /* SUPP_RTAI */ |
666 | eventDescription lEventDesc; /* Description of event */ |
667 | |
668 | /* Did we allocate space for strings */ |
669 | if(lString[0] == NULL) |
670 | /* Allocate space for strings */ |
671 | for (i = 0; i < RTCLIST_NB_COLUMNS - 1; i++) |
672 | lString[i] = (char*) g_malloc(MW_DEFAULT_STRLEN); |
673 | |
674 | /* Allocate space for description string */ |
675 | lString[RTCLIST_NB_COLUMNS - 1] = (char*) g_malloc(MW_LONG_STRLEN); |
676 | |
677 | /* If no event was supplied, start at the beginning */ |
678 | if(pmEvent == NULL) |
679 | lEvent = pmTraceDB->FirstEvent; |
680 | else |
681 | lEvent = *pmEvent; |
682 | |
683 | /* Freeze and clear clist */ |
684 | gtk_clist_freeze(GTK_CLIST(pmList)); |
685 | gtk_clist_clear(GTK_CLIST(pmList)); |
686 | |
687 | /* Reset index */ |
688 | i = 0; |
689 | |
690 | /* Go through the event list */ |
691 | do |
692 | { |
693 | /* Get the event description */ |
694 | DBEventDescription(pmTraceDB, &lEvent, TRUE, &lEventDesc); |
695 | |
696 | /* Get the event's process */ |
697 | pProcess = DBEventProcess(pmTraceDB, &lEvent, pmSystem, FALSE); |
698 | |
699 | #if SUPP_RTAI |
700 | /* Does this trace contain RTAI information */ |
701 | if(pmTraceDB->SystemType == TRACE_SYS_TYPE_RTAI_LINUX) |
702 | /* Get the RTAI task to which this event belongs */ |
703 | pTask = RTAIDBEventTask(pmTraceDB, &lEvent, pmSystem, FALSE); |
704 | #endif /* SUPP_RTAI */ |
705 | |
706 | /* Set the event's entry in the list of raw events displayed */ |
707 | sRawEventsDisplayed[i] = lEvent; |
708 | |
709 | /* Add text describing the event */ |
710 | /* The CPU ID */ |
711 | if(pmTraceDB->LogCPUID == TRUE) |
712 | snprintf(lString[0], MW_DEFAULT_STRLEN, "%d", lEventDesc.CPUID); |
713 | else |
714 | snprintf(lString[0], MW_DEFAULT_STRLEN, "0"); |
715 | |
716 | /* The event ID */ |
717 | snprintf(lString[1], MW_DEFAULT_STRLEN, "%s", pmTraceDB->EventString(pmTraceDB, lEventDesc.ID, &lEvent)); |
718 | |
719 | /* The event's time of occurence */ |
720 | DBFormatTimeInReadableString(lTimeStr, |
721 | lEventDesc.Time.tv_sec, |
722 | lEventDesc.Time.tv_usec); |
723 | snprintf(lString[2], MW_DEFAULT_STRLEN, "%s", lTimeStr); |
724 | |
725 | /* Is this an RT event */ |
726 | if(lEventDesc.ID <= TRACE_MAX) |
727 | { |
728 | /* The PID of the process to which the event belongs */ |
729 | if(pProcess != NULL) |
730 | snprintf(lString[3], MW_DEFAULT_STRLEN, "%d", pProcess->PID); |
731 | else |
732 | snprintf(lString[3], MW_DEFAULT_STRLEN, "N/A"); |
733 | } |
734 | #if SUPP_RTAI |
735 | else |
736 | { |
737 | /* The TID of the task to which the event belongs */ |
738 | if(pTask != NULL) |
739 | snprintf(lString[3], MW_DEFAULT_STRLEN, "RT:%d", pTask->TID); |
740 | else |
741 | snprintf(lString[3], MW_DEFAULT_STRLEN, "RT:N/A"); |
742 | } |
743 | #endif /* SUPP_RTAI */ |
744 | |
745 | /* The size of the entry */ |
746 | snprintf(lString[4], MW_DEFAULT_STRLEN, "%d", lEventDesc.Size); |
747 | |
748 | /* The string describing the event */ |
749 | snprintf(lString[5], MW_LONG_STRLEN, "%s", lEventDesc.String); |
750 | |
751 | /* Insert the entry into the list */ |
752 | gtk_clist_append(GTK_CLIST(pmList), lString); |
753 | |
754 | /* Set the row's data to point to the current event */ |
755 | WDI_gtk_clist_set_last_row_data_full(GTK_CLIST(pmList), (gpointer) &(sRawEventsDisplayed[i]), NULL); |
756 | |
757 | /* Was this the last selected event */ |
758 | if(DBEventsEqual(lEvent, (*pmSelectedEvent))) |
759 | gtk_clist_select_row(GTK_CLIST(pmList), i, 0); |
760 | |
761 | /* Go to next row */ |
762 | i++; |
763 | } while((DBEventNext(pmTraceDB, &lEvent) == TRUE) && (i < RTCLIST_NB_ROWS)); |
764 | |
765 | /* Resize the list's length */ |
766 | gtk_widget_queue_resize(pmList); |
767 | |
768 | /* Thaw the clist */ |
769 | gtk_clist_thaw(GTK_CLIST(pmList)); |
770 | } |
771 | |
fbbb2697 |
772 | #endif //DEBUG |
773 | |
774 | static void destroy_cb( GtkWidget *widget, |
775 | gpointer data ) |
776 | { |
777 | gtk_main_quit (); |
778 | } |
779 | |
780 | |
781 | |
782 | int main(int argc, char **argv) |
783 | { |
784 | GtkWidget *Window; |
785 | GtkWidget *ListViewer; |
786 | GtkWidget *VBox_V; |
787 | EventViewerData *Event_Viewer_Data; |
788 | |
789 | /* Initialize i18n support */ |
790 | gtk_set_locale (); |
791 | |
792 | /* Initialize the widget set */ |
793 | gtk_init (&argc, &argv); |
794 | |
795 | init(); |
fcdf0ec2 |
796 | |
fbbb2697 |
797 | Window = gtk_window_new (GTK_WINDOW_TOPLEVEL); |
798 | gtk_window_set_title (GTK_WINDOW (Window), ("Test Window")); |
799 | |
800 | g_signal_connect (G_OBJECT (Window), "destroy", |
801 | G_CALLBACK (destroy_cb), NULL); |
802 | |
803 | |
804 | VBox_V = gtk_vbox_new(0, 0); |
805 | gtk_container_add (GTK_CONTAINER (Window), VBox_V); |
806 | |
807 | ListViewer = hGuiEvents(Window); |
808 | gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, TRUE, TRUE, 0); |
809 | |
810 | ListViewer = hGuiEvents(Window); |
811 | gtk_box_pack_start(GTK_BOX(VBox_V), ListViewer, FALSE, TRUE, 0); |
812 | |
813 | gtk_widget_show (VBox_V); |
814 | gtk_widget_show (Window); |
815 | |
816 | gtk_main (); |
817 | |
818 | g_critical("main loop finished"); |
819 | |
820 | //hGuiEvents_Destructor(ListViewer); |
821 | |
822 | //g_critical("GuiEvents Destructor finished"); |
823 | destroy(); |
824 | |
825 | return 0; |
826 | } |
fcdf0ec2 |
827 | |
17abcce3 |
828 | |
5c7463ed |
829 | /*\@}*/ |
fbbb2697 |
830 | |