4 * (c) 2006, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 static const funnel_ops_t* ops = NULL;
31 struct _lua_menu_data {
37 static int menu_cb_error_handler(lua_State* L) {
38 const gchar* error = lua_tostring(L,1);
39 report_failure("Lua: Error During execution of Menu Callback:\n %s",error);
43 ELUA_FUNCTION lua_gui_enabled(lua_State* L) { /* Checks whether the GUI facility is enabled. */
44 lua_pushboolean(L,GPOINTER_TO_INT(ops));
45 ELUA_RETURN(1); /* A boolean: true if it is enabled, false if it isn't. */
48 void lua_menu_callback(gpointer data) {
49 struct _lua_menu_data* md = data;
51 lua_pushcfunction(md->L,menu_cb_error_handler);
52 lua_rawgeti(md->L, LUA_REGISTRYINDEX, md->cb_ref);
53 lua_rawgeti(md->L, LUA_REGISTRYINDEX, md->data_ref);
55 lua_pcall(md->L,1,0,1);
60 ELUA_FUNCTION elua_register_menu(lua_State* L) { /* Register a menu item in the Statistics menu. */
61 #define ELUA_ARG_register_menu_NAME 1 /* The name of the menu item. */
62 #define ELUA_ARG_register_menu_ACTION 2 /* The function to be called when the menu item is invoked. */
63 #define ELUA_OPTARG_register_menu_USERDATA 3 /* To be passed to the action. */
65 const gchar* name = luaL_checkstring(L,ELUA_ARG_register_menu_NAME);
66 struct _lua_menu_data* md;
67 gboolean retap = FALSE;
70 ELUA_ARG_ERROR(register_menu,NAME,"must be a string");
72 if (!lua_isfunction(L,ELUA_ARG_register_menu_ACTION))
73 ELUA_ARG_ERROR(register_menu,ACTION,"must be a function");
75 md = g_malloc(sizeof(struct _lua_menu_data));
79 md->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
81 if ( lua_gettop(L) > 2) {
82 lua_pushvalue(L, ELUA_OPTARG_register_menu_USERDATA);
83 md->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
85 md->data_ref = LUA_NOREF;
88 funnel_register_menu(name,
89 REGISTER_STAT_GROUP_GENERIC,
100 struct _dlg_cb_data {
106 static int dlg_cb_error_handler(lua_State* L) {
107 const gchar* error = lua_tostring(L,1);
108 report_failure("Lua: Error During execution of dialog callback:\n %s",error);
112 static void lua_dialog_cb(gchar** user_input, void* data) {
113 struct _dlg_cb_data* dcbd = data;
116 lua_State* L = dcbd->L;
119 lua_pushcfunction(L,dlg_cb_error_handler);
120 lua_rawgeti(L, LUA_REGISTRYINDEX, dcbd->func_ref);
121 lua_rawgeti(L, LUA_REGISTRYINDEX, dcbd->data_ref);
123 for (i = 0; (input = user_input[i]) ; i++) {
124 lua_pushstring(L,input);
130 switch ( lua_pcall(L,i+1,0,1) ) {
134 g_warning("Runtime error while calling dialog callback");
137 g_warning("Memory alloc error while calling dialog callback");
140 g_assert_not_reached();
146 ELUA_FUNCTION elua_new_dialog(lua_State* L) { /* Pops up a new dialog */
147 #define ELUA_ARG_new_dialog_TITLE 1 /* Title of the dialog's window. */
148 #define ELUA_ARG_new_dialog_ACTION 2 /* Action to be performed when OKd. */
149 /* ELUA_MOREARGS new_dialog A series of strings to be used as labels of the dialog's fields */
152 int top = lua_gettop(L);
155 struct _dlg_cb_data* dcbd;
158 luaL_error(L,"the GUI facility has to be enabled");
162 if (! (title = luaL_checkstring(L,ELUA_ARG_new_dialog_TITLE)) ) {
163 ELUA_ARG_ERROR(new_dialog,TITLE,"must be a string");
167 if (! lua_isfunction(L,ELUA_ARG_new_dialog_ACTION)) {
168 ELUA_ARG_ERROR(new_dialog,ACTION,"must be a function");
173 ELUA_ERROR(new_dialog,"at least one field required");
178 dcbd = g_malloc(sizeof(struct _dlg_cb_data));
184 dcbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
188 dcbd->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
191 labels = g_ptr_array_new();
195 for (i = 1; i <= top; i++) {
196 gchar* label = (void*)luaL_checkstring(L,i);
198 /* XXX leaks labels on error */
200 ELUA_ERROR(new_dialog,"all fields must be strings");
202 g_ptr_array_add(labels,label);
205 g_ptr_array_add(labels,NULL);
207 ops->new_dialog(title, (const gchar**)labels->pdata, lua_dialog_cb, dcbd);
209 g_ptr_array_free(labels,TRUE);
216 ELUA_CLASS_DEFINE(TextWindow,NOP) /* Manages a text window. */
218 ELUA_CONSTRUCTOR TextWindow_new(lua_State* L) { /* Creates a new TextWindow. */
219 #define ELUA_OPTARG_TextWindow_new_TITLE 1 /* Title of the new window. */
224 title = luaL_optstring(L,ELUA_OPTARG_TextWindow_new_TITLE,"Untitled Window");
225 tw = ops->new_text_window(title);
226 pushTextWindow(L,tw);
228 ELUA_RETURN(1); /* The newly created TextWindow object. */
231 struct _close_cb_data {
237 int text_win_close_cb_error_handler(lua_State* L) {
238 const gchar* error = lua_tostring(L,1);
239 report_failure("Lua: Error During execution of TextWindow close callback:\n %s",error);
243 static void text_win_close_cb(void* data) {
244 struct _close_cb_data* cbd = data;
245 lua_State* L = cbd->L;
247 lua_pushcfunction(L,text_win_close_cb_error_handler);
248 lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->func_ref);
249 lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->data_ref);
251 switch ( lua_pcall(L,1,0,1) ) {
255 g_warning("Runtime error during execution of TextWindow close callback");
258 g_warning("Memory alloc error during execution of TextWindow close callback");
261 g_assert_not_reached();
266 ELUA_METHOD TextWindow_set_atclose(lua_State* L) { /* Set the function that will be called when the window closes */
267 #define ELUA_ARG_TextWindow_at_close_ACTION 2 /* A function to be executed when the user closes the window */
269 TextWindow tw = checkTextWindow(L,1);
270 struct _close_cb_data* cbd;
273 ELUA_ERROR(TextWindow_at_close,"cannot be called for something not a TextWindow");
277 if (! lua_isfunction(L,2))
278 ELUA_ARG_ERROR(TextWindow_at_close,ACTION,"must be a function");
280 cbd = g_malloc(sizeof(struct _close_cb_data));
283 cbd->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
284 cbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
286 ops->set_close_cb(tw,text_win_close_cb,cbd);
288 pushTextWindow(L,tw);
289 ELUA_RETURN(1); /* The TextWindow object. */
292 ELUA_METHOD TextWindow_set(lua_State* L) { /* Sets the text. */
293 #define ELUA_ARG_TextWindow_set_TEXT 2 /* The text to be used. */
295 TextWindow tw = checkTextWindow(L,1);
296 const gchar* text = luaL_checkstring(L,2);
299 ELUA_ERROR(TextWindow_set,"cannot be called for something not a TextWindow");
302 ELUA_ARG_ERROR(TextWindow_set,TEXT,"must be a string");
304 ops->set_text(tw,text);
306 pushTextWindow(L,tw);
307 ELUA_RETURN(1); /* The TextWindow object. */
310 ELUA_METHOD TextWindow_append(lua_State* L) { /* Appends text */
311 #define ELUA_ARG_TextWindow_append_TEXT 2 /* The text to be appended */
312 TextWindow tw = checkTextWindow(L,1);
313 const gchar* text = luaL_checkstring(L,2);
316 ELUA_ERROR(TextWindow_append,"cannot be called for something not a TextWindow");
319 ELUA_ARG_ERROR(TextWindow_append,TEXT,"must be a string");
321 ops->append_text(tw,text);
323 pushTextWindow(L,tw);
324 ELUA_RETURN(1); /* The TextWindow object. */
327 ELUA_METHOD TextWindow_prepend(lua_State* L) { /* Prepends text */
328 #define ELUA_ARG_TextWindow_prepend_TEXT 2 /* The text to be appended */
329 TextWindow tw = checkTextWindow(L,1);
330 const gchar* text = luaL_checkstring(L,2);
333 ELUA_ERROR(TextWindow_prepend,"cannot be called for something not a TextWindow");
336 ELUA_ARG_ERROR(TextWindow_prepend,TEXT,"must be a string");
338 ops->prepend_text(tw,text);
340 pushTextWindow(L,tw);
341 ELUA_RETURN(1); /* The TextWindow object. */
344 ELUA_METHOD TextWindow_clear(lua_State* L) { /* Errases all text in the window. */
345 TextWindow tw = checkTextWindow(L,1);
348 ELUA_ERROR(TextWindow_clear,"cannot be called for something not a TextWindow");
352 pushTextWindow(L,tw);
353 ELUA_RETURN(1); /* The TextWindow object. */
356 ELUA_METHOD TextWindow_get_text(lua_State* L) { /* Get the text of the window */
357 TextWindow tw = checkTextWindow(L,1);
361 ELUA_ERROR(TextWindow_get_text,"cannot be called for something not a TextWindow");
363 text = ops->get_text(tw);
365 lua_pushstring(L,text);
366 ELUA_RETURN(1); /* The TextWindow's text. */
369 static int TextWindow__gc(lua_State* L) {
370 TextWindow tw = checkTextWindow(L,1);
373 ELUA_ERROR(TextWindow_gc,"cannot be called for something not a TextWindow");
375 ops->destroy_text_window(tw);
379 ELUA_METHOD TextWindow_set_editable(lua_State* L) { /* Set the function that will be called when the window closes */
380 #define ELUA_OPTARG_TextWindow_at_close_EDITABLE 2 /* A boolean flag, defaults to true */
382 TextWindow tw = checkTextWindow(L,1);
383 gboolean editable = luaL_optint(L,2,1);
386 ELUA_ERROR(TextWindow_at_close,"cannot be called for something not a TextWindow");
388 if (ops->set_editable)
389 ops->set_editable(tw,editable);
391 pushTextWindow(L,tw);
392 ELUA_RETURN(1); /* The TextWindow object. */
395 typedef struct _elua_bt_cb_t {
401 static gboolean elua_button_callback(funnel_text_window_t* tw, void* data) {
402 elua_bt_cb_t* cbd = data;
403 lua_State* L = cbd->L;
406 lua_pushcfunction(L,dlg_cb_error_handler);
407 lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->func_ref);
408 pushTextWindow(L,tw);
409 lua_rawgeti(L, LUA_REGISTRYINDEX, cbd->data_ref);
411 switch ( lua_pcall(L,2,0,1) ) {
415 g_warning("Runtime error while calling button callback");
418 g_warning("Memory alloc error while calling button callback");
421 g_assert_not_reached();
428 ELUA_METHOD TextWindow_add_button(lua_State* L) {
429 #define ELUA_ARG_TextWindow_add_button_LABEL 2 /* The label of the button */
430 #define ELUA_ARG_TextWindow_add_button_FUNCTION 3 /* The function to be called when clicked */
431 #define ELUA_ARG_TextWindow_add_button_DATA 4 /* The data to be passed to the function (other than the window) */
432 TextWindow tw = checkTextWindow(L,1);
433 const gchar* label = luaL_checkstring(L,ELUA_ARG_TextWindow_add_button_LABEL);
439 ELUA_ERROR(TextWindow_at_close,"cannot be called for something not a TextWindow");
441 if (! lua_isfunction(L,ELUA_ARG_TextWindow_add_button_FUNCTION) )
442 ELUA_ARG_ERROR(TextWindow_add_button,FUNCTION,"must be a function");
446 if (ops->add_button) {
447 fbt = ep_alloc(sizeof(funnel_bt_t));
448 cbd = ep_alloc(sizeof(elua_bt_cb_t));
451 fbt->func = elua_button_callback;
455 cbd->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
456 cbd->func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
458 ops->add_button(tw,fbt,label);
461 pushTextWindow(L,tw);
462 ELUA_RETURN(1); /* The TextWindow object. */
465 ELUA_METHODS TextWindow_methods[] = {
466 ELUA_CLASS_FNREG(TextWindow,new),
467 ELUA_CLASS_FNREG(TextWindow,set),
468 ELUA_CLASS_FNREG(TextWindow,new),
469 ELUA_CLASS_FNREG(TextWindow,append),
470 ELUA_CLASS_FNREG(TextWindow,prepend),
471 ELUA_CLASS_FNREG(TextWindow,clear),
472 ELUA_CLASS_FNREG(TextWindow,set_atclose),
473 ELUA_CLASS_FNREG(TextWindow,set_editable),
474 ELUA_CLASS_FNREG(TextWindow,get_text),
475 ELUA_CLASS_FNREG(TextWindow,add_button),
479 ELUA_META TextWindow_meta[] = {
480 {"__tostring", TextWindow_get_text},
481 {"__gc", TextWindow__gc},
485 int TextWindow_register(lua_State* L) {
487 ops = funnel_get_funnel_ops();
489 ELUA_REGISTER_CLASS(TextWindow);
495 ELUA_FUNCTION elua_retap_packets(lua_State* L) {
497 Rescan all packets and just run taps - don't reconstruct the display.
499 if ( ops->retap_packets ) {
500 ops->retap_packets();
502 ELUA_ERROR(elua_retap_packets, "does not work on tWireshark");