Improve UI latency and CPU usage
[mcabber.git] / mcabber / src / events.c
blobfac0d72ec1e0908d9b2574715e662935977a5aae
1 /*
2 * events.c -- Events fonctions
4 * Copyright (C) 2006-2009 Mikael Berthe <mikael@lilotux.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
22 #include <glib.h>
23 #include <string.h>
24 #include "events.h"
25 #include "logprint.h"
27 static GSList *evs_list; // Events list
29 static eviqs *evs_find(const char *evid);
31 // evs_new(type, timeout)
32 // Create an events structure.
33 eviqs *evs_new(guint8 type, time_t timeout)
35 static guint evs_idn;
36 eviqs *new_evs;
37 time_t now_t;
38 char *stridn;
40 if (!++evs_idn)
41 evs_idn = 1;
42 /* Check for wrapping, we shouldn't reuse ids */
43 stridn = g_strdup_printf("%d", evs_idn);
44 if (evs_find(stridn)) {
45 g_free(stridn);
46 // We could try another id but for now giving up should be fine...
47 return NULL;
50 new_evs = g_new0(eviqs, 1);
51 time(&now_t);
52 new_evs->ts_create = now_t;
53 if (timeout)
54 new_evs->ts_expire = now_t + timeout;
55 new_evs->type = type;
56 new_evs->id = stridn;
58 if(!g_slist_length(evs_list))
59 g_timeout_add_seconds(20, evs_check_timeout, NULL);
60 evs_list = g_slist_append(evs_list, new_evs);
61 return new_evs;
64 int evs_del(const char *evid)
66 GSList *p;
67 eviqs *i;
69 if (!evid) return 1;
71 for (p = evs_list; p; p = g_slist_next(p)) {
72 i = p->data;
73 if (!strcmp(evid, i->id))
74 break;
76 if (p) {
77 g_free(i->id);
78 g_free(i->data);
79 g_free(i->desc);
80 g_free(i);
81 evs_list = g_slist_remove(evs_list, p->data);
82 return 0; // Ok, deleted
84 return -1; // Not found
87 static eviqs *evs_find(const char *evid)
89 GSList *p;
90 eviqs *i;
92 if (!evid) return NULL;
94 for (p = evs_list; p; p = g_slist_next(p)) {
95 i = p->data;
96 if (!strcmp(evid, i->id))
97 return i;
99 return NULL;
102 // evs_callback(evid, evcontext)
103 // Callback processing for the specified event.
104 // Return 0 in case of success, -1 if the evid hasn't been found.
105 int evs_callback(const char *evid, guint evcontext)
107 eviqs *i;
109 i = evs_find(evid);
110 if (!i) return -1;
112 // IQ processing
113 // Note: If xml_result is NULL, this is a timeout
114 if (i->callback)
115 (void)(*i->callback)(i, evcontext);
117 evs_del(evid);
118 return 0;
121 gboolean evs_check_timeout()
123 time_t now_t;
124 GSList *p;
125 eviqs *i;
127 time(&now_t);
128 p = evs_list;
129 if (!p)
130 return FALSE;
131 while (p) {
132 i = p->data;
133 // We must get next IQ eviqs element now because the current one
134 // could be freed.
135 p = g_slist_next(p);
137 if ((!i->ts_expire && now_t > i->ts_create + EVS_MAX_TIMEOUT) ||
138 (i->ts_expire && now_t > i->ts_expire)) {
139 evs_callback(i->id, EVS_CONTEXT_TIMEOUT);
142 return TRUE;
145 void evs_display_list(void)
147 GSList *p;
148 eviqs *i;
150 scr_LogPrint(LPRINT_LOGNORM, "Events list:");
151 for (p = evs_list; p; p = g_slist_next(p)) {
152 i = p->data;
153 scr_LogPrint(LPRINT_LOGNORM,
154 "Id: %-3s %s", i->id, (i->desc ? i->desc : ""));
156 scr_LogPrint(LPRINT_LOGNORM, "End of events list.");
159 // evs_geteventslist(bool comp)
160 // Return a singly-linked-list of events ids, for the completion system.
161 // If comp is true, the string "list" is added (it's a completion argument).
162 // Note: the caller should free the list (and data) after use.
163 GSList *evs_geteventslist(int compl)
165 GSList *evidlist = NULL, *p;
166 eviqs *i;
168 for (p = evs_list; p; p = g_slist_next(p)) {
169 i = p->data;
170 evidlist = g_slist_append(evidlist, g_strdup(i->id));
173 if (compl) {
174 // Last item is the "list" subcommand.
175 evidlist = g_slist_append(evidlist, g_strdup("list"));
177 return evidlist;
180 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */