Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/main.c @ 1653:fca9a4c17432
Improve UI latency and CPU usage
Remove main_loop(), and use GIOChannels for the FIFO system.
author | Myhailo Danylenko <isbear@ukrpost.net> |
---|---|
date | Tue, 01 Dec 2009 21:06:06 +0100 |
parents | 8c0e173d7d6a |
children | c4ee6d99f75b |
comparison
equal
deleted
inserted
replaced
1652:8036750d0169 | 1653:fca9a4c17432 |
---|---|
28 #include <termios.h> | 28 #include <termios.h> |
29 #include <sys/types.h> | 29 #include <sys/types.h> |
30 #include <sys/wait.h> | 30 #include <sys/wait.h> |
31 #include <glib.h> | 31 #include <glib.h> |
32 #include <config.h> | 32 #include <config.h> |
33 #include <poll.h> | |
33 | 34 |
34 #include "caps.h" | 35 #include "caps.h" |
35 #include "screen.h" | 36 #include "screen.h" |
36 #include "settings.h" | 37 #include "settings.h" |
37 #include "roster.h" | 38 #include "roster.h" |
51 #ifndef WAIT_ANY | 52 #ifndef WAIT_ANY |
52 # define WAIT_ANY -1 | 53 # define WAIT_ANY -1 |
53 #endif | 54 #endif |
54 | 55 |
55 static unsigned int terminate_ui; | 56 static unsigned int terminate_ui; |
56 GMainLoop *main_loop = NULL; | 57 GMainContext *main_context; |
58 | |
59 static gboolean update_screen = TRUE; | |
57 | 60 |
58 static struct termios *backup_termios; | 61 static struct termios *backup_termios; |
59 | 62 |
60 char *mcabber_version(void) | 63 char *mcabber_version(void) |
61 { | 64 { |
68 return ver; | 71 return ver; |
69 } | 72 } |
70 | 73 |
71 static void mcabber_terminate(const char *msg) | 74 static void mcabber_terminate(const char *msg) |
72 { | 75 { |
73 fifo_deinit(); | |
74 xmpp_disconnect(); | 76 xmpp_disconnect(); |
75 scr_TerminateCurses(); | 77 scr_TerminateCurses(); |
76 | 78 |
77 // Restore term settings, if needed. | 79 // Restore term settings, if needed. |
78 if (backup_termios) | 80 if (backup_termios) |
249 void mcabber_set_terminate_ui(void) | 251 void mcabber_set_terminate_ui(void) |
250 { | 252 { |
251 terminate_ui = TRUE; | 253 terminate_ui = TRUE; |
252 } | 254 } |
253 | 255 |
254 gboolean mcabber_loop() | 256 typedef struct { |
257 GSource source; | |
258 GPollFD pollfd; | |
259 } mcabber_source_t; | |
260 | |
261 static gboolean mcabber_source_prepare(GSource *source, gint *timeout) | |
262 { | |
263 *timeout = -1; | |
264 return FALSE; | |
265 } | |
266 | |
267 static gboolean mcabber_source_check(GSource *source) | |
268 { | |
269 mcabber_source_t *mc_source = (mcabber_source_t *) source; | |
270 gushort revents = mc_source->pollfd.revents; | |
271 if (revents) | |
272 return TRUE; | |
273 return FALSE; | |
274 } | |
275 | |
276 static gboolean mcabber_source_dispatch(GSource *source, GSourceFunc callback, | |
277 gpointer udata) | |
255 { | 278 { |
256 keycode kcode; | 279 keycode kcode; |
257 | 280 |
258 if (terminate_ui) { | 281 if (terminate_ui) { |
259 g_main_loop_quit(main_loop); | |
260 return FALSE; | 282 return FALSE; |
261 } | 283 } |
262 scr_DoUpdate(); | 284 scr_DoUpdate(); |
263 scr_Getch(&kcode); | 285 scr_Getch(&kcode); |
264 | 286 |
265 while (kcode.value != ERR) { | 287 while (kcode.value != ERR) { |
266 process_key(kcode); | 288 process_key(kcode); |
267 scr_DoUpdate(); | 289 update_screen = TRUE; |
268 scr_Getch(&kcode); | 290 scr_Getch(&kcode); |
269 } | 291 } |
270 scr_CheckAutoAway(FALSE); | 292 scr_CheckAutoAway(FALSE); |
271 | |
272 if (update_roster) | |
273 scr_DrawRoster(); | |
274 | 293 |
275 hk_mainloop(); | 294 hk_mainloop(); |
276 return TRUE; | 295 return TRUE; |
277 } | 296 } |
297 | |
298 static GSourceFuncs mcabber_source_funcs = { | |
299 mcabber_source_prepare, | |
300 mcabber_source_check, | |
301 mcabber_source_dispatch, | |
302 NULL, | |
303 NULL, | |
304 NULL | |
305 }; | |
278 | 306 |
279 int main(int argc, char **argv) | 307 int main(int argc, char **argv) |
280 { | 308 { |
281 char *configFile = NULL; | 309 char *configFile = NULL; |
282 const char *optstring; | 310 const char *optstring; |
396 fifo_init(settings_opt_get("fifo_name")); | 424 fifo_init(settings_opt_get("fifo_name")); |
397 | 425 |
398 /* Load previous roster state */ | 426 /* Load previous roster state */ |
399 hlog_load_state(); | 427 hlog_load_state(); |
400 | 428 |
401 main_loop = g_main_loop_new(NULL, TRUE); | 429 main_context = g_main_context_default(); |
402 | 430 |
403 if (ret < 0) { | 431 if (ret < 0) { |
404 scr_LogPrint(LPRINT_NORMAL, "No configuration file has been found."); | 432 scr_LogPrint(LPRINT_NORMAL, "No configuration file has been found."); |
405 scr_ShowBuddyWindow(); | 433 scr_ShowBuddyWindow(); |
406 } else { | 434 } else { |
407 /* Connection */ | 435 /* Connection */ |
408 xmpp_connect(); | 436 xmpp_connect(); |
409 } | 437 } |
410 | 438 |
411 scr_LogPrint(LPRINT_DEBUG, "Entering into main loop..."); | 439 { // add keypress processing source |
412 | 440 GSource *mc_source = g_source_new(&mcabber_source_funcs, |
413 g_timeout_add(100, mcabber_loop, NULL); | 441 sizeof(mcabber_source_t)); |
414 g_main_loop_run(main_loop); | 442 GPollFD *mc_pollfd = &(((mcabber_source_t *)mc_source)->pollfd); |
443 mc_pollfd->fd = STDIN_FILENO; | |
444 mc_pollfd->events = POLLIN|POLLERR|POLLPRI; | |
445 mc_pollfd->revents = 0; | |
446 g_source_add_poll(mc_source, mc_pollfd); | |
447 g_source_attach(mc_source, main_context); | |
448 | |
449 scr_LogPrint(LPRINT_DEBUG, "Entering into main loop..."); | |
450 | |
451 while(!terminate_ui) { | |
452 g_main_context_iteration(main_context, TRUE); | |
453 if (update_roster) | |
454 scr_DrawRoster(); | |
455 if(update_screen) | |
456 scr_DoUpdate(); | |
457 } | |
458 | |
459 g_source_destroy(mc_source); | |
460 g_source_unref(mc_source); | |
461 } | |
415 | 462 |
416 scr_TerminateCurses(); | 463 scr_TerminateCurses(); |
417 #ifdef MODULES_ENABLE | 464 #ifdef MODULES_ENABLE |
418 cmd_deinit(); | 465 cmd_deinit(); |
419 #endif | 466 #endif |