diff --git a/Makefile.am b/Makefile.am index f9c89d64..eef812aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -130,6 +130,7 @@ unittest_sources = \ tests/unittests/xmpp/stub_xmpp.c \ tests/unittests/xmpp/stub_message.c \ tests/unittests/ui/stub_ui.c tests/unittests/ui/stub_ui.h \ + tests/unittests/ui/stub_inputwin.c tests/unittests/ui/stub_inputwin.h \ tests/unittests/ui/stub_vcardwin.c \ tests/unittests/log/stub_log.c \ tests/unittests/chatlog/stub_chatlog.c \ diff --git a/src/profanity.c b/src/profanity.c index 9660945c..09bf29df 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -60,6 +61,7 @@ #include "command/cmd_defs.h" #include "plugins/plugins.h" #include "event/client_events.h" +#include "ui/inputwin.h" #include "ui/ui.h" #include "ui/window_list.h" #include "xmpp/resource.h" @@ -86,15 +88,15 @@ static void _init(char* log_level, char* config_file, char* log_file, char* theme_name); static void _shutdown(void); static void _connect_default(const char* const account); +static gboolean _main_update(gpointer data); pthread_mutex_t lock; static gboolean force_quit = FALSE; +GMainLoop* mainloop = NULL; void prof_run(char* log_level, char* account_name, char* config_file, char* log_file, char* theme_name) { - gboolean cont = TRUE; - _init(log_level, config_file, log_file, theme_name); plugins_on_start(); _connect_default(account_name); @@ -105,33 +107,10 @@ prof_run(char* log_level, char* account_name, char* config_file, char* log_file, session_init_activity(); - char* line = NULL; - while (cont && !force_quit) { - log_stderr_handler(); - session_check_autoaway(); - - line = inp_readline(); - if (line) { - ProfWin* window = wins_get_current(); - cont = cmd_process_input(window, line); - free(line); - line = NULL; - } else { - cont = TRUE; - } - -#ifdef HAVE_LIBOTR - otr_poll(); -#endif - plugins_run_timed(); - notify_remind(); - session_process_events(); - iq_autoping_check(); - ui_update(); -#ifdef HAVE_GTK - tray_update(); -#endif - } + mainloop = g_main_loop_new(NULL, TRUE); + g_timeout_add(1000 / 60, _main_update, NULL); + inp_add_watch(); + g_main_loop_run(mainloop); } void @@ -140,6 +119,29 @@ prof_set_quit(void) force_quit = TRUE; } +static gboolean +_main_update(gpointer data) +{ + log_stderr_handler(); + session_check_autoaway(); + +#ifdef HAVE_LIBOTR + otr_poll(); +#endif + plugins_run_timed(); + notify_remind(); + session_process_events(); + iq_autoping_check(); + ui_update(); + chat_state_idle(); +#ifdef HAVE_GTK + tray_update(); +#endif + + // Always repeat + return TRUE; +} + static void _connect_default(const char* const account) { diff --git a/src/profanity.h b/src/profanity.h index 0e5faba1..e5e6cbcb 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -44,5 +44,6 @@ void prof_run(char* log_level, char* account_name, char* config_file, char* log_ void prof_set_quit(void); extern pthread_mutex_t lock; +extern GMainLoop* mainloop; #endif diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index d1d27807..979b0b0a 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -171,6 +171,45 @@ create_input_window(void) _inp_win_update_virtual(); } +static gboolean +_inp_callback(GIOChannel* source, GIOCondition condition, gpointer data) +{ + rl_callback_read_char(); + + if (rl_line_buffer && rl_line_buffer[0] != '/' && rl_line_buffer[0] != '\0' && rl_line_buffer[0] != '\n') { + chat_state_activity(); + } + + ui_reset_idle_time(); + if (!get_password) { + // Update the input buffer on screen + _inp_write(rl_line_buffer, rl_point); + } + + if (inp_line) { + ProfWin* window = wins_get_current(); + + if (!cmd_process_input(window, inp_line)) + g_main_loop_quit(mainloop); + + free(inp_line); + inp_line = NULL; + } + + return TRUE; +} + +void +inp_add_watch(void) +{ + GIOChannel* channel = g_io_channel_unix_new(fileno(rl_instream)); + if (g_io_channel_set_encoding(channel, NULL, NULL) != G_IO_STATUS_NORMAL) { + log_error("cannot set NULL encoding"); + } + + g_io_add_watch(channel, G_IO_IN, _inp_callback, NULL); +} + char* inp_readline(void) { diff --git a/src/ui/inputwin.h b/src/ui/inputwin.h index 3aefcc0a..ec428e43 100644 --- a/src/ui/inputwin.h +++ b/src/ui/inputwin.h @@ -46,5 +46,6 @@ void inp_win_resize(void); void inp_put_back(void); char* inp_get_password(void); char* inp_get_line(void); +void inp_add_watch(void); #endif diff --git a/tests/unittests/ui/stub_inputwin.c b/tests/unittests/ui/stub_inputwin.c new file mode 100644 index 00000000..f4005bae --- /dev/null +++ b/tests/unittests/ui/stub_inputwin.c @@ -0,0 +1,4 @@ +void +inp_add_watch(void) +{ +} \ No newline at end of file diff --git a/tests/unittests/ui/stub_inputwin.h b/tests/unittests/ui/stub_inputwin.h new file mode 100644 index 00000000..a7535da4 --- /dev/null +++ b/tests/unittests/ui/stub_inputwin.h @@ -0,0 +1 @@ +void inp_add_watch(void); \ No newline at end of file