main.c
changeset 52 50d4e9bc622d
parent 40 4e598287dec4
child 72 d049c92d0809
equal deleted inserted replaced
51:a95a3a73482c 52:50d4e9bc622d
    19 #include "roster.h"      // imstatus2char, foreach_buddy, buddy_*, current_buddy, BUDDATA, ROSTER_TYPE_*
    19 #include "roster.h"      // imstatus2char, foreach_buddy, buddy_*, current_buddy, BUDDATA, ROSTER_TYPE_*
    20 #include "utils.h"       // from_utf8, jidtodisp
    20 #include "utils.h"       // from_utf8, jidtodisp
    21 #include "hooks.h"       // hk_add_handler, hk_del_handler
    21 #include "hooks.h"       // hk_add_handler, hk_del_handler
    22 #include "settings.h"    // settings_set, settings_del, settings_get
    22 #include "settings.h"    // settings_set, settings_del, settings_get
    23 #include "compl.h"       // compl_new_category, compl_add_category_word, compl_del_category_word
    23 #include "compl.h"       // compl_new_category, compl_add_category_word, compl_del_category_word
       
    24 #include "events.h"      // evs_*
    24 
    25 
    25 
    26 
    26 // global lua state object, necessary for uninitialization function
    27 // global lua state object, necessary for uninitialization function
    27 static lua_State *lua = NULL;
    28 static lua_State *lua = NULL;
    28 
    29 
   521 	if (el) {
   522 	if (el) {
   522 		g_free (el->data);
   523 		g_free (el->data);
   523 		lua_added_features = g_slist_delete_link (lua_added_features, el);
   524 		lua_added_features = g_slist_delete_link (lua_added_features, el);
   524 	}
   525 	}
   525 	return 0;
   526 	return 0;
       
   527 }
       
   528 
       
   529 // MCABBER EVENTS
       
   530 
       
   531 /// event context
       
   532 /// Enum, indicating what exactly caused event function firing.
       
   533 /// XXX Well, I am not really understand that EVS_* constants mapping semantics,
       
   534 ///     so, I just provide data, obtained by experiment.
       
   535 /// G:
       
   536 static const string2enum_t lua_event_context[] = {
       
   537 	{ "timeout", EVS_CONTEXT_TIMEOUT  },
       
   538 	{ "cancel",  EVS_CONTEXT_CANCEL   },
       
   539 	{ "reject",  EVS_CONTEXT_USER     },
       
   540 	{ "accept",  EVS_CONTEXT_USER + 1 },
       
   541 	{ NULL,      0                    },
       
   542 };
       
   543 
       
   544 typedef struct {
       
   545 	lua_State *L;
       
   546 	int        reference;
       
   547 } lua_event_callback_t;
       
   548 
       
   549 static GSList *lua_events = NULL;
       
   550 
       
   551 /// event function
       
   552 /// Function to be called, when some event state change occurs
       
   553 /// A: event context
       
   554 static int lua_event_callback (eviqs *event, int context)
       
   555 {
       
   556 	lua_event_callback_t *cb = event->data;
       
   557 
       
   558 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
       
   559 	luaL_pushenum (cb->L, context, lua_event_context);
       
   560 	if (lua_pcall (cb->L, 1, 0, 0)) {
       
   561 		scr_LogPrint (LPRINT_LOGNORM, "lua: Event callback execution error: %s", lua_tostring (cb->L, -1));
       
   562 		lua_pop (cb->L, 1);
       
   563 	}
       
   564 
       
   565 	luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
       
   566 	lua_events = g_slist_remove (lua_events, event);
       
   567 	evs_del (event->id); // XXX
       
   568 
       
   569 	return 0; // XXX
       
   570 }
       
   571 
       
   572 /// main.event
       
   573 /// Creates new event. If called without arguments, returns event id list.
       
   574 /// A: event function (optional), integer (expiration timeout, optional), string (description, optional)
       
   575 /// R: string (event id) or nothing (creation error) or table (list of event names)
       
   576 static int lua_main_event (lua_State *L)
       
   577 {
       
   578 	int top = lua_gettop (L);
       
   579 	if (top > 0) { // Create
       
   580 		eviqs                *event;
       
   581 		lua_event_callback_t *cb;
       
   582 		int                   timeout = 0;
       
   583 		char                 *desc    = NULL;
       
   584 		luaL_argcheck (L, lua_type (L, 1) == LUA_TFUNCTION, 1, "event function expected");
       
   585 
       
   586 		if (top > 1) {
       
   587 			timeout = luaL_checkinteger (L, 2);
       
   588 			if (top > 2) {
       
   589 				desc = g_strdup (luaL_checkstring (L, 3)); // g_freed by mcabber
       
   590 				lua_pop (L, 2);
       
   591 			} else
       
   592 				lua_pop (L, 1);
       
   593 		}
       
   594 
       
   595 		event = evs_new (EVS_TYPE_USER, timeout);
       
   596 		if (!event)
       
   597 			return 0;
       
   598 
       
   599 		lua_pushvalue (L, 1);
       
   600 		cb            = g_new (lua_event_callback_t, 1); // g_freed by mcabber
       
   601 		cb->L         = L;
       
   602 		cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
       
   603 
       
   604 		event->data     = cb;
       
   605 		event->callback = lua_event_callback;
       
   606 		event->desc     = desc;
       
   607 
       
   608 		lua_events = g_slist_prepend (lua_events, event);
       
   609 
       
   610 		lua_pushstring (L, event->id);
       
   611 		return 1;
       
   612 	} else { // List
       
   613 		GSList *events = evs_geteventslist (0);
       
   614 		GSList *event;
       
   615 
       
   616 		lua_newtable (L);
       
   617 		for (event = events; event; event = g_slist_next (event)) {
       
   618 			lua_pushstring (L, event->data);
       
   619 			luaL_ref (L, -2);
       
   620 			g_free (event->data);
       
   621 		}
       
   622 		g_slist_free (events);
       
   623 
       
   624 		return 1;
       
   625 	}
   526 }
   626 }
   527 
   627 
   528 // MCABBER COMMANDS
   628 // MCABBER COMMANDS
   529 
   629 
   530 /// completion type
   630 /// completion type
  1070 	reg ( alias          ) 
  1170 	reg ( alias          ) 
  1071 	reg ( binding        ) 
  1171 	reg ( binding        ) 
  1072 	reg ( fileoption     ) 
  1172 	reg ( fileoption     ) 
  1073 	reg ( add_feature    ) 
  1173 	reg ( add_feature    ) 
  1074 	reg ( del_feature    ) 
  1174 	reg ( del_feature    ) 
       
  1175 	reg ( event          )
  1075 	reg ( parse_args     ) 
  1176 	reg ( parse_args     ) 
  1076 	reg ( add_category   ) 
  1177 	reg ( add_category   ) 
  1077 	reg ( del_category   ) 
  1178 	reg ( del_category   ) 
  1078 	reg ( add_completion ) 
  1179 	reg ( add_completion ) 
  1079 	reg ( del_completion ) 
  1180 	reg ( del_completion ) 
  1159 	}
  1260 	}
  1160 
  1261 
  1161 	return NULL;
  1262 	return NULL;
  1162 }
  1263 }
  1163 
  1264 
       
  1265 static void lua_events_destroy (eviqs *event, gpointer ignore)
       
  1266 {
       
  1267 	lua_event_callback_t *cb = event->data;
       
  1268 	evs_callback (event->id, EVS_CONTEXT_CANCEL); // ignore
       
  1269 	luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
       
  1270 	evs_del (event->id);
       
  1271 }
       
  1272 
  1164 static void lua_timers_destroy (guint source, gpointer ignore)
  1273 static void lua_timers_destroy (guint source, gpointer ignore)
  1165 {
  1274 {
  1166 	g_source_remove (source);
  1275 	g_source_remove (source);
  1167 }
  1276 }
  1168 
  1277 
  1200 
  1309 
  1201 		g_slist_foreach (lua_timers, (GFunc) lua_timers_destroy, NULL);
  1310 		g_slist_foreach (lua_timers, (GFunc) lua_timers_destroy, NULL);
  1202 		g_slist_free (lua_timers);
  1311 		g_slist_free (lua_timers);
  1203 		lua_timers = NULL;
  1312 		lua_timers = NULL;
  1204 
  1313 
       
  1314 		g_slist_foreach (lua_events, (GFunc) lua_events_destroy, NULL);
       
  1315 		g_slist_free (lua_events);
       
  1316 		lua_events = NULL;
       
  1317 
  1205 		g_slist_foreach (lua_added_features, (GFunc) lua_features_destroy, NULL);
  1318 		g_slist_foreach (lua_added_features, (GFunc) lua_features_destroy, NULL);
  1206 		g_slist_free (lua_added_features);
  1319 		g_slist_free (lua_added_features);
  1207 		lua_added_features = NULL;
  1320 		lua_added_features = NULL;
  1208 
  1321 
  1209 		g_slist_foreach (lua_added_commands, (GFunc) lua_commands_destroy, NULL);
  1322 		g_slist_foreach (lua_added_commands, (GFunc) lua_commands_destroy, NULL);