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