1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2005 Mathieu Desnoyers
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,
27 #include <gdk/gdkkeysyms.h>
29 #include <lttv/lttv.h>
30 #include <lttv/module.h>
31 #include <lttv/hook.h>
33 #include <lttvwindow/lttvwindow.h>
34 #include <lttvwindow/lttvwindowtraces.h>
36 #include "hTraceControlInsert.xpm"
37 #include "TraceControlStart.xpm"
38 #include "TraceControlPause.xpm"
39 #include "TraceControlStop.xpm"
41 #include <sys/types.h>
49 #define MAX_ARGS_LEN PATH_MAX * 10
51 GSList
*g_control_list
= NULL
;
53 /*! \file lttv/modules/gui/tracecontrol/tracecontrol.c
54 * \brief Graphic trace start/stop control interface.
56 * This plugin interacts with lttctl to start/stop tracing. It needs to take the
57 * root password to be able to interact with lttctl.
61 typedef struct _ControlData ControlData
;
66 GtkWidget
*guicontrol_get_widget(ControlData
*tcd
);
67 ControlData
*gui_control(Tab
*tab
);
68 void gui_control_destructor(ControlData
*tcd
);
69 GtkWidget
* h_guicontrol(Tab
*tab
);
70 void control_destroy_walk(gpointer data
, gpointer user_data
);
76 static void start_clicked (GtkButton
*button
, gpointer user_data
);
77 static void pause_clicked (GtkButton
*button
, gpointer user_data
);
78 static void unpause_clicked (GtkButton
*button
, gpointer user_data
);
79 static void stop_clicked (GtkButton
*button
, gpointer user_data
);
83 * @struct _ControlData
85 * @brief Main structure of gui control
88 Tab
*tab
; /**< current tab of module */
90 GtkWidget
*window
; /**< window */
92 GtkWidget
*main_box
; /**< main container */
93 GtkWidget
*start_button
;
94 GtkWidget
*pause_button
;
95 GtkWidget
*unpause_button
;
96 GtkWidget
*stop_button
;
97 GtkWidget
*username_label
;
98 GtkWidget
*username_entry
;
99 GtkWidget
*password_label
;
100 GtkWidget
*password_entry
;
101 GtkWidget
*channel_dir_label
;
102 GtkWidget
*channel_dir_entry
;
103 GtkWidget
*trace_dir_label
;
104 GtkWidget
*trace_dir_entry
;
105 GtkWidget
*trace_name_label
;
106 GtkWidget
*trace_name_entry
;
107 GtkWidget
*trace_mode_label
;
108 GtkWidget
*trace_mode_combo
;
109 GtkWidget
*start_daemon_label
;
110 GtkWidget
*start_daemon_check
;
111 GtkWidget
*append_label
;
112 GtkWidget
*append_check
;
113 GtkWidget
*optional_label
;
114 GtkWidget
*subbuf_size_label
;
115 GtkWidget
*subbuf_size_entry
;
116 GtkWidget
*subbuf_num_label
;
117 GtkWidget
*subbuf_num_entry
;
118 GtkWidget
*lttctl_path_label
;
119 GtkWidget
*lttctl_path_entry
;
120 GtkWidget
*lttd_path_label
;
121 GtkWidget
*lttd_path_entry
;
122 GtkWidget
*fac_path_label
;
123 GtkWidget
*fac_path_entry
;
127 * @fn GtkWidget* guicontrol_get_widget(ControlData*)
129 * This function returns the current main widget
130 * used by this module
131 * @param tcd the module struct
132 * @return The main widget
135 guicontrol_get_widget(ControlData
*tcd
)
141 * @fn ControlData* gui_control(Tab*)
143 * Constructor is used to create ControlData data structure.
144 * @param tab The tab structure used by the widget
145 * @return The Filter viewer data created.
148 gui_control(Tab
*tab
)
150 g_debug("filter::gui_control()");
153 GtkCellRenderer
*renderer
;
154 GtkTreeViewColumn
*column
;
156 ControlData
* tcd
= g_new(ControlData
,1);
160 tcd
->window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
161 gtk_window_set_title(GTK_WINDOW(tcd
->window
), "LTTng Trace Control");
163 * Initiating GtkTable layout
164 * starts with 2 rows and 5 columns and
165 * expands when expressions added
167 tcd
->main_box
= gtk_table_new(14,7,FALSE
);
168 gtk_table_set_row_spacings(GTK_TABLE(tcd
->main_box
),5);
169 gtk_table_set_col_spacings(GTK_TABLE(tcd
->main_box
),5);
171 gtk_container_add(GTK_CONTAINER(tcd
->window
), GTK_WIDGET(tcd
->main_box
));
173 GList
*focus_chain
= NULL
;
176 * start/pause/stop buttons
180 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStart_xpm
);
181 image
= gtk_image_new_from_pixbuf(pixbuf
);
182 tcd
->start_button
= gtk_button_new_with_label("start");
183 gtk_button_set_image(GTK_BUTTON(tcd
->start_button
), image
);
184 gtk_button_set_alignment(GTK_BUTTON(tcd
->start_button
), 0.0, 0.0);
185 gtk_widget_show (tcd
->start_button
);
186 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->start_button
,6,7,0,1,GTK_FILL
,GTK_FILL
,2,2);
188 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm
);
189 image
= gtk_image_new_from_pixbuf(pixbuf
);
190 tcd
->pause_button
= gtk_button_new_with_label("pause");
191 gtk_button_set_image(GTK_BUTTON(tcd
->pause_button
), image
);
192 gtk_button_set_alignment(GTK_BUTTON(tcd
->pause_button
), 0.0, 0.0);
193 gtk_widget_show (tcd
->pause_button
);
194 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->pause_button
,6,7,1,2,GTK_FILL
,GTK_FILL
,2,2);
196 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlPause_xpm
);
197 image
= gtk_image_new_from_pixbuf(pixbuf
);
198 tcd
->unpause_button
= gtk_button_new_with_label("unpause");
199 gtk_button_set_image(GTK_BUTTON(tcd
->unpause_button
), image
);
200 gtk_button_set_alignment(GTK_BUTTON(tcd
->unpause_button
), 0.0, 0.0);
201 gtk_widget_show (tcd
->unpause_button
);
202 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->unpause_button
,6,7,2,3,GTK_FILL
,GTK_FILL
,2,2);
204 pixbuf
= gdk_pixbuf_new_from_xpm_data((const char **)TraceControlStop_xpm
);
205 image
= gtk_image_new_from_pixbuf(pixbuf
);
206 tcd
->stop_button
= gtk_button_new_with_label("stop");
207 gtk_button_set_image(GTK_BUTTON(tcd
->stop_button
), image
);
208 gtk_button_set_alignment(GTK_BUTTON(tcd
->stop_button
), 0.0, 0.0);
209 gtk_widget_show (tcd
->stop_button
);
210 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->stop_button
,6,7,3,4,GTK_FILL
,GTK_FILL
,2,2);
213 * First half of the filter window
214 * - textual entry of filter expression
215 * - processing button
217 tcd
->username_label
= gtk_label_new("Username:");
218 gtk_widget_show (tcd
->username_label
);
219 tcd
->username_entry
= gtk_entry_new();
220 gtk_entry_set_text(GTK_ENTRY(tcd
->username_entry
),"root");
221 gtk_widget_show (tcd
->username_entry
);
222 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->username_label
,0,2,0,1,GTK_FILL
,GTK_FILL
,2,2);
223 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->username_entry
,2,6,0,1,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
227 tcd
->password_label
= gtk_label_new("Password:");
228 gtk_widget_show (tcd
->password_label
);
229 tcd
->password_entry
= gtk_entry_new();
230 gtk_entry_set_visibility(GTK_ENTRY(tcd
->password_entry
), FALSE
);
231 gtk_widget_show (tcd
->password_entry
);
232 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->password_label
,0,2,1,2,GTK_FILL
,GTK_FILL
,2,2);
233 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->password_entry
,2,6,1,2,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
236 tcd
->channel_dir_label
= gtk_label_new("Channel directory:");
237 gtk_widget_show (tcd
->channel_dir_label
);
238 tcd
->channel_dir_entry
= gtk_entry_new();
239 gtk_entry_set_text(GTK_ENTRY(tcd
->channel_dir_entry
),"/mnt/relayfs/ltt");
240 gtk_widget_show (tcd
->channel_dir_entry
);
241 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->channel_dir_label
,0,2,2,3,GTK_FILL
,GTK_FILL
,2,2);
242 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->channel_dir_entry
,2,6,2,3,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
244 tcd
->trace_dir_label
= gtk_label_new("Trace directory:");
245 gtk_widget_show (tcd
->trace_dir_label
);
246 tcd
->trace_dir_entry
= gtk_entry_new();
247 gtk_entry_set_text(GTK_ENTRY(tcd
->trace_dir_entry
),"/tmp/trace1");
248 gtk_widget_show (tcd
->trace_dir_entry
);
249 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_dir_label
,0,2,3,4,GTK_FILL
,GTK_FILL
,2,2);
250 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_dir_entry
,2,6,3,4,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
252 tcd
->trace_name_label
= gtk_label_new("Trace name:");
253 gtk_widget_show (tcd
->trace_name_label
);
254 tcd
->trace_name_entry
= gtk_entry_new();
255 gtk_entry_set_text(GTK_ENTRY(tcd
->trace_name_entry
),"trace");
256 gtk_widget_show (tcd
->trace_name_entry
);
257 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_name_label
,0,2,4,5,GTK_FILL
,GTK_FILL
,2,2);
258 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_name_entry
,2,6,4,5,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
260 tcd
->trace_mode_label
= gtk_label_new("Trace mode ");
261 gtk_widget_show (tcd
->trace_mode_label
);
262 tcd
->trace_mode_combo
= gtk_combo_box_new_text();
263 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd
->trace_mode_combo
),
265 gtk_combo_box_append_text(GTK_COMBO_BOX(tcd
->trace_mode_combo
),
267 gtk_combo_box_set_active(GTK_COMBO_BOX(tcd
->trace_mode_combo
), 0);
268 gtk_widget_show (tcd
->trace_mode_combo
);
269 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_mode_label
,0,2,5,6,GTK_FILL
,GTK_FILL
,2,2);
270 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->trace_mode_combo
,2,6,5,6,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
272 tcd
->start_daemon_label
= gtk_label_new("Start daemon ");
273 gtk_widget_show (tcd
->start_daemon_label
);
274 tcd
->start_daemon_check
= gtk_check_button_new();
275 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd
->start_daemon_check
), TRUE
);
276 gtk_widget_show (tcd
->start_daemon_check
);
277 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->start_daemon_label
,0,2,6,7,GTK_FILL
,GTK_FILL
,2,2);
278 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->start_daemon_check
,2,6,6,7,GTK_FILL
,GTK_FILL
,0,0);
280 tcd
->append_label
= gtk_label_new("Append to trace ");
281 gtk_widget_show (tcd
->append_label
);
282 tcd
->append_check
= gtk_check_button_new();
283 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tcd
->append_check
), FALSE
);
284 gtk_widget_show (tcd
->append_check
);
285 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->append_label
,0,2,7,8,GTK_FILL
,GTK_FILL
,2,2);
286 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->append_check
,2,6,7,8,GTK_FILL
,GTK_FILL
,0,0);
289 tcd
->optional_label
= gtk_label_new("Optional fields ");
290 gtk_widget_show (tcd
->optional_label
);
291 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->optional_label
,0,6,8,9,GTK_FILL
,GTK_FILL
,2,2);
293 tcd
->subbuf_size_label
= gtk_label_new("Subbuffer size:");
294 gtk_widget_show (tcd
->subbuf_size_label
);
295 tcd
->subbuf_size_entry
= gtk_entry_new();
296 gtk_widget_show (tcd
->subbuf_size_entry
);
297 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->subbuf_size_label
,0,2,9,10,GTK_FILL
,GTK_FILL
,2,2);
298 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->subbuf_size_entry
,2,6,9,10,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
300 tcd
->subbuf_num_label
= gtk_label_new("Number of subbuffers:");
301 gtk_widget_show (tcd
->subbuf_num_label
);
302 tcd
->subbuf_num_entry
= gtk_entry_new();
303 gtk_widget_show (tcd
->subbuf_num_entry
);
304 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->subbuf_num_label
,0,2,10,11,GTK_FILL
,GTK_FILL
,2,2);
305 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->subbuf_num_entry
,2,6,10,11,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
307 tcd
->lttctl_path_label
= gtk_label_new("path to lttctl:");
308 gtk_widget_show (tcd
->lttctl_path_label
);
309 tcd
->lttctl_path_entry
= gtk_entry_new();
310 gtk_entry_set_text(GTK_ENTRY(tcd
->lttctl_path_entry
),PACKAGE_BIN_DIR
"/lttctl");
311 gtk_widget_show (tcd
->lttctl_path_entry
);
312 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->lttctl_path_label
,0,2,11,12,GTK_FILL
,GTK_FILL
,2,2);
313 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->lttctl_path_entry
,2,6,11,12,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
316 tcd
->lttd_path_label
= gtk_label_new("path to lttd:");
317 gtk_widget_show (tcd
->lttd_path_label
);
318 tcd
->lttd_path_entry
= gtk_entry_new();
319 gtk_entry_set_text(GTK_ENTRY(tcd
->lttd_path_entry
),PACKAGE_BIN_DIR
"/lttd");
320 gtk_widget_show (tcd
->lttd_path_entry
);
321 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->lttd_path_label
,0,2,12,13,GTK_FILL
,GTK_FILL
,2,2);
322 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->lttd_path_entry
,2,6,12,13,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
325 tcd
->fac_path_label
= gtk_label_new("path to facilities:");
326 gtk_widget_show (tcd
->fac_path_label
);
327 tcd
->fac_path_entry
= gtk_entry_new();
328 gtk_entry_set_text(GTK_ENTRY(tcd
->fac_path_entry
),PACKAGE_DATA_DIR
"/" PACKAGE
"/facilities");
329 gtk_widget_set_size_request(tcd
->fac_path_entry
, 250, -1);
330 gtk_widget_show (tcd
->fac_path_entry
);
331 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->fac_path_label
,0,2,13,14,GTK_FILL
,GTK_FILL
,2,2);
332 gtk_table_attach( GTK_TABLE(tcd
->main_box
),tcd
->fac_path_entry
,2,6,13,14,GTK_FILL
|GTK_EXPAND
|GTK_SHRINK
,GTK_FILL
,0,0);
334 focus_chain
= g_list_append (focus_chain
, tcd
->username_entry
);
335 focus_chain
= g_list_append (focus_chain
, tcd
->password_entry
);
336 focus_chain
= g_list_append (focus_chain
, tcd
->start_button
);
337 focus_chain
= g_list_append (focus_chain
, tcd
->pause_button
);
338 focus_chain
= g_list_append (focus_chain
, tcd
->unpause_button
);
339 focus_chain
= g_list_append (focus_chain
, tcd
->stop_button
);
340 focus_chain
= g_list_append (focus_chain
, tcd
->channel_dir_entry
);
341 focus_chain
= g_list_append (focus_chain
, tcd
->trace_dir_entry
);
342 focus_chain
= g_list_append (focus_chain
, tcd
->trace_name_entry
);
343 focus_chain
= g_list_append (focus_chain
, tcd
->trace_mode_combo
);
344 focus_chain
= g_list_append (focus_chain
, tcd
->start_daemon_check
);
345 focus_chain
= g_list_append (focus_chain
, tcd
->append_check
);
346 focus_chain
= g_list_append (focus_chain
, tcd
->subbuf_size_entry
);
347 focus_chain
= g_list_append (focus_chain
, tcd
->subbuf_num_entry
);
348 focus_chain
= g_list_append (focus_chain
, tcd
->lttctl_path_entry
);
349 focus_chain
= g_list_append (focus_chain
, tcd
->lttd_path_entry
);
350 focus_chain
= g_list_append (focus_chain
, tcd
->fac_path_entry
);
352 gtk_container_set_focus_chain(GTK_CONTAINER(tcd
->main_box
), focus_chain
);
354 g_signal_connect(G_OBJECT(tcd
->start_button
), "clicked",
355 (GCallback
)start_clicked
, tcd
);
356 g_signal_connect(G_OBJECT(tcd
->pause_button
), "clicked",
357 (GCallback
)pause_clicked
, tcd
);
358 g_signal_connect(G_OBJECT(tcd
->unpause_button
), "clicked",
359 (GCallback
)unpause_clicked
, tcd
);
360 g_signal_connect(G_OBJECT(tcd
->stop_button
), "clicked",
361 (GCallback
)stop_clicked
, tcd
);
364 * show main container
366 gtk_widget_show(tcd
->main_box
);
367 gtk_widget_show(tcd
->window
);
370 g_object_set_data_full(
371 G_OBJECT(guicontrol_get_widget(tcd
)),
372 "control_viewer_data",
374 (GDestroyNotify
)gui_control_destructor
);
376 g_control_list
= g_slist_append(
385 * @fn void gui_control_destructor(ControlData*)
387 * Destructor for the filter gui module
388 * @param tcd The module structure
391 gui_control_destructor(ControlData
*tcd
)
395 /* May already been done by GTK window closing */
396 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd
))){
397 g_info("widget still exists");
400 // lttvwindow_unregister_traceset_notify(tcd->tab,
401 // filter_traceset_changed,
402 // filter_viewer_data);
404 lttvwindowtraces_background_notify_remove(tcd
);
406 g_control_list
= g_slist_remove(g_control_list
, tcd
);
411 static void execute_command(const gchar
*command
, const gchar
*username
,
412 const gchar
*password
, const gchar
*lttd_path
, const gchar
*fac_path
)
416 pid
= forkpty(&fdpty
, NULL
, NULL
, NULL
);
423 /* discuss with su */
424 struct timeval timeout
;
428 struct pollfd pollfd
;
433 /* Read the output from the child terminal before the prompt. If no data in
434 * 200 ms, we stop reading to give the password */
435 g_info("Reading from child console...");
438 pollfd
.events
= POLLIN
|POLLPRI
;
440 num_rdy
= poll(&pollfd
, 1, 200);
443 perror("Poll error");
448 /* Timeout : stop waiting for chars */
449 if(num_rdy
== 0) break;
451 switch(pollfd
.revents
) {
453 g_warning("Error returned in polling fd\n");
457 g_info("Polling FD : hung up.");
461 g_warning("Polling fd tells it is not open");
466 count
= read (fdpty
, buf
, 256);
470 } else if(count
== -1) {
471 perror("Error in read");
477 g_warning("Child hung up too fast");
482 /* Write the password */
483 g_info("Got su prompt, now writing password...");
485 ret
= write(fdpty
, password
, strlen(password
));
486 if(ret
< 0) perror("Error in write");
487 ret
= write(fdpty
, "\n", 1);
488 if(ret
< 0) perror("Error in write");
491 /* Take the output from the terminal and show it on the real console */
492 g_info("Getting data from child terminal...");
496 pollfd
.events
= POLLIN
|POLLPRI
;
498 num_rdy
= poll(&pollfd
, 1, -1);
501 perror("Poll error");
505 if(num_rdy
== 0) break;
507 switch(pollfd
.revents
) {
509 g_warning("Error returned in polling fd\n");
513 g_info("Polling FD : hung up.");
517 g_warning("Polling fd tells it is not open");
522 count
= read (fdpty
, buf
, 256);
526 } else if(count
== -1) {
527 perror("Error in read");
532 if(num_hup
> 0) goto wait_child
;
535 g_info("Waiting for child exit...");
537 ret
= waitpid(pid
, &status
, 0);
540 if(WEXITSTATUS(ret
) != 0)
541 g_warning("An error occured in the su command : %s",
542 strerror(WEXITSTATUS(ret
)));
544 g_info("Child exited.");
546 } else if(pid
== 0) {
547 /* Setup environment variables */
548 if(strcmp(lttd_path
, "") != 0)
549 setenv("LTT_DAEMON", lttd_path
, 1);
550 if(strcmp(fac_path
, "") != 0)
551 setenv("LTT_FACILITIES", fac_path
, 1);
553 g_message("Executing (as %s) : %s\n", username
, command
);
555 execlp("su", "su", "-p", "-c", command
, username
, NULL
);
556 exit(-1); /* not supposed to happen! */
558 //gint ret = execvp();
562 g_warning("Error happened when forking for su");
570 void start_clicked (GtkButton
*button
, gpointer user_data
)
572 ControlData
*tcd
= (ControlData
*)user_data
;
574 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
575 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
576 const gchar
*channel_dir
=
577 gtk_entry_get_text(GTK_ENTRY(tcd
->channel_dir_entry
));
578 const gchar
*trace_dir
= gtk_entry_get_text(GTK_ENTRY(tcd
->trace_dir_entry
));
579 const gchar
*trace_name
=
580 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
582 const gchar
*trace_mode_sel
=
583 gtk_combo_box_get_active_text(GTK_COMBO_BOX(tcd
->trace_mode_combo
));
584 const gchar
*trace_mode
;
585 if(strcmp(trace_mode_sel
, "normal") == 0)
586 trace_mode
= "normal";
588 trace_mode
= "flight";
590 gboolean start_daemon
=
591 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd
->start_daemon_check
));
594 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tcd
->append_check
));
596 const gchar
*subbuf_size
=
597 gtk_entry_get_text(GTK_ENTRY(tcd
->subbuf_size_entry
));
598 const gchar
*subbuf_num
=
599 gtk_entry_get_text(GTK_ENTRY(tcd
->subbuf_num_entry
));
600 const gchar
*lttctl_path
=
601 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
602 const gchar
*lttd_path
= gtk_entry_get_text(GTK_ENTRY(tcd
->lttd_path_entry
));
603 const gchar
*fac_path
= gtk_entry_get_text(GTK_ENTRY(tcd
->fac_path_entry
));
606 /* Setup arguments to su */
608 gchar args
[MAX_ARGS_LEN
];
609 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
614 strncat(args
, "exec", args_left
);
615 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
618 strncat(args
, " ", args_left
);
619 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
621 if(strcmp(lttctl_path
, "") == 0)
622 strncat(args
, "lttctl", args_left
);
624 strncat(args
, lttctl_path
, args_left
);
625 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
628 strncat(args
, " ", args_left
);
629 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
632 strncat(args
, "-l ", args_left
);
633 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
634 strncat(args
, channel_dir
, args_left
);
635 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
638 strncat(args
, " ", args_left
);
639 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
642 strncat(args
, "-t ", args_left
);
643 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
644 strncat(args
, trace_dir
, args_left
);
645 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
648 strncat(args
, " ", args_left
);
649 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
652 strncat(args
, "-n ", args_left
);
653 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
654 strncat(args
, trace_name
, args_left
);
655 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
658 strncat(args
, " ", args_left
);
659 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
662 strncat(args
, "-m ", args_left
);
663 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
664 strncat(args
, trace_mode
, args_left
);
665 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
668 strncat(args
, " ", args_left
);
669 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
673 strncat(args
, "-d", args_left
);
674 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
676 /* Simply create the channel and then start tracing */
677 strncat(args
, "-b", args_left
);
678 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
682 /* Append to trace ? */
685 strncat(args
, " ", args_left
);
686 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
687 strncat(args
, "-a", args_left
);
688 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
691 /* optional arguments */
693 if(strcmp(subbuf_size
, "") != 0) {
695 strncat(args
, " ", args_left
);
696 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
698 strncat(args
, "-z ", args_left
);
699 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
700 strncat(args
, subbuf_size
, args_left
);
701 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
704 /* number of subbuffers */
705 if(strcmp(subbuf_num
, "") != 0) {
707 strncat(args
, " ", args_left
);
708 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
710 strncat(args
, "-x ", args_left
);
711 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
712 strncat(args
, subbuf_num
, args_left
);
713 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
717 execute_command(args
, username
, password
, lttd_path
, fac_path
);
723 void pause_clicked (GtkButton
*button
, gpointer user_data
)
725 ControlData
*tcd
= (ControlData
*)user_data
;
727 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
728 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
729 const gchar
*trace_name
=
730 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
731 const gchar
*lttd_path
= "";
732 const gchar
*fac_path
= "";
734 const gchar
*lttctl_path
=
735 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
737 /* Setup arguments to su */
739 gchar args
[MAX_ARGS_LEN
];
740 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
745 strncat(args
, "exec", args_left
);
746 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
749 strncat(args
, " ", args_left
);
750 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
752 if(strcmp(lttctl_path
, "") == 0)
753 strncat(args
, "lttctl", args_left
);
755 strncat(args
, lttctl_path
, args_left
);
756 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
759 strncat(args
, " ", args_left
);
760 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
763 strncat(args
, "-n ", args_left
);
764 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
765 strncat(args
, trace_name
, args_left
);
766 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
769 strncat(args
, " ", args_left
);
770 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
772 /* Simply pause tracing */
773 strncat(args
, "-q", args_left
);
774 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
776 execute_command(args
, username
, password
, lttd_path
, fac_path
);
780 void unpause_clicked (GtkButton
*button
, gpointer user_data
)
782 ControlData
*tcd
= (ControlData
*)user_data
;
784 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
785 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
786 const gchar
*trace_name
=
787 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
788 const gchar
*lttd_path
= "";
789 const gchar
*fac_path
= "";
791 const gchar
*lttctl_path
=
792 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
794 /* Setup arguments to su */
796 gchar args
[MAX_ARGS_LEN
];
797 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
802 strncat(args
, "exec", args_left
);
803 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
806 strncat(args
, " ", args_left
);
807 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
809 if(strcmp(lttctl_path
, "") == 0)
810 strncat(args
, "lttctl", args_left
);
812 strncat(args
, lttctl_path
, args_left
);
813 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
816 strncat(args
, " ", args_left
);
817 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
820 strncat(args
, "-n ", args_left
);
821 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
822 strncat(args
, trace_name
, args_left
);
823 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
826 strncat(args
, " ", args_left
);
827 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
829 /* Simply unpause tracing */
830 strncat(args
, "-s", args_left
);
831 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
833 execute_command(args
, username
, password
, lttd_path
, fac_path
);
836 void stop_clicked (GtkButton
*button
, gpointer user_data
)
838 ControlData
*tcd
= (ControlData
*)user_data
;
840 const gchar
*username
= gtk_entry_get_text(GTK_ENTRY(tcd
->username_entry
));
841 const gchar
*password
= gtk_entry_get_text(GTK_ENTRY(tcd
->password_entry
));
842 const gchar
*trace_name
=
843 gtk_entry_get_text(GTK_ENTRY(tcd
->trace_name_entry
));
844 const gchar
*lttd_path
= "";
845 const gchar
*fac_path
= "";
847 const gchar
*lttctl_path
=
848 gtk_entry_get_text(GTK_ENTRY(tcd
->lttctl_path_entry
));
849 const gchar
*trace_dir
= gtk_entry_get_text(GTK_ENTRY(tcd
->trace_dir_entry
));
851 /* Setup arguments to su */
853 gchar args
[MAX_ARGS_LEN
];
854 gint args_left
= MAX_ARGS_LEN
- 1; /* for \0 */
859 strncat(args
, "exec", args_left
);
860 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
863 strncat(args
, " ", args_left
);
864 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
866 if(strcmp(lttctl_path
, "") == 0)
867 strncat(args
, "lttctl", args_left
);
869 strncat(args
, lttctl_path
, args_left
);
870 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
873 strncat(args
, " ", args_left
);
874 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
877 strncat(args
, "-n ", args_left
);
878 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
879 strncat(args
, trace_name
, args_left
);
880 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
883 strncat(args
, " ", args_left
);
884 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
886 /* Simply stop tracing and destroy channel */
887 strncat(args
, "-R", args_left
);
888 args_left
= MAX_ARGS_LEN
- strlen(args
) - 1;
890 execute_command(args
, username
, password
, lttd_path
, fac_path
);
893 /* Ask to the user if he wants to open the trace in a new window */
898 dialogue
= gtk_dialog_new_with_buttons("Open trace ?",
899 GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(button
))),
900 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
901 GTK_STOCK_YES
,GTK_RESPONSE_ACCEPT
,
902 GTK_STOCK_NO
,GTK_RESPONSE_REJECT
,
904 label
= gtk_label_new("Do you want to open the trace in LTTV ?");
905 gtk_widget_show(label
);
907 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialogue
)->vbox
),
910 id
= gtk_dialog_run(GTK_DIALOG(dialogue
));
913 case GTK_RESPONSE_ACCEPT
:
915 create_main_window_with_trace(trace_dir
);
918 case GTK_RESPONSE_REJECT
:
922 gtk_widget_destroy(dialogue
);
928 * @fn GtkWidget* h_guicontrol(Tab*)
930 * Control Module's constructor hook
932 * This constructor is given as a parameter to the menuitem and toolbar button
933 * registration. It creates the list.
934 * @param tab A pointer to the parent window.
935 * @return The widget created.
938 h_guicontrol(Tab
*tab
)
940 ControlData
* f
= gui_control(tab
) ;
946 * @fn static void init()
948 * This function initializes the Filter Viewer functionnality through the
953 lttvwindow_register_constructor("guicontrol",
955 "Insert Tracing Control Module",
956 hTraceControlInsert_xpm
,
957 "Insert Tracing Control Module",
962 * @fn void control_destroy_walk(gpointer,gpointer)
964 * Initiate the destruction of the current gui module
965 * on the GTK Interface
968 control_destroy_walk(gpointer data
, gpointer user_data
)
970 ControlData
*tcd
= (ControlData
*)data
;
972 g_debug("traceontrol.c : control_destroy_walk, %p", tcd
);
974 /* May already have been done by GTK window closing */
975 if(GTK_IS_WIDGET(guicontrol_get_widget(tcd
)))
976 gtk_widget_destroy(guicontrol_get_widget(tcd
));
980 * @fn static void destroy()
981 * @brief plugin's destroy function
983 * This function releases the memory reserved by the module and unregisters
984 * everything that has been registered in the gtkTraceSet API.
986 static void destroy() {
988 g_slist_foreach(g_control_list
, control_destroy_walk
, NULL
);
990 lttvwindow_unregister_constructor(h_guicontrol
);
995 LTTV_MODULE("guitracecontrol", "Trace Control Window", \
996 "Graphical module that let user control kernel tracing", \
997 init
, destroy
, "lttvwindow")