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 |
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); |