6 #include <lttv/module.h>
7 #include <lttv/gtkTraceSet.h>
8 #include <lttv/processTrace.h>
10 #include <lttv/common.h>
11 #include <lttv/state.h>
12 #include <lttv/stats.h>
15 #include <ltt/event.h>
17 #include <ltt/trace.h>
21 #include "../icons/hGuiStatisticInsert.xpm"
23 #define PATH_LENGTH 256
25 static LttvModule
*Main_Win_Module
;
27 /** Array containing instanced objects. Used when module is unloaded */
28 GSList
*gStatistic_Viewer_Data_List
= NULL
;
30 typedef struct _StatisticViewerData StatisticViewerData
;
32 //! Statistic Viewer's constructor hook
33 GtkWidget
*hGuiStatistic(mainWindow
*pmParentWindow
);
34 //! Statistic Viewer's constructor
35 StatisticViewerData
*GuiStatistic(mainWindow
*pmParentWindow
);
36 //! Statistic Viewer's destructor
37 void GuiStatistic_Destructor(StatisticViewerData
*Statistic_Viewer_Data
);
38 void GuiStatistic_free(StatisticViewerData
*Statistic_Viewer_Data
);
40 void grab_focus(GtkWidget
*widget
, gpointer data
);
41 static void tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
);
43 void Destroy_hash_key(gpointer key
);
44 void Destroy_hash_data(gpointer data
);
46 void get_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
);
47 void show_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
);
48 void show_tree(StatisticViewerData
* Statistic_Viewer_Data
,
49 LttvAttribute
* stats
, GtkTreeIter
* parent
);
50 void show_statistic(StatisticViewerData
* Statistic_Viewer_Data
,
51 LttvAttribute
* stats
, GtkTextBuffer
* buf
);
60 struct _StatisticViewerData
{
62 LttvTracesetStats
* stats
;
65 GtkTreeStore
* Store_M
;
68 //scroll window containing Tree View
69 GtkWidget
* Scroll_Win_Tree
;
72 //scroll window containing Text View
73 GtkWidget
* Scroll_Win_Text
;
76 GtkTreeSelection
*Select_C
;
79 GHashTable
*Statistic_Hash
;
84 * plugin's init function
86 * This function initializes the Statistic Viewer functionnality through the
89 G_MODULE_EXPORT
void init(LttvModule
*self
, int argc
, char *argv
[]) {
91 Main_Win_Module
= lttv_module_require(self
, "mainwin", argc
, argv
);
93 if(Main_Win_Module
== NULL
){
94 g_critical("Can't load Statistic Viewer : missing mainwin\n");
98 g_critical("GUI Statistic Viewer init()");
100 /* Register the toolbar insert button */
101 ToolbarItemReg(hGuiStatisticInsert_xpm
, "Insert Statistic Viewer", hGuiStatistic
);
103 /* Register the menu item insert entry */
104 MenuItemReg("/", "Insert Statistic Viewer", hGuiStatistic
);
108 void destroy_walk(gpointer data
, gpointer user_data
)
110 GuiStatistic_Destructor((StatisticViewerData
*)data
);
114 * plugin's destroy function
116 * This function releases the memory reserved by the module and unregisters
117 * everything that has been registered in the gtkTraceSet API.
119 G_MODULE_EXPORT
void destroy() {
122 StatisticViewerData
*Statistic_Viewer_Data
;
124 g_critical("GUI Statistic Viewer destroy()");
126 g_slist_foreach(gStatistic_Viewer_Data_List
, destroy_walk
, NULL
);
128 g_slist_free(gStatistic_Viewer_Data_List
);
130 /* Unregister the toolbar insert button */
131 ToolbarItemUnreg(hGuiStatistic
);
133 /* Unregister the menu item insert entry */
134 MenuItemUnreg(hGuiStatistic
);
139 GuiStatistic_free(StatisticViewerData
*Statistic_Viewer_Data
)
141 g_hash_table_destroy(Statistic_Viewer_Data
->Statistic_Hash
);
142 gStatistic_Viewer_Data_List
= g_slist_remove(gStatistic_Viewer_Data_List
, Statistic_Viewer_Data
);
143 g_warning("Delete Statistic data\n");
144 g_free(Statistic_Viewer_Data
);
148 GuiStatistic_Destructor(StatisticViewerData
*Statistic_Viewer_Data
)
150 /* May already been done by GTK window closing */
151 if(GTK_IS_WIDGET(Statistic_Viewer_Data
->HPaned_V
))
152 gtk_widget_destroy(Statistic_Viewer_Data
->HPaned_V
);
154 GuiStatistic_free(Statistic_Viewer_Data
);
159 * Statistic Viewer's constructor hook
161 * This constructor is given as a parameter to the menuitem and toolbar button
162 * registration. It creates the list.
163 * @param pmParentWindow A pointer to the parent window.
164 * @return The widget created.
167 hGuiStatistic(mainWindow
* pmParentWindow
)
169 StatisticViewerData
* Statistic_Viewer_Data
= GuiStatistic(pmParentWindow
) ;
171 if(Statistic_Viewer_Data
)
172 return Statistic_Viewer_Data
->HPaned_V
;
178 * Statistic Viewer's constructor
180 * This constructor is used to create StatisticViewerData data structure.
181 * @return The Statistic viewer data created.
183 StatisticViewerData
*
184 GuiStatistic(mainWindow
*pmParentWindow
)
186 GtkCellRenderer
*renderer
;
187 GtkTreeViewColumn
*column
;
189 StatisticViewerData
* Statistic_Viewer_Data
= g_new(StatisticViewerData
,1);
191 Statistic_Viewer_Data
->mw
= pmParentWindow
;
192 Statistic_Viewer_Data
->stats
= getTracesetStats(Statistic_Viewer_Data
->mw
);
194 Statistic_Viewer_Data
->Statistic_Hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
195 Destroy_hash_key
, Destroy_hash_data
);
197 Statistic_Viewer_Data
->HPaned_V
= gtk_hpaned_new();
198 Statistic_Viewer_Data
->Store_M
= gtk_tree_store_new (N_COLUMNS
, G_TYPE_STRING
);
199 Statistic_Viewer_Data
->Tree_V
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (Statistic_Viewer_Data
->Store_M
));
200 g_object_unref (G_OBJECT (Statistic_Viewer_Data
->Store_M
));
202 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Tree_V
), "grab-focus",
203 G_CALLBACK (grab_focus
),
204 Statistic_Viewer_Data
);
206 // Setup the selection handler
207 Statistic_Viewer_Data
->Select_C
= gtk_tree_view_get_selection (GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
));
208 gtk_tree_selection_set_mode (Statistic_Viewer_Data
->Select_C
, GTK_SELECTION_SINGLE
);
209 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Select_C
), "changed",
210 G_CALLBACK (tree_selection_changed_cb
),
211 Statistic_Viewer_Data
);
213 renderer
= gtk_cell_renderer_text_new ();
214 column
= gtk_tree_view_column_new_with_attributes ("Statistic Name",
218 gtk_tree_view_column_set_alignment (column
, 0.0);
219 // gtk_tree_view_column_set_fixed_width (column, 45);
220 gtk_tree_view_append_column (GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
), column
);
223 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
), FALSE
);
225 Statistic_Viewer_Data
->Scroll_Win_Tree
= gtk_scrolled_window_new (NULL
, NULL
);
226 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Statistic_Viewer_Data
->Scroll_Win_Tree
),
227 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
229 gtk_container_add (GTK_CONTAINER (Statistic_Viewer_Data
->Scroll_Win_Tree
), Statistic_Viewer_Data
->Tree_V
);
230 gtk_paned_pack1(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
),Statistic_Viewer_Data
->Scroll_Win_Tree
, TRUE
, FALSE
);
231 gtk_paned_set_position(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
), 160);
233 Statistic_Viewer_Data
->Scroll_Win_Text
= gtk_scrolled_window_new (NULL
, NULL
);
234 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Statistic_Viewer_Data
->Scroll_Win_Text
),
235 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
237 Statistic_Viewer_Data
->Text_V
= gtk_text_view_new ();
238 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Text_V
), "grab-focus",
239 G_CALLBACK (grab_focus
),
240 Statistic_Viewer_Data
);
242 gtk_text_view_set_editable(GTK_TEXT_VIEW(Statistic_Viewer_Data
->Text_V
),FALSE
);
243 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(Statistic_Viewer_Data
->Text_V
),FALSE
);
244 gtk_container_add (GTK_CONTAINER (Statistic_Viewer_Data
->Scroll_Win_Text
), Statistic_Viewer_Data
->Text_V
);
245 gtk_paned_pack2(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
), Statistic_Viewer_Data
->Scroll_Win_Text
, TRUE
, FALSE
);
247 gtk_widget_show(Statistic_Viewer_Data
->Scroll_Win_Tree
);
248 gtk_widget_show(Statistic_Viewer_Data
->Scroll_Win_Text
);
249 gtk_widget_show(Statistic_Viewer_Data
->Tree_V
);
250 gtk_widget_show(Statistic_Viewer_Data
->Text_V
);
251 gtk_widget_show(Statistic_Viewer_Data
->HPaned_V
);
253 g_object_set_data_full(
254 G_OBJECT(Statistic_Viewer_Data
->HPaned_V
),
255 "Statistic_Viewer_Data",
256 Statistic_Viewer_Data
,
257 (GDestroyNotify
)GuiStatistic_free
);
259 /* Add the object's information to the module's array */
260 gStatistic_Viewer_Data_List
= g_slist_append(gStatistic_Viewer_Data_List
, Statistic_Viewer_Data
);
262 get_traceset_stats(Statistic_Viewer_Data
);
264 return Statistic_Viewer_Data
;
267 void grab_focus(GtkWidget
*widget
, gpointer data
)
269 StatisticViewerData
*Statistic_Viewer_Data
= (StatisticViewerData
*)data
;
270 mainWindow
* mw
= Statistic_Viewer_Data
->mw
;
271 SetFocusedPane(mw
, gtk_widget_get_parent(Statistic_Viewer_Data
->HPaned_V
));
275 tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
)
277 StatisticViewerData
*Statistic_Viewer_Data
= (StatisticViewerData
*)data
;
279 GtkTreeModel
*model
= GTK_TREE_MODEL(Statistic_Viewer_Data
->Store_M
);
284 GtkTextIter text_iter
;
285 LttvAttribute
* stats
;
287 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
289 gtk_tree_model_get (model
, &iter
, NAME_COLUMN
, &Event
, -1);
291 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
),&iter
);
292 str
= gtk_tree_path_to_string (path
);
293 stats
= (LttvAttribute
*)g_hash_table_lookup (Statistic_Viewer_Data
->Statistic_Hash
,str
);
296 buf
= gtk_text_view_get_buffer((GtkTextView
*)Statistic_Viewer_Data
->Text_V
);
297 gtk_text_buffer_set_text(buf
,"Statistic for '", -1);
298 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
299 gtk_text_buffer_insert(buf
, &text_iter
, Event
, strlen(Event
));
300 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
301 gtk_text_buffer_insert(buf
, &text_iter
, "' :\n\n",5);
303 show_statistic(Statistic_Viewer_Data
, stats
, buf
);
309 void Destroy_hash_key(gpointer key
)
314 void Destroy_hash_data(gpointer data
)
319 void get_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
)
325 end
.tv_sec
= G_MAXULONG
;
326 end
.tv_nsec
= G_MAXULONG
;
328 stateAddEventHooks(Statistic_Viewer_Data
->mw
);
329 statsAddEventHooks(Statistic_Viewer_Data
->mw
);
331 processTraceset(Statistic_Viewer_Data
->mw
, start
, end
, G_MAXULONG
);
333 stateRemoveEventHooks(Statistic_Viewer_Data
->mw
);
334 statsRemoveEventHooks(Statistic_Viewer_Data
->mw
);
336 //establish tree view for stats
337 show_traceset_stats(Statistic_Viewer_Data
);
340 void show_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
)
345 LttSystemDescription
*desc
;
346 LttvTracesetStats
* tscs
= Statistic_Viewer_Data
->stats
;
347 gchar
* str
, trace_str
[PATH_LENGTH
];
350 GtkTreeStore
* store
= Statistic_Viewer_Data
->Store_M
;
352 if(tscs
->stats
== NULL
) return;
354 gtk_tree_store_append (store
, &iter
, NULL
);
355 gtk_tree_store_set (store
, &iter
,
356 NAME_COLUMN
, "Traceset statistics",
358 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
359 str
= gtk_tree_path_to_string (path
);
360 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
361 (gpointer
)str
, tscs
->stats
);
362 show_tree(Statistic_Viewer_Data
, tscs
->stats
, &iter
);
364 //show stats for all traces
365 ts
= tscs
->parent
.parent
.ts
;
366 nb
= lttv_traceset_number(ts
);
368 for(i
= 0 ; i
< nb
; i
++) {
369 tcs
= (LttvTraceStats
*)(LTTV_TRACESET_CONTEXT(tscs
)->traces
[i
]);
370 desc
= ltt_trace_system_description(tcs
->parent
.parent
.t
);
371 sprintf(trace_str
, "Trace on system %s at time %d secs",
372 desc
->node_name
,desc
->trace_start
.tv_sec
);
374 gtk_tree_store_append (store
, &iter
, NULL
);
375 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,trace_str
,-1);
376 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
377 str
= gtk_tree_path_to_string (path
);
378 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
379 (gpointer
)str
,tcs
->stats
);
380 show_tree(Statistic_Viewer_Data
, tcs
->stats
, &iter
);
384 void show_tree(StatisticViewerData
* Statistic_Viewer_Data
,
385 LttvAttribute
* stats
, GtkTreeIter
* parent
)
388 LttvAttribute
*subtree
;
389 LttvAttributeName name
;
390 LttvAttributeValue value
;
391 LttvAttributeType type
;
392 gchar
* str
, dir_str
[PATH_LENGTH
];
395 GtkTreeStore
* store
= Statistic_Viewer_Data
->Store_M
;
397 nb
= lttv_attribute_get_number(stats
);
398 for(i
= 0 ; i
< nb
; i
++) {
399 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
402 if(LTTV_IS_ATTRIBUTE(*(value
.v_gobject
))) {
403 sprintf(dir_str
, "%s", g_quark_to_string(name
));
404 subtree
= (LttvAttribute
*)*(value
.v_gobject
);
405 gtk_tree_store_append (store
, &iter
, parent
);
406 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,dir_str
,-1);
407 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
408 str
= gtk_tree_path_to_string (path
);
409 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
410 (gpointer
)str
, subtree
);
411 show_tree(Statistic_Viewer_Data
, subtree
, &iter
);
420 void show_statistic(StatisticViewerData
* Statistic_Viewer_Data
,
421 LttvAttribute
* stats
, GtkTextBuffer
* buf
)
424 LttvAttribute
*subtree
;
425 LttvAttributeName name
;
426 LttvAttributeValue value
;
427 LttvAttributeType type
;
428 gchar type_name
[PATH_LENGTH
], type_value
[PATH_LENGTH
];
429 GtkTextIter text_iter
;
432 nb
= lttv_attribute_get_number(stats
);
433 for(i
= 0 ; i
< nb
; i
++) {
434 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
435 sprintf(type_name
,"%s", g_quark_to_string(name
));
436 type_value
[0] = '\0';
439 sprintf(type_value
, " : %d\n", *value
.v_int
);
442 sprintf(type_value
, " : %u\n", *value
.v_uint
);
445 sprintf(type_value
, " : %ld\n", *value
.v_long
);
448 sprintf(type_value
, " : %lu\n", *value
.v_ulong
);
451 sprintf(type_value
, " : %f\n", (double)*value
.v_float
);
454 sprintf(type_value
, " : %f\n", *value
.v_double
);
457 sprintf(type_value
, " : %10u.%09u\n", value
.v_time
->tv_sec
,
458 value
.v_time
->tv_nsec
);
461 sprintf(type_value
, " : POINTER\n");
464 sprintf(type_value
, " : %s\n", *value
.v_string
);
469 if(strlen(type_value
)){
471 strcat(type_name
,type_value
);
472 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
473 gtk_text_buffer_insert(buf
, &text_iter
, type_name
, strlen(type_name
));
478 sprintf(type_value
, "No statistic information in this directory.\nCheck in subdirectories please.\n");
479 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
480 gtk_text_buffer_insert(buf
, &text_iter
, type_value
, strlen(type_value
));