1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Simon Bouvier-Zappa
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 #include <lttv/lttv.h>
25 #include <lttv/module.h>
26 #include <lttv/hook.h>
27 #include <lttv/filter.h>
29 #include <lttvwindow/lttvwindow.h>
30 #include <lttvwindow/lttvwindowtraces.h>
32 #include "hGuiFilterInsert.xpm"
36 * - connect the gui filter to the core filter
39 typedef struct _FilterViewerData FilterViewerData
;
40 typedef struct _FilterViewerDataLine FilterViewerDataLine
;
45 GtkWidget
*guifilter_get_widget(FilterViewerData
*fvd
);
46 FilterViewerData
*gui_filter(Tab
*tab
);
47 void gui_filter_destructor(FilterViewerData
*fvd
);
48 FilterViewerDataLine
* gui_filter_add_line(FilterViewerData
*fvd
);
49 void gui_filter_line_set_visible(FilterViewerDataLine
*fvdl
, gboolean v
);
50 void gui_filter_line_reset(FilterViewerDataLine
*fvdl
);
51 gboolean
filter_traceset_changed(void * hook_data
, void * call_data
);
52 gboolean
filter_viewer_data(void * hook_data
, void * call_data
);
53 GtkWidget
* h_guifilter(Tab
*tab
);
54 void filter_destroy_walk(gpointer data
, gpointer user_data
);
59 void callback_process_button(GtkWidget
*widget
, gpointer data
);
60 void callback_add_button(GtkWidget
*widget
, gpointer data
);
61 void callback_logical_op_box(GtkWidget
*widget
, gpointer data
);
62 void callback_expression_field(GtkWidget
*widget
, gpointer data
);
64 struct _FilterViewerDataLine
{
67 GtkWidget
*f_logical_op_box
;
68 GtkWidget
*f_struct_box
;
69 GtkWidget
*f_subfield_box
;
70 GtkWidget
*f_math_op_box
;
71 GtkWidget
*f_value_field
;
75 * @struct _FilterViewerData
76 * Main struct for the filter gui module
78 struct _FilterViewerData
{
81 GtkWidget
*f_main_box
;
86 GtkWidget
*f_expression_field
;
87 GtkWidget
*f_process_button
;
89 GtkWidget
*f_logical_op_junction_box
;
94 GtkWidget
*f_add_button
;
97 GtkWidget
*f_selectwnd
;
103 * This function returns the current main widget
104 * used by this module
105 * @param fvd the module struct
106 * @return The main widget
109 *guifilter_get_widget(FilterViewerData
*fvd
)
111 return fvd
->f_main_box
;
115 * Constructor is used to create FilterViewerData data structure.
116 * @param the tab structure used by the widget
117 * @return The Filter viewer data created.
122 g_print("filter::gui_filter()");
124 GtkCellRenderer
*renderer
;
125 GtkTreeViewColumn
*column
;
127 FilterViewerData
* fvd
= g_new(FilterViewerData
,1);
131 lttvwindow_register_traceset_notify(fvd
->tab
,
132 filter_traceset_changed
,
134 // request_background_data(filter_viewer_data);
137 * Initiating GtkTable layout
138 * starts with 2 rows and 5 columns and
139 * expands when expressions added
141 fvd
->f_main_box
= gtk_table_new(3,6,FALSE
);
142 gtk_table_set_row_spacings(GTK_TABLE(fvd
->f_main_box
),5);
143 gtk_table_set_col_spacings(GTK_TABLE(fvd
->f_main_box
),5);
146 * First half of the filter window
147 * - textual entry of filter expression
148 * - processing button
150 fvd
->f_expression_field
= gtk_entry_new(); //gtk_scrolled_window_new (NULL, NULL);
151 // gtk_entry_set_text(GTK_ENTRY(fvd->f_expression_field),"state.cpu>0");
152 gtk_widget_show (fvd
->f_expression_field
);
154 g_signal_connect (G_OBJECT (fvd
->f_expression_field
), "changed",
155 G_CALLBACK (callback_expression_field
), (gpointer
) fvd
);
157 fvd
->f_process_button
= gtk_button_new_with_label("Process");
158 gtk_widget_show (fvd
->f_process_button
);
160 g_signal_connect (G_OBJECT (fvd
->f_process_button
), "clicked",
161 G_CALLBACK (callback_process_button
), (gpointer
) fvd
);
163 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvd
->f_expression_field
,0,5,0,1,GTK_FILL
,GTK_FILL
,0,0);
164 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvd
->f_process_button
,5,6,0,1,GTK_FILL
,GTK_FILL
,0,0);
169 * Second half of the filter window
170 * - combo boxes featuring filtering options added to the expression
172 fvd
->f_add_button
= gtk_button_new_with_label("Add Expression");
173 gtk_widget_show (fvd
->f_add_button
);
175 g_signal_connect (G_OBJECT (fvd
->f_add_button
), "clicked",
176 G_CALLBACK (callback_add_button
), (gpointer
) fvd
);
178 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvd
->f_add_button
,5,6,1,2,GTK_FILL
,GTK_FILL
,0,0);
180 fvd
->f_logical_op_junction_box
= gtk_combo_box_new_text();
181 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd
->f_logical_op_junction_box
), "");
182 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd
->f_logical_op_junction_box
), "&");
183 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd
->f_logical_op_junction_box
), "|");
184 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd
->f_logical_op_junction_box
), "^");
185 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd
->f_logical_op_junction_box
), "!");
186 //gtk_widget_show(fvd->f_logical_op_box);
188 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvd
->f_logical_op_junction_box
,0,1,1,2,GTK_SHRINK
,GTK_FILL
,0,0);
190 /* initialize a new line */
191 fvd
->f_lines
= g_ptr_array_new();
193 FilterViewerDataLine
* fvdl
= gui_filter_add_line(fvd
);
194 g_ptr_array_add(fvd
->f_lines
,(gpointer
) fvdl
);
197 * show main container
199 gtk_widget_show(fvd
->f_main_box
);
202 g_object_set_data_full(
203 G_OBJECT(guifilter_get_widget(fvd
)),
204 "filter_viewer_data",
206 (GDestroyNotify
)gui_filter_destructor
);
213 * Adds a filter option line on the module tab
214 * @param fvd The filter module structure
215 * @return The line structure
217 FilterViewerDataLine
*
218 gui_filter_add_line(FilterViewerData
* fvd
) {
220 FilterViewerDataLine
* fvdl
= g_new(FilterViewerDataLine
,1);
222 fvdl
->row
= fvd
->rows
;
223 fvdl
->visible
= TRUE
;
225 fvdl
->f_struct_box
= gtk_combo_box_new_text();
226 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_struct_box
), "");
227 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_struct_box
), "event");
228 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_struct_box
), "tracefile");
229 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_struct_box
), "trace");
230 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_struct_box
), "state");
231 gtk_widget_show(fvdl
->f_struct_box
);
233 fvdl
->f_subfield_box
= gtk_combo_box_new_text();
234 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "");
235 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "name");
236 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "category");
237 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "time");
238 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "tsc");
239 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "pid");
240 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "ppid");
241 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "creation time");
242 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "insertion time");
243 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "process name");
244 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "execution mode");
245 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "execution submode");
246 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "process status");
247 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_subfield_box
), "cpu");
248 gtk_widget_show(fvdl
->f_subfield_box
);
250 fvdl
->f_math_op_box
= gtk_combo_box_new_text();
251 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), "");
252 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), "=");
253 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), "!=");
254 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), "<");
255 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), "<=");
256 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), ">");
257 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_math_op_box
), ">=");
258 gtk_widget_show(fvdl
->f_math_op_box
);
260 fvdl
->f_value_field
= gtk_entry_new();
261 gtk_widget_show(fvdl
->f_value_field
);
263 fvdl
->f_logical_op_box
= gtk_combo_box_new_text();
264 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_logical_op_box
), "");
265 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_logical_op_box
), "&");
266 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_logical_op_box
), "|");
267 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_logical_op_box
), "^");
268 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl
->f_logical_op_box
), "!");
269 gtk_widget_show(fvdl
->f_logical_op_box
);
271 gtk_widget_set_events(fvdl
->f_logical_op_box
,
272 GDK_ENTER_NOTIFY_MASK
|
273 GDK_LEAVE_NOTIFY_MASK
|
274 GDK_FOCUS_CHANGE_MASK
);
276 g_signal_connect (G_OBJECT (fvdl
->f_logical_op_box
), "changed",
277 G_CALLBACK (callback_logical_op_box
), (gpointer
) fvd
);
279 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvdl
->f_struct_box
,0,1,fvd
->rows
+1,fvd
->rows
+2,GTK_SHRINK
,GTK_FILL
,0,0);
280 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvdl
->f_subfield_box
,1,2,fvd
->rows
+1,fvd
->rows
+2,GTK_SHRINK
,GTK_FILL
,0,0);
281 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvdl
->f_math_op_box
,2,3,fvd
->rows
+1,fvd
->rows
+2,GTK_SHRINK
,GTK_FILL
,0,0);
282 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvdl
->f_value_field
,3,4,fvd
->rows
+1,fvd
->rows
+2,GTK_SHRINK
,GTK_FILL
,0,0);
283 gtk_table_attach( GTK_TABLE(fvd
->f_main_box
),fvdl
->f_logical_op_box
,4,5,fvd
->rows
+1,fvd
->rows
+2,GTK_SHRINK
,GTK_FILL
,0,0);
288 void gui_filter_line_set_visible(FilterViewerDataLine
*fvdl
, gboolean v
) {
292 gtk_widget_show(fvdl
->f_struct_box
);
293 gtk_widget_show(fvdl
->f_subfield_box
);
294 gtk_widget_show(fvdl
->f_math_op_box
);
295 gtk_widget_show(fvdl
->f_value_field
);
296 gtk_widget_show(fvdl
->f_logical_op_box
);
298 gtk_widget_hide(fvdl
->f_struct_box
);
299 gtk_widget_hide(fvdl
->f_subfield_box
);
300 gtk_widget_hide(fvdl
->f_math_op_box
);
301 gtk_widget_hide(fvdl
->f_value_field
);
302 gtk_widget_hide(fvdl
->f_logical_op_box
);
307 void gui_filter_line_reset(FilterViewerDataLine
*fvdl
) {
309 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl
->f_struct_box
),0);
310 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl
->f_subfield_box
),0);
311 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl
->f_math_op_box
),0);
312 gtk_entry_set_text(GTK_COMBO_BOX(fvdl
->f_value_field
),"");
313 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl
->f_logical_op_box
),0);
317 * Destructor for the filter gui module
318 * @param fvd The module structure
321 gui_filter_destructor(FilterViewerData
*fvd
)
325 /* May already been done by GTK window closing */
326 if(GTK_IS_WIDGET(guifilter_get_widget(fvd
))){
327 g_info("widget still exists");
330 lttvwindow_unregister_traceset_notify(fvd
->tab
,
331 filter_traceset_changed
,
334 lttvwindowtraces_background_notify_remove(fvd
);
341 * @param hook_data The hook data
342 * @param call_data The call data
343 * @return Success/Failure of operation
346 filter_traceset_changed(void * hook_data
, void * call_data
) {
353 * @param hook_data The hook data
354 * @param call_data The call data
355 * @return Success/Failure of operation
358 filter_viewer_data(void * hook_data
, void * call_data
) {
364 * Filter Module's constructor hook
366 * This constructor is given as a parameter to the menuitem and toolbar button
367 * registration. It creates the list.
368 * @param tab A pointer to the parent window.
369 * @return The widget created.
372 h_guifilter(Tab
*tab
)
374 FilterViewerData
* f
= gui_filter(tab
) ;
376 g_print("FilterViewerData:%p\n",f
);
378 return guifilter_get_widget(f
);
384 * This function initializes the Filter Viewer functionnality through the
389 lttvwindow_register_constructor("guifilter",
391 "Insert Filter Module",
392 hGuiFilterInsert_xpm
,
393 "Insert Filter Module",
398 * Initiate the destruction of the current gui module
399 * on the GTK Interface
401 void filter_destroy_walk(gpointer data
, gpointer user_data
)
403 FilterViewerData
*fvd
= (FilterViewerData
*)data
;
405 g_debug("CFV.c : filter_destroy_walk, %p", fvd
);
406 /* May already have been done by GTK window closing */
407 if(GTK_IS_WIDGET(guifilter_get_widget(fvd
)))
408 gtk_widget_destroy(guifilter_get_widget(fvd
));
412 * plugin's destroy function
414 * This function releases the memory reserved by the module and unregisters
415 * everything that has been registered in the gtkTraceSet API.
417 static void destroy() {
419 lttvwindow_unregister_constructor(h_guifilter
);
424 * The Process Button callback function
425 * @param widget The Button widget passed to the callback function
426 * @param data Data sent along with the callback function
428 void callback_process_button(GtkWidget
*widget
, gpointer data
) {
430 FilterViewerData
*fvd
= (FilterViewerData
*)data
;
432 if(strlen(gtk_entry_get_text(GTK_ENTRY(fvd
->f_expression_field
))) !=0)
433 lttv_filter_new(gtk_entry_get_text(GTK_ENTRY(fvd
->f_expression_field
)),NULL
);
437 * The Add Button callback function
438 * @param widget The Button widget passed to the callback function
439 * @param data Data sent along with the callback function
441 void callback_expression_field(GtkWidget
*widget
, gpointer data
) {
443 FilterViewerData
*fvd
= (FilterViewerData
*)data
;
445 if(strlen(gtk_entry_get_text(GTK_ENTRY(fvd
->f_expression_field
))) !=0) {
446 gtk_widget_show(fvd
->f_logical_op_junction_box
);
448 gtk_widget_hide(fvd
->f_logical_op_junction_box
);
454 * The Add Button callback function
455 * @param widget The Button widget passed to the callback function
456 * @param data Data sent along with the callback function
458 void callback_add_button(GtkWidget
*widget
, gpointer data
) {
460 g_print("filter::callback_add_button()\n");
462 FilterViewerData
*fvd
= (FilterViewerData
*)data
;
463 FilterViewerDataLine
*fvdl
= NULL
;
464 GString
* a_filter_string
= g_string_new("");
466 // g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvd->f_logical_op_junction_box)));
467 gtk_combo_box_set_active(fvd
->f_logical_op_junction_box
,0);
469 g_string_append_c(a_filter_string
,"(");
472 for(i
=0;i
<fvd
->f_lines
->len
;i
++) {
473 fvdl
= (FilterViewerDataLine
*)g_ptr_array_index(fvd
->f_lines
,i
);
474 // g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_struct_box)));
475 g_string_append_c(a_filter_string
,".");
476 // g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_subfield_box)));
477 // g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_math_op_box)));
478 // g_string_append(a_filter_string,gtk_entry_get_text(GTK_ENTRY(fvdl->f_value_field)));
479 // g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_logical_op_box)));
480 gui_filter_line_reset(fvdl
);
481 if(i
) gui_filter_line_set_visible(fvdl
,FALSE
);
484 g_string_append(a_filter_string
,")");
486 gtk_entry_set_text(GTK_ENTRY(fvdl
->f_value_field
),a_filter_string
->str
);
491 * The logical op box callback function
492 * @param widget The Button widget passed to the callback function
493 * @param data Data sent along with the callback function
495 void callback_logical_op_box(GtkWidget
*widget
, gpointer data
) {
497 g_print("filter::callback_logical_op_box()\n");
499 FilterViewerData
*fvd
= (FilterViewerData
*)data
;
500 FilterViewerDataLine
*fvdl
= NULL
;
503 for(i
=0;i
<fvd
->f_lines
->len
;i
++) {
504 fvdl
= (FilterViewerDataLine
*)g_ptr_array_index(fvd
->f_lines
,i
);
505 if(fvdl
->f_logical_op_box
== widget
) {
506 if(gtk_combo_box_get_active(fvdl
->f_logical_op_box
) == 0) return;
507 if(i
==fvd
->f_lines
->len
-1) { /* create a new line */
509 FilterViewerDataLine
* fvdl2
= gui_filter_add_line(fvd
);
510 g_ptr_array_add(fvd
->f_lines
,(gpointer
) fvdl2
);
512 FilterViewerDataLine
*fvdl2
= (FilterViewerDataLine
*)g_ptr_array_index(fvd
->f_lines
,i
+1);
513 if(!fvdl2
->visible
) gui_filter_line_set_visible(fvdl2
,TRUE
);
520 LTTV_MODULE("guifilter", "Filter window", \
521 "Graphical module that let user specify their filtering options", \
522 init
, destroy
, "lttvwindow")