1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-29 22:36:38 +02:00
Files
weechat/src/gui/curses/gui-curses-main.c
T

379 lines
11 KiB
C

/*
* Copyright (c) 2003-2006 by FlashCode <flashcode@flashtux.org>
* See README for License detail, AUTHORS for developers list.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* gui-curses-main.c: main loop for Curses GUI */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include "../../common/weechat.h"
#include "../gui.h"
#include "../../common/fifo.h"
#include "../../common/utf8.h"
#include "../../common/util.h"
#include "../../common/weeconfig.h"
#include "../../irc/irc.h"
#include "gui-curses.h"
#ifdef PLUGINS
#include "../../plugins/plugins.h"
#endif
int send_irc_quit = 0;
/*
* gui_main_quit: quit weechat (signal received)
*/
void
gui_main_quit ()
{
quit_weechat = 1;
send_irc_quit = 1;
}
/*
* gui_main_loop: main loop for WeeChat with ncurses GUI
*/
void
gui_main_loop ()
{
fd_set read_fd;
static struct timeval timeout, tv;
static struct timezone tz;
t_irc_server *ptr_server;
t_gui_buffer *ptr_buffer;
int old_day, old_min, old_sec, diff;
char text_time[1024];
time_t new_time;
struct tm *local_time;
quit_weechat = 0;
send_irc_quit = 0;
new_time = time (NULL);
gui_last_activity_time = new_time;
local_time = localtime (&new_time);
old_day = local_time->tm_mday;
old_min = -1;
old_sec = -1;
check_away = 0;
/* if SIGTERM or SIGHUP received => quit */
signal (SIGTERM, gui_main_quit);
signal (SIGHUP, gui_main_quit);
while (!quit_weechat)
{
/* refresh needed ? */
if (gui_refresh_screen_needed)
gui_window_refresh_screen (0);
new_time = time (NULL);
local_time = localtime (&new_time);
/* minute has changed ? => redraw infobar */
if (local_time->tm_min != old_min)
{
old_min = local_time->tm_min;
gui_infobar_draw (gui_current_window->buffer, 1);
if (cfg_look_day_change
&& (local_time->tm_mday != old_day))
{
strftime (text_time, sizeof (text_time),
cfg_look_day_change_timestamp, local_time);
gui_add_hotlist = 0;
for (ptr_buffer = gui_buffers; ptr_buffer;
ptr_buffer = ptr_buffer->next_buffer)
{
if (ptr_buffer->type == BUFFER_TYPE_STANDARD)
gui_printf_nolog_notime (ptr_buffer,
_("Day changed to %s\n"),
text_time);
}
gui_add_hotlist = 1;
}
old_day = local_time->tm_mday;
}
/* second has changed ? */
if (local_time->tm_sec != old_sec)
{
old_sec = local_time->tm_sec;
if (cfg_look_infobar_seconds)
{
gui_infobar_draw_time (gui_current_window->buffer);
wmove (GUI_CURSES(gui_current_window)->win_input,
0, gui_current_window->win_input_cursor_x);
wrefresh (GUI_CURSES(gui_current_window)->win_input);
}
/* infobar count down */
if (gui_infobar && gui_infobar->remaining_time > 0)
{
gui_infobar->remaining_time--;
if (gui_infobar->remaining_time == 0)
{
gui_infobar_remove ();
gui_infobar_draw (gui_current_window->buffer, 1);
}
}
/* away check */
if (cfg_irc_away_check != 0)
{
check_away++;
if (check_away >= (cfg_irc_away_check * 60))
{
check_away = 0;
server_check_away ();
}
}
#ifdef PLUGINS
/* call timer handlers */
plugin_timer_handler_exec ();
#endif
}
/* read keyboard */
/* on GNU/Hurd 2 select() are causing troubles with keyboard */
/* waiting for a fix, we use only one select() */
#ifndef __GNU__
FD_ZERO (&read_fd);
timeout.tv_sec = 0;
timeout.tv_usec = 8000;
FD_SET (STDIN_FILENO, &read_fd);
if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
{
if (FD_ISSET (STDIN_FILENO, &read_fd))
{
gui_keyboard_read ();
}
}
#endif
/* read sockets (servers, child process when connecting, FIFO pipe) */
FD_ZERO (&read_fd);
#ifdef __GNU__
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
FD_SET (STDIN_FILENO, &read_fd);
#else
timeout.tv_sec = 0;
timeout.tv_usec = 2000;
#endif
if (weechat_fifo != -1)
FD_SET (weechat_fifo, &read_fd);
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
/* check if reconnection is pending */
if ((!ptr_server->is_connected)
&& (ptr_server->reconnect_start > 0)
&& (new_time >= (ptr_server->reconnect_start + ptr_server->autoreconnect_delay)))
server_reconnect (ptr_server);
else
{
if (ptr_server->is_connected)
{
/* check for lag */
if ((ptr_server->lag_check_time.tv_sec == 0)
&& (new_time >= ptr_server->lag_next_check))
{
server_sendf (ptr_server, "PING %s\r\n", ptr_server->address);
gettimeofday (&(ptr_server->lag_check_time), &tz);
}
/* lag timeout => disconnect */
if ((ptr_server->lag_check_time.tv_sec != 0)
&& (cfg_irc_lag_disconnect > 0))
{
gettimeofday (&tv, &tz);
diff = (int) get_timeval_diff (&(ptr_server->lag_check_time), &tv);
if (diff / 1000 > cfg_irc_lag_disconnect * 60)
{
irc_display_prefix (ptr_server, ptr_server->buffer, PREFIX_ERROR);
gui_printf (ptr_server->buffer,
_("%s lag is high, disconnecting from server...\n"),
WEECHAT_WARNING);
server_disconnect (ptr_server, 1);
continue;
}
}
}
if (!ptr_server->is_connected && (ptr_server->child_pid > 0))
FD_SET (ptr_server->child_read, &read_fd);
else
{
if (ptr_server->sock >= 0)
FD_SET (ptr_server->sock, &read_fd);
}
}
}
if (select (FD_SETSIZE, &read_fd, NULL, NULL, &timeout) > 0)
{
#ifdef __GNU__
if (FD_ISSET (STDIN_FILENO, &read_fd))
{
gui_keyboard_read ();
}
#endif
if ((weechat_fifo != -1) && (FD_ISSET (weechat_fifo, &read_fd)))
{
fifo_read ();
}
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
if (!ptr_server->is_connected && (ptr_server->child_pid > 0))
{
if (FD_ISSET (ptr_server->child_read, &read_fd))
server_child_read (ptr_server);
}
else
{
if ((ptr_server->sock >= 0) &&
(FD_ISSET (ptr_server->sock, &read_fd)))
server_recv (ptr_server);
}
}
}
/* manages active DCC */
dcc_handle ();
}
if (send_irc_quit)
irc_cmd_send_quit (NULL, NULL, NULL);
}
/*
* gui_main_pre_init: pre-initialize GUI (called before gui_init)
*/
void
gui_main_pre_init (int *argc, char **argv[])
{
/* nothing for Curses interface */
(void) argc;
(void) argv;
}
/*
* gui_main_init: init GUI
*/
void
gui_main_init ()
{
initscr ();
curs_set (1);
noecho ();
nodelay (stdscr, TRUE);
gui_color_init ();
gui_infobar = NULL;
gui_ok = ((COLS > WINDOW_MIN_WIDTH) && (LINES > WINDOW_MIN_HEIGHT));
refresh ();
/* init clipboard buffer */
gui_input_clipboard = NULL;
/* create new window/buffer */
if (gui_window_new (NULL, 0, 0, COLS, LINES, 100, 100))
{
gui_current_window = gui_windows;
gui_buffer_new (gui_windows, NULL, NULL, BUFFER_TYPE_STANDARD, 1);
if (cfg_look_set_title)
gui_window_set_title ();
gui_init_ok = 1;
signal (SIGWINCH, gui_window_refresh_screen_sigwinch);
}
}
/*
* gui_main_end: GUI end
*/
void
gui_main_end ()
{
/* free clipboard buffer */
if (gui_input_clipboard)
free (gui_input_clipboard);
/* delete all panels */
while (gui_panels)
gui_panel_free (gui_panels);
/* delete all windows */
while (gui_windows)
gui_window_free (gui_windows);
gui_window_tree_free (&gui_windows_tree);
/* delete all buffers */
while (gui_buffers)
gui_buffer_free (gui_buffers, 0);
/* delete global history */
history_global_free ();
/* delete infobar messages */
while (gui_infobar)
gui_infobar_remove ();
/* reset title */
if (cfg_look_set_title)
gui_window_reset_title ();
/* end of Curses output */
refresh ();
endwin ();
}