Mercurial > ~mikael > mcabber > hg
diff mcabber/mcabber/events.c @ 1668:41c26b7d2890
Install mcabber headers
* Change mcabber headers naming scheme
* Move 'src/' -> 'mcabber/'
* Add missing include <mcabber/config.h>'s
* Create and install clean config.h version in 'include/'
* Move "dirty" config.h version to 'mcabber/'
* Add $(top_srcdir) to compiler include path
* Update modules HOWTO
author | Myhailo Danylenko <isbear@ukrpost.net> |
---|---|
date | Mon, 18 Jan 2010 15:36:19 +0200 |
parents | mcabber/src/events.c@dcd5d4c75199 |
children | 1342df44c814 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mcabber/mcabber/events.c Mon Jan 18 15:36:19 2010 +0200 @@ -0,0 +1,180 @@ +/* + * events.c -- Events fonctions + * + * Copyright (C) 2006-2009 Mikael Berthe <mikael@lilotux.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include <glib.h> +#include <string.h> +#include "events.h" +#include "logprint.h" + +static GSList *evs_list; // Events list + +static eviqs *evs_find(const char *evid); + +// evs_new(type, timeout) +// Create an events structure. +eviqs *evs_new(guint8 type, time_t timeout) +{ + static guint evs_idn; + eviqs *new_evs; + time_t now_t; + char *stridn; + + if (!++evs_idn) + evs_idn = 1; + /* Check for wrapping, we shouldn't reuse ids */ + stridn = g_strdup_printf("%d", evs_idn); + if (evs_find(stridn)) { + g_free(stridn); + // We could try another id but for now giving up should be fine... + return NULL; + } + + new_evs = g_new0(eviqs, 1); + time(&now_t); + new_evs->ts_create = now_t; + if (timeout) + new_evs->ts_expire = now_t + timeout; + new_evs->type = type; + new_evs->id = stridn; + + if(!g_slist_length(evs_list)) + g_timeout_add_seconds(20, evs_check_timeout, NULL); + evs_list = g_slist_append(evs_list, new_evs); + return new_evs; +} + +int evs_del(const char *evid) +{ + GSList *p; + eviqs *i; + + if (!evid) return 1; + + for (p = evs_list; p; p = g_slist_next(p)) { + i = p->data; + if (!strcmp(evid, i->id)) + break; + } + if (p) { + g_free(i->id); + g_free(i->data); + g_free(i->desc); + g_free(i); + evs_list = g_slist_remove(evs_list, p->data); + return 0; // Ok, deleted + } + return -1; // Not found +} + +static eviqs *evs_find(const char *evid) +{ + GSList *p; + eviqs *i; + + if (!evid) return NULL; + + for (p = evs_list; p; p = g_slist_next(p)) { + i = p->data; + if (!strcmp(evid, i->id)) + return i; + } + return NULL; +} + +// evs_callback(evid, evcontext) +// Callback processing for the specified event. +// Return 0 in case of success, -1 if the evid hasn't been found. +int evs_callback(const char *evid, guint evcontext) +{ + eviqs *i; + + i = evs_find(evid); + if (!i) return -1; + + // IQ processing + // Note: If xml_result is NULL, this is a timeout + if (i->callback) + (void)(*i->callback)(i, evcontext); + + evs_del(evid); + return 0; +} + +gboolean evs_check_timeout() +{ + time_t now_t; + GSList *p; + eviqs *i; + + time(&now_t); + p = evs_list; + if (!p) + return FALSE; + while (p) { + i = p->data; + // We must get next IQ eviqs element now because the current one + // could be freed. + p = g_slist_next(p); + + if ((!i->ts_expire && now_t > i->ts_create + EVS_MAX_TIMEOUT) || + (i->ts_expire && now_t > i->ts_expire)) { + evs_callback(i->id, EVS_CONTEXT_TIMEOUT); + } + } + return TRUE; +} + +void evs_display_list(void) +{ + GSList *p; + eviqs *i; + + scr_LogPrint(LPRINT_LOGNORM, "Events list:"); + for (p = evs_list; p; p = g_slist_next(p)) { + i = p->data; + scr_LogPrint(LPRINT_LOGNORM, + "Id: %-3s %s", i->id, (i->desc ? i->desc : "")); + } + scr_LogPrint(LPRINT_LOGNORM, "End of events list."); +} + +// evs_geteventslist(bool comp) +// Return a singly-linked-list of events ids, for the completion system. +// If comp is true, the string "list" is added (it's a completion argument). +// Note: the caller should free the list (and data) after use. +GSList *evs_geteventslist(int compl) +{ + GSList *evidlist = NULL, *p; + eviqs *i; + + for (p = evs_list; p; p = g_slist_next(p)) { + i = p->data; + evidlist = g_slist_append(evidlist, g_strdup(i->id)); + } + + if (compl) { + // Last item is the "list" subcommand. + evidlist = g_slist_append(evidlist, g_strdup("list")); + } + return evidlist; +} + +/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */