mcabber/mcabber/main.c
changeset 2288 ece02eb9c81d
parent 2281 1bb9002801e5
child 2292 f181418db215
equal deleted inserted replaced
2287:1f5f708d58a6 2288:ece02eb9c81d
    26 #include <sys/types.h>
    26 #include <sys/types.h>
    27 #include <sys/wait.h>
    27 #include <sys/wait.h>
    28 #include <glib.h>
    28 #include <glib.h>
    29 #include <config.h>
    29 #include <config.h>
    30 #include <poll.h>
    30 #include <poll.h>
    31 #include <time.h>
       
    32 #include <errno.h>
    31 #include <errno.h>
    33 
    32 
    34 #include "caps.h"
    33 #include "caps.h"
    35 #include "screen.h"
    34 #include "screen.h"
    36 #include "settings.h"
    35 #include "settings.h"
    65 #ifdef USE_SIGWINCH
    64 #ifdef USE_SIGWINCH
    66 void sigwinch_resize(void);
    65 void sigwinch_resize(void);
    67 static bool sigwinch;
    66 static bool sigwinch;
    68 #endif
    67 #endif
    69 
    68 
    70 extern int build_buddylist;
       
    71 
       
    72 static bool terminate_ui;
    69 static bool terminate_ui;
    73 GMainContext *main_context;
    70 GMainContext *main_context;
    74 static guint refresh_timeout_id;
       
    75 
    71 
    76 static struct termios *backup_termios;
    72 static struct termios *backup_termios;
    77 
    73 
    78 char *mcabber_version(void)
    74 char *mcabber_version(void)
    79 {
    75 {
   379 static gboolean mcabber_source_dispatch(GSource *source, GSourceFunc callback,
   375 static gboolean mcabber_source_dispatch(GSource *source, GSourceFunc callback,
   380                                         gpointer udata) {
   376                                         gpointer udata) {
   381   return keyboard_activity();
   377   return keyboard_activity();
   382 }
   378 }
   383 
   379 
   384 static gboolean refresh_timeout_cb(gpointer data) {
       
   385    // Only called once, to trigger a refresh if needed
       
   386    // so reset ID and return false.
       
   387   refresh_timeout_id = 0;
       
   388   return FALSE;
       
   389 }
       
   390 
       
   391 static GSourceFuncs mcabber_source_funcs = {
   380 static GSourceFuncs mcabber_source_funcs = {
   392   mcabber_source_prepare,
   381   mcabber_source_prepare,
   393   mcabber_source_check,
   382   mcabber_source_check,
   394   mcabber_source_dispatch,
   383   mcabber_source_dispatch,
   395   NULL,
   384   NULL,
   492       settings_set(SETTINGS_TYPE_OPTION, "password", pwd);
   481       settings_set(SETTINGS_TYPE_OPTION, "password", pwd);
   493       g_free(pwd);
   482       g_free(pwd);
   494     }
   483     }
   495   }
   484   }
   496 
   485 
   497   /* Initialize buddylist update timestamp */
       
   498   struct timespec last_ui_update;
       
   499   clock_gettime(CLOCK_MONOTONIC, &last_ui_update);
       
   500 
       
   501   /* Initialize PGP system
   486   /* Initialize PGP system
   502      We do it before ncurses initialization because we may need to request
   487      We do it before ncurses initialization because we may need to request
   503      a passphrase. */
   488      a passphrase. */
   504   if (settings_opt_get_int("pgp"))
   489   if (settings_opt_get_int("pgp"))
   505     main_init_pgp();
   490     main_init_pgp();
   568     g_source_attach(mc_source, main_context);
   553     g_source_attach(mc_source, main_context);
   569 
   554 
   570     scr_LogPrint(LPRINT_DEBUG, "Entering into main loop...");
   555     scr_LogPrint(LPRINT_DEBUG, "Entering into main loop...");
   571 
   556 
   572     while(!terminate_ui) {
   557     while(!terminate_ui) {
   573       int64_t timediff;
       
   574       struct timespec now;
       
   575 
       
   576       if (g_main_context_iteration(main_context, TRUE) == FALSE)
   558       if (g_main_context_iteration(main_context, TRUE) == FALSE)
   577         keyboard_activity();
   559         keyboard_activity();
   578 #ifdef USE_SIGWINCH
   560 #ifdef USE_SIGWINCH
   579       if (sigwinch) {
   561       if (sigwinch) {
   580         sigwinch_resize();
   562         sigwinch_resize();
   581         sigwinch = FALSE;
   563         sigwinch = FALSE;
   582       }
   564       }
   583 #endif
   565 #endif
   584 
   566       if (update_roster)
   585       // Compute time in ms since last buddylist/screen update
   567         scr_draw_roster();
   586       clock_gettime(CLOCK_MONOTONIC, &now);
   568       scr_do_update();
   587       timediff = (((now.tv_sec - last_ui_update.tv_sec)  * 1.0e9) +
       
   588                   (now.tv_nsec - last_ui_update.tv_nsec)) / 1.0e6;
       
   589 
       
   590       if (timediff <= 200) {
       
   591         // Trigger a timeout in 1s to make sure no refresh will be missed
       
   592         if (!refresh_timeout_id) {
       
   593           refresh_timeout_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
       
   594                                      1, refresh_timeout_cb, NULL, NULL);
       
   595         }
       
   596       } else if ((build_buddylist || update_roster)) {
       
   597         // More than 200ms
       
   598         if (build_buddylist || update_roster) {
       
   599           if (build_buddylist) {
       
   600             buddylist_build();
       
   601             update_roster = TRUE;
       
   602           }
       
   603           if (update_roster) {
       
   604             scr_draw_roster();
       
   605             scr_do_update();
       
   606             last_ui_update = now;
       
   607           }
       
   608         } else {
       
   609           // No roster change; minimum screen update
       
   610           update_panels();
       
   611           doupdate();
       
   612         }
       
   613       }
       
   614     }
   569     }
   615 
   570 
   616     g_source_destroy(mc_source);
   571     g_source_destroy(mc_source);
   617     g_source_unref(mc_source);
   572     g_source_unref(mc_source);
   618   }
   573   }