From 6172338bb7c7dd35cb7b93209e828134bb827fd5 Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Sun, 7 May 2006 11:31:11 +0000 Subject: [PATCH] Fixed refresh bug (deadlock in curses) when terminal is resized (bug #16542) --- ChangeLog | 10 +- .../curses/{gui-main.c => gui-curses-main.c} | 54 ++- .../{gui-window.c => gui-curses-window.c} | 321 +++++++++++------- weechat/ChangeLog | 10 +- .../curses/{gui-main.c => gui-curses-main.c} | 54 ++- .../{gui-window.c => gui-curses-window.c} | 321 +++++++++++------- 6 files changed, 458 insertions(+), 312 deletions(-) rename src/gui/curses/{gui-main.c => gui-curses-main.c} (90%) rename src/gui/curses/{gui-window.c => gui-curses-window.c} (78%) rename weechat/src/gui/curses/{gui-main.c => gui-curses-main.c} (90%) rename weechat/src/gui/curses/{gui-window.c => gui-curses-window.c} (78%) diff --git a/ChangeLog b/ChangeLog index 7ce9a9a3c..0d79401fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,19 +1,21 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -ChangeLog - 2006-05-05 +ChangeLog - 2006-05-07 Version 0.1.9 (under dev!): + * fixed refresh bug (deadlock in curses) when terminal is resized + (bug #16542) * fixed nicklist sort bug * added russian translations (thanks to Pavel Shevchuk) * added german doc (thanks to Frank Zacharias) * added missing IRC commands (290, 292, 437, 974) * fixed crash when multiple pv have same name: now it's forbidden and pv buffer is not renamed (when a nick changes) if another - exists with same name + exists with same name (bug #16369) * command /clear [-all] now clears hotlist - * fixed crash after /upgrade if a line in history is empty - * fixed many crashes with DCC chat + * fixed crash after /upgrade if a line in history is empty (bug #16379) + * fixed many crashes with DCC chat (bug #16416) * added new option to customize input prompt * added nick modes * fixed commands 332, 333 (/topic now ok when channel is not opened) diff --git a/src/gui/curses/gui-main.c b/src/gui/curses/gui-curses-main.c similarity index 90% rename from src/gui/curses/gui-main.c rename to src/gui/curses/gui-curses-main.c index 0e8c61fd2..2588443b1 100644 --- a/src/gui/curses/gui-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* gui-main.c: main loop and keyboard management for Curses GUI */ +/* gui-curses-main.c: main loop for Curses GUI */ #ifdef HAVE_CONFIG_H @@ -30,12 +30,6 @@ #include #include -#ifdef HAVE_NCURSESW_CURSES_H -#include -#else -#include -#endif - #include "../../common/weechat.h" #include "../gui.h" #include "../../common/fifo.h" @@ -77,6 +71,10 @@ gui_main_loop () check_away = 0; while (!quit_weechat) { + /* refresh needed ? */ + if (gui_refresh_screen_needed) + gui_window_refresh_screen (); + new_time = time (NULL); local_time = localtime (&new_time); @@ -113,9 +111,9 @@ gui_main_loop () if (cfg_look_infobar_seconds) { gui_infobar_draw_time (gui_current_window->buffer); - wmove (gui_current_window->win_input, + wmove (GUI_CURSES(gui_current_window)->win_input, 0, gui_current_window->win_input_x); - wrefresh (gui_current_window->win_input); + wrefresh (GUI_CURSES(gui_current_window)->win_input); } /* infobar count down */ @@ -289,13 +287,13 @@ gui_main_init () { gui_current_window = gui_windows; gui_buffer_new (gui_windows, NULL, NULL, BUFFER_TYPE_STANDARD, 1); - - signal (SIGWINCH, gui_window_refresh_screen_sigwinch); - + if (cfg_look_set_title) gui_window_set_title (); - + gui_init_ok = 1; + + signal (SIGWINCH, gui_window_refresh_screen_sigwinch); } } @@ -306,32 +304,18 @@ gui_main_init () void gui_main_end () { - t_gui_window *ptr_win; - /* free clipboard buffer */ if (gui_input_clipboard) - free(gui_input_clipboard); + free (gui_input_clipboard); + + /* delete all panels */ + while (gui_panels) + gui_panel_free (gui_panels); - /* delete all windows */ - for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) - { - if (ptr_win->win_title) - delwin (ptr_win->win_title); - if (ptr_win->win_chat) - delwin (ptr_win->win_chat); - if (ptr_win->win_nick) - delwin (ptr_win->win_nick); - if (ptr_win->win_status) - delwin (ptr_win->win_status); - if (ptr_win->win_infobar) - delwin (ptr_win->win_infobar); - if (ptr_win->win_input) - delwin (ptr_win->win_input); - } - /* delete all buffers */ + gui_window_merge_all (gui_current_window); while (gui_buffers) - gui_buffer_free (gui_buffers, 0); + gui_buffer_free (gui_buffers, 0); /* delete all windows */ while (gui_windows) @@ -349,7 +333,7 @@ gui_main_end () if (cfg_look_set_title) gui_window_reset_title (); - /* end of curses output */ + /* end of Curses output */ refresh (); endwin (); } diff --git a/src/gui/curses/gui-window.c b/src/gui/curses/gui-curses-window.c similarity index 78% rename from src/gui/curses/gui-window.c rename to src/gui/curses/gui-curses-window.c index 8cb067234..006f41f47 100644 --- a/src/gui/curses/gui-window.c +++ b/src/gui/curses/gui-curses-window.c @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* gui-window.c: window display functions for Curses GUI */ +/* gui-curses-window.c: window display functions for Curses GUI */ #ifdef HAVE_CONFIG_H @@ -29,12 +29,6 @@ #include #include -#ifdef HAVE_NCURSESW_CURSES_H -#include -#else -#include -#endif - #include "../../common/weechat.h" #include "../gui.h" #include "../../common/hotlist.h" @@ -42,6 +36,99 @@ #include "gui-curses.h" +int gui_refresh_screen_needed = 0; + + +/* + * gui_window_get_width: get screen width (terminal width in chars for Curses) + */ + +int +gui_window_get_width () +{ + return COLS; +} + +/* + * gui_window_get_height: get screen height (terminal height in chars for Curses) + */ + +int +gui_window_get_height () +{ + return LINES; +} + +/* + * gui_window_objects_init: init Curses windows + */ + +int +gui_window_objects_init (t_gui_window *window) +{ + t_gui_curses_objects *new_objects; + + if ((new_objects = (t_gui_curses_objects *) malloc (sizeof (t_gui_curses_objects)))) + { + window->gui_objects = new_objects; + GUI_CURSES(window)->win_title = NULL; + GUI_CURSES(window)->win_chat = NULL; + GUI_CURSES(window)->win_nick = NULL; + GUI_CURSES(window)->win_status = NULL; + GUI_CURSES(window)->win_infobar = NULL; + GUI_CURSES(window)->win_input = NULL; + GUI_CURSES(window)->win_separator = NULL; + GUI_CURSES(window)->panel_windows = NULL; + return 1; + } + else + return 0; +} + +/* + * gui_window_objects_free: free Curses windows for a window + */ + +void +gui_window_objects_free (t_gui_window *window, int free_separator) +{ + if (GUI_CURSES(window)->win_title) + { + delwin (GUI_CURSES(window)->win_title); + GUI_CURSES(window)->win_title = NULL; + } + if (GUI_CURSES(window)->win_chat) + { + delwin (GUI_CURSES(window)->win_chat); + GUI_CURSES(window)->win_chat = NULL; + } + if (GUI_CURSES(window)->win_nick) + { + delwin (GUI_CURSES(window)->win_nick); + GUI_CURSES(window)->win_nick = NULL; + } + if (GUI_CURSES(window)->win_status) + { + delwin (GUI_CURSES(window)->win_status); + GUI_CURSES(window)->win_status = NULL; + } + if (GUI_CURSES(window)->win_infobar) + { + delwin (GUI_CURSES(window)->win_infobar); + GUI_CURSES(window)->win_infobar = NULL; + } + if (GUI_CURSES(window)->win_input) + { + delwin (GUI_CURSES(window)->win_input); + GUI_CURSES(window)->win_input = NULL; + } + if (free_separator && GUI_CURSES(window)->win_separator) + { + delwin (GUI_CURSES(window)->win_separator); + GUI_CURSES(window)->win_separator = NULL; + } +} + /* * gui_window_curses_clear: clear a Curses window */ @@ -82,10 +169,16 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) { int max_length, max_height, lines; int num_nicks, num_op, num_halfop, num_voice, num_normal; + int add_right, add_left, add_top, add_bottom; if (!gui_ok) return 0; + add_left = gui_panel_get_size (window, GUI_PANEL_LEFT); + add_right = gui_panel_get_size (window, GUI_PANEL_RIGHT); + add_top = gui_panel_get_size (window, GUI_PANEL_TOP); + add_bottom = gui_panel_get_size (window, GUI_PANEL_BOTTOM); + /* init chat & nicklist settings */ if (cfg_look_nicklist && BUFFER_IS_CHANNEL(window->buffer)) { @@ -128,9 +221,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) switch (cfg_look_nicklist_position) { case CFG_LOOK_NICKLIST_LEFT: - window->win_chat_x = window->win_x + max_length + 2; + window->win_chat_x = window->win_x + add_left + max_length + 2; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width - max_length - 2; + window->win_chat_width = window->win_width - add_left - max_length - 2; window->win_nick_x = window->win_x + 0; window->win_nick_y = window->win_y + 1; window->win_nick_width = max_length + 2; @@ -147,9 +240,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) window->win_nick_num_max = window->win_nick_height; break; case CFG_LOOK_NICKLIST_RIGHT: - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width - max_length - 2; + window->win_chat_width = window->win_width - add_left - max_length - 2; window->win_nick_x = window->win_x + window->win_width - max_length - 2; window->win_nick_y = window->win_y + 1; window->win_nick_width = max_length + 2; @@ -166,9 +259,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) window->win_nick_num_max = window->win_nick_height; break; case CFG_LOOK_NICKLIST_TOP: - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1 + (lines + 1); - window->win_chat_width = window->win_width; + window->win_chat_width = window->win_width - add_left; if (cfg_look_infobar) window->win_chat_height = window->win_height - 3 - (lines + 1) - 1; else @@ -180,9 +273,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) window->win_nick_num_max = lines * (window->win_nick_width / (max_length + 2)); break; case CFG_LOOK_NICKLIST_BOTTOM: - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width; + window->win_chat_width = window->win_width - add_left; if (cfg_look_infobar) window->win_chat_height = window->win_height - 3 - (lines + 1) - 1; else @@ -203,14 +296,14 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) } else { - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width; + window->win_chat_width = window->win_width - add_left; if (cfg_look_infobar) window->win_chat_height = window->win_height - 4; else window->win_chat_height = window->win_height - 3; - window->win_chat_cursor_x = window->win_x; + window->win_chat_cursor_x = window->win_x + add_left; window->win_chat_cursor_y = window->win_y; window->win_nick_x = -1; window->win_nick_y = -1; @@ -229,18 +322,18 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) void gui_window_draw_separator (t_gui_window *window) { - if (window->win_separator) - delwin (window->win_separator); + if (GUI_CURSES(window)->win_separator) + delwin (GUI_CURSES(window)->win_separator); if (window->win_x > 0) { - window->win_separator = newwin (window->win_height, - 1, - window->win_y, - window->win_x - 1); - gui_window_set_weechat_color (window->win_separator, COLOR_WIN_SEPARATOR); - wborder (window->win_separator, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); - wnoutrefresh (window->win_separator); + GUI_CURSES(window)->win_separator = newwin (window->win_height, + 1, + window->win_y, + window->win_x - 1); + gui_window_set_weechat_color (GUI_CURSES(window)->win_separator, COLOR_WIN_SEPARATOR); + wborder (GUI_CURSES(window)->win_separator, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); + wnoutrefresh (GUI_CURSES(window)->win_separator); refresh (); } } @@ -263,7 +356,7 @@ gui_window_redraw_buffer (t_gui_buffer *buffer) { gui_chat_draw_title (buffer, 1); gui_chat_draw (buffer, 1); - if (ptr_win->win_nick) + if (GUI_CURSES(ptr_win)->win_nick) gui_nicklist_draw (buffer, 1); gui_status_draw (buffer, 1); if (cfg_look_infobar) @@ -271,6 +364,7 @@ gui_window_redraw_buffer (t_gui_buffer *buffer) gui_input_draw (buffer, 1); } } + gui_panel_redraw_buffer (buffer); } /* @@ -298,81 +392,57 @@ gui_window_switch_to_buffer (t_gui_window *window, t_gui_buffer *buffer) gui_window_calculate_pos_size (window, 1); /* destroy Curses windows */ - if (window->win_title) - { - delwin (window->win_title); - window->win_title = NULL; - } - if (window->win_nick) - { - delwin (window->win_nick); - window->win_nick = NULL; - } - if (window->win_status) - { - delwin (window->win_status); - window->win_status = NULL; - } - if (window->win_infobar) - { - delwin (window->win_infobar); - window->win_infobar = NULL; - } - if (window->win_input) - { - delwin (window->win_input); - window->win_input = NULL; - } - + gui_window_objects_free (window, 0); + /* create Curses windows */ - window->win_title = newwin (1, - window->win_width, - window->win_y, - window->win_x); - window->win_input = newwin (1, - window->win_width, - window->win_y + window->win_height - 1, - window->win_x); + GUI_CURSES(window)->win_title = newwin (1, + window->win_width, + window->win_y, + window->win_x); + GUI_CURSES(window)->win_input = newwin (1, + window->win_width, + window->win_y + window->win_height - 1, + window->win_x); if (BUFFER_IS_CHANNEL(buffer)) { - if (window->win_chat) - delwin (window->win_chat); - window->win_chat = newwin (window->win_chat_height, - window->win_chat_width, - window->win_chat_y, - window->win_chat_x); + if (GUI_CURSES(window)->win_chat) + delwin (GUI_CURSES(window)->win_chat); + GUI_CURSES(window)->win_chat = newwin (window->win_chat_height, + window->win_chat_width, + window->win_chat_y, + window->win_chat_x); if (cfg_look_nicklist) - window->win_nick = newwin (window->win_nick_height, - window->win_nick_width, - window->win_nick_y, - window->win_nick_x); + GUI_CURSES(window)->win_nick = newwin (window->win_nick_height, + window->win_nick_width, + window->win_nick_y, + window->win_nick_x); else - window->win_nick = NULL; + GUI_CURSES(window)->win_nick = NULL; } if (!(BUFFER_IS_CHANNEL(buffer))) { - if (window->win_chat) - delwin (window->win_chat); - window->win_chat = newwin (window->win_chat_height, - window->win_chat_width, - window->win_chat_y, - window->win_chat_x); + if (GUI_CURSES(window)->win_chat) + delwin (GUI_CURSES(window)->win_chat); + GUI_CURSES(window)->win_chat = newwin (window->win_chat_height, + window->win_chat_width, + window->win_chat_y, + window->win_chat_x); } /* create status/infobar windows */ if (cfg_look_infobar) { - window->win_infobar = newwin (1, window->win_width, - window->win_y + window->win_height - 2, - window->win_x); - window->win_status = newwin (1, window->win_width, - window->win_y + window->win_height - 3, - window->win_x); + GUI_CURSES(window)->win_infobar = newwin (1, window->win_width, + window->win_y + window->win_height - 2, + window->win_x); + GUI_CURSES(window)->win_status = newwin (1, window->win_width, + window->win_y + window->win_height - 3, + window->win_x); } else - window->win_status = newwin (1, window->win_width, - window->win_y + window->win_height - 2, - window->win_x); + GUI_CURSES(window)->win_status = newwin (1, window->win_width, + window->win_y + window->win_height - 2, + window->win_x); window->start_line = NULL; window->start_line_pos = 0; @@ -633,21 +703,6 @@ gui_window_nick_page_down (t_gui_window *window) } } -/* - * gui_window_init_subwindows: init subviews for a WeeChat window - */ - -void -gui_window_init_subwindows (t_gui_window *window) -{ - window->win_title = NULL; - window->win_chat = NULL; - window->win_nick = NULL; - window->win_status = NULL; - window->win_infobar = NULL; - window->win_input = NULL; -} - /* * gui_window_auto_resize: auto-resize all windows, according to % of global size * This function is called after a terminal resize. @@ -718,7 +773,9 @@ gui_window_refresh_windows () { old_current_window = gui_current_window; - if (gui_window_auto_resize (gui_windows_tree, 0, 0, COLS, LINES, 0) < 0) + if (gui_window_auto_resize (gui_windows_tree, 0, 0, + gui_window_get_width (), + gui_window_get_height (), 0) < 0) gui_window_merge_all (gui_current_window); for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) @@ -839,7 +896,9 @@ gui_window_resize (t_gui_window *window, int pourcentage) parent->split_pct = pourcentage; else parent->split_pct = 100 - pourcentage; - if (gui_window_auto_resize (gui_windows_tree, 0, 0, COLS, LINES, 1) < 0) + if (gui_window_auto_resize (gui_windows_tree, 0, 0, + gui_window_get_width (), + gui_window_get_height (), 1) < 0) parent->split_pct = old_split_pct; else gui_window_refresh_windows (); @@ -898,21 +957,30 @@ gui_window_merge (t_gui_window *window) void gui_window_merge_all (t_gui_window *window) { + int num_deleted; + + num_deleted = 0; while (gui_windows->next_window) { gui_window_free ((gui_windows == window) ? gui_windows->next_window : gui_windows); + num_deleted++; + } + + if (num_deleted > 0) + { + gui_window_tree_free (&gui_windows_tree); + gui_window_tree_init (window); + window->ptr_tree = gui_windows_tree; + window->win_x = 0; + window->win_y = 0; + window->win_width = gui_window_get_width (); + window->win_height = gui_window_get_height (); + window->win_width_pct = 100; + window->win_height_pct = 100; + gui_current_window = window; + gui_window_switch_to_buffer (window, window->buffer); + gui_window_redraw_buffer (window->buffer); } - gui_window_tree_free (&gui_windows_tree); - gui_window_tree_init (window); - window->ptr_tree = gui_windows_tree; - window->win_x = 0; - window->win_y = 0; - window->win_width = COLS; - window->win_height = LINES; - window->win_width_pct = 100; - window->win_height_pct = 100; - gui_window_switch_to_buffer (window, window->buffer); - gui_window_redraw_buffer (window->buffer); } /* @@ -1080,6 +1148,8 @@ gui_window_refresh_screen () if (gui_ok) gui_window_refresh_windows (); + + gui_refresh_screen_needed = 0; } /* @@ -1089,7 +1159,7 @@ gui_window_refresh_screen () void gui_window_refresh_screen_sigwinch () { - gui_window_refresh_screen (); + gui_refresh_screen_needed = 1; signal (SIGWINCH, gui_window_refresh_screen_sigwinch); } @@ -1173,3 +1243,20 @@ gui_window_reset_title () } } } + +/* + * gui_window_objects_print_log: print window Curses objects infos in log + * (usually for crash dump) + */ + +void +gui_window_objects_print_log (t_gui_window *window) +{ + weechat_log_printf (" win_title . . . . . : 0x%X\n", GUI_CURSES(window)->win_title); + weechat_log_printf (" win_chat. . . . . . : 0x%X\n", GUI_CURSES(window)->win_chat); + weechat_log_printf (" win_nick. . . . . . : 0x%X\n", GUI_CURSES(window)->win_nick); + weechat_log_printf (" win_status. . . . . : 0x%X\n", GUI_CURSES(window)->win_status); + weechat_log_printf (" win_infobar . . . . : 0x%X\n", GUI_CURSES(window)->win_infobar); + weechat_log_printf (" win_input . . . . . : 0x%X\n", GUI_CURSES(window)->win_input); + weechat_log_printf (" win_separator . . . : 0x%X\n", GUI_CURSES(window)->win_separator); +} diff --git a/weechat/ChangeLog b/weechat/ChangeLog index 7ce9a9a3c..0d79401fc 100644 --- a/weechat/ChangeLog +++ b/weechat/ChangeLog @@ -1,19 +1,21 @@ WeeChat - Wee Enhanced Environment for Chat =========================================== -ChangeLog - 2006-05-05 +ChangeLog - 2006-05-07 Version 0.1.9 (under dev!): + * fixed refresh bug (deadlock in curses) when terminal is resized + (bug #16542) * fixed nicklist sort bug * added russian translations (thanks to Pavel Shevchuk) * added german doc (thanks to Frank Zacharias) * added missing IRC commands (290, 292, 437, 974) * fixed crash when multiple pv have same name: now it's forbidden and pv buffer is not renamed (when a nick changes) if another - exists with same name + exists with same name (bug #16369) * command /clear [-all] now clears hotlist - * fixed crash after /upgrade if a line in history is empty - * fixed many crashes with DCC chat + * fixed crash after /upgrade if a line in history is empty (bug #16379) + * fixed many crashes with DCC chat (bug #16416) * added new option to customize input prompt * added nick modes * fixed commands 332, 333 (/topic now ok when channel is not opened) diff --git a/weechat/src/gui/curses/gui-main.c b/weechat/src/gui/curses/gui-curses-main.c similarity index 90% rename from weechat/src/gui/curses/gui-main.c rename to weechat/src/gui/curses/gui-curses-main.c index 0e8c61fd2..2588443b1 100644 --- a/weechat/src/gui/curses/gui-main.c +++ b/weechat/src/gui/curses/gui-curses-main.c @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* gui-main.c: main loop and keyboard management for Curses GUI */ +/* gui-curses-main.c: main loop for Curses GUI */ #ifdef HAVE_CONFIG_H @@ -30,12 +30,6 @@ #include #include -#ifdef HAVE_NCURSESW_CURSES_H -#include -#else -#include -#endif - #include "../../common/weechat.h" #include "../gui.h" #include "../../common/fifo.h" @@ -77,6 +71,10 @@ gui_main_loop () check_away = 0; while (!quit_weechat) { + /* refresh needed ? */ + if (gui_refresh_screen_needed) + gui_window_refresh_screen (); + new_time = time (NULL); local_time = localtime (&new_time); @@ -113,9 +111,9 @@ gui_main_loop () if (cfg_look_infobar_seconds) { gui_infobar_draw_time (gui_current_window->buffer); - wmove (gui_current_window->win_input, + wmove (GUI_CURSES(gui_current_window)->win_input, 0, gui_current_window->win_input_x); - wrefresh (gui_current_window->win_input); + wrefresh (GUI_CURSES(gui_current_window)->win_input); } /* infobar count down */ @@ -289,13 +287,13 @@ gui_main_init () { gui_current_window = gui_windows; gui_buffer_new (gui_windows, NULL, NULL, BUFFER_TYPE_STANDARD, 1); - - signal (SIGWINCH, gui_window_refresh_screen_sigwinch); - + if (cfg_look_set_title) gui_window_set_title (); - + gui_init_ok = 1; + + signal (SIGWINCH, gui_window_refresh_screen_sigwinch); } } @@ -306,32 +304,18 @@ gui_main_init () void gui_main_end () { - t_gui_window *ptr_win; - /* free clipboard buffer */ if (gui_input_clipboard) - free(gui_input_clipboard); + free (gui_input_clipboard); + + /* delete all panels */ + while (gui_panels) + gui_panel_free (gui_panels); - /* delete all windows */ - for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) - { - if (ptr_win->win_title) - delwin (ptr_win->win_title); - if (ptr_win->win_chat) - delwin (ptr_win->win_chat); - if (ptr_win->win_nick) - delwin (ptr_win->win_nick); - if (ptr_win->win_status) - delwin (ptr_win->win_status); - if (ptr_win->win_infobar) - delwin (ptr_win->win_infobar); - if (ptr_win->win_input) - delwin (ptr_win->win_input); - } - /* delete all buffers */ + gui_window_merge_all (gui_current_window); while (gui_buffers) - gui_buffer_free (gui_buffers, 0); + gui_buffer_free (gui_buffers, 0); /* delete all windows */ while (gui_windows) @@ -349,7 +333,7 @@ gui_main_end () if (cfg_look_set_title) gui_window_reset_title (); - /* end of curses output */ + /* end of Curses output */ refresh (); endwin (); } diff --git a/weechat/src/gui/curses/gui-window.c b/weechat/src/gui/curses/gui-curses-window.c similarity index 78% rename from weechat/src/gui/curses/gui-window.c rename to weechat/src/gui/curses/gui-curses-window.c index 8cb067234..006f41f47 100644 --- a/weechat/src/gui/curses/gui-window.c +++ b/weechat/src/gui/curses/gui-curses-window.c @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* gui-window.c: window display functions for Curses GUI */ +/* gui-curses-window.c: window display functions for Curses GUI */ #ifdef HAVE_CONFIG_H @@ -29,12 +29,6 @@ #include #include -#ifdef HAVE_NCURSESW_CURSES_H -#include -#else -#include -#endif - #include "../../common/weechat.h" #include "../gui.h" #include "../../common/hotlist.h" @@ -42,6 +36,99 @@ #include "gui-curses.h" +int gui_refresh_screen_needed = 0; + + +/* + * gui_window_get_width: get screen width (terminal width in chars for Curses) + */ + +int +gui_window_get_width () +{ + return COLS; +} + +/* + * gui_window_get_height: get screen height (terminal height in chars for Curses) + */ + +int +gui_window_get_height () +{ + return LINES; +} + +/* + * gui_window_objects_init: init Curses windows + */ + +int +gui_window_objects_init (t_gui_window *window) +{ + t_gui_curses_objects *new_objects; + + if ((new_objects = (t_gui_curses_objects *) malloc (sizeof (t_gui_curses_objects)))) + { + window->gui_objects = new_objects; + GUI_CURSES(window)->win_title = NULL; + GUI_CURSES(window)->win_chat = NULL; + GUI_CURSES(window)->win_nick = NULL; + GUI_CURSES(window)->win_status = NULL; + GUI_CURSES(window)->win_infobar = NULL; + GUI_CURSES(window)->win_input = NULL; + GUI_CURSES(window)->win_separator = NULL; + GUI_CURSES(window)->panel_windows = NULL; + return 1; + } + else + return 0; +} + +/* + * gui_window_objects_free: free Curses windows for a window + */ + +void +gui_window_objects_free (t_gui_window *window, int free_separator) +{ + if (GUI_CURSES(window)->win_title) + { + delwin (GUI_CURSES(window)->win_title); + GUI_CURSES(window)->win_title = NULL; + } + if (GUI_CURSES(window)->win_chat) + { + delwin (GUI_CURSES(window)->win_chat); + GUI_CURSES(window)->win_chat = NULL; + } + if (GUI_CURSES(window)->win_nick) + { + delwin (GUI_CURSES(window)->win_nick); + GUI_CURSES(window)->win_nick = NULL; + } + if (GUI_CURSES(window)->win_status) + { + delwin (GUI_CURSES(window)->win_status); + GUI_CURSES(window)->win_status = NULL; + } + if (GUI_CURSES(window)->win_infobar) + { + delwin (GUI_CURSES(window)->win_infobar); + GUI_CURSES(window)->win_infobar = NULL; + } + if (GUI_CURSES(window)->win_input) + { + delwin (GUI_CURSES(window)->win_input); + GUI_CURSES(window)->win_input = NULL; + } + if (free_separator && GUI_CURSES(window)->win_separator) + { + delwin (GUI_CURSES(window)->win_separator); + GUI_CURSES(window)->win_separator = NULL; + } +} + /* * gui_window_curses_clear: clear a Curses window */ @@ -82,10 +169,16 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) { int max_length, max_height, lines; int num_nicks, num_op, num_halfop, num_voice, num_normal; + int add_right, add_left, add_top, add_bottom; if (!gui_ok) return 0; + add_left = gui_panel_get_size (window, GUI_PANEL_LEFT); + add_right = gui_panel_get_size (window, GUI_PANEL_RIGHT); + add_top = gui_panel_get_size (window, GUI_PANEL_TOP); + add_bottom = gui_panel_get_size (window, GUI_PANEL_BOTTOM); + /* init chat & nicklist settings */ if (cfg_look_nicklist && BUFFER_IS_CHANNEL(window->buffer)) { @@ -128,9 +221,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) switch (cfg_look_nicklist_position) { case CFG_LOOK_NICKLIST_LEFT: - window->win_chat_x = window->win_x + max_length + 2; + window->win_chat_x = window->win_x + add_left + max_length + 2; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width - max_length - 2; + window->win_chat_width = window->win_width - add_left - max_length - 2; window->win_nick_x = window->win_x + 0; window->win_nick_y = window->win_y + 1; window->win_nick_width = max_length + 2; @@ -147,9 +240,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) window->win_nick_num_max = window->win_nick_height; break; case CFG_LOOK_NICKLIST_RIGHT: - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width - max_length - 2; + window->win_chat_width = window->win_width - add_left - max_length - 2; window->win_nick_x = window->win_x + window->win_width - max_length - 2; window->win_nick_y = window->win_y + 1; window->win_nick_width = max_length + 2; @@ -166,9 +259,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) window->win_nick_num_max = window->win_nick_height; break; case CFG_LOOK_NICKLIST_TOP: - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1 + (lines + 1); - window->win_chat_width = window->win_width; + window->win_chat_width = window->win_width - add_left; if (cfg_look_infobar) window->win_chat_height = window->win_height - 3 - (lines + 1) - 1; else @@ -180,9 +273,9 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) window->win_nick_num_max = lines * (window->win_nick_width / (max_length + 2)); break; case CFG_LOOK_NICKLIST_BOTTOM: - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width; + window->win_chat_width = window->win_width - add_left; if (cfg_look_infobar) window->win_chat_height = window->win_height - 3 - (lines + 1) - 1; else @@ -203,14 +296,14 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) } else { - window->win_chat_x = window->win_x; + window->win_chat_x = window->win_x + add_left; window->win_chat_y = window->win_y + 1; - window->win_chat_width = window->win_width; + window->win_chat_width = window->win_width - add_left; if (cfg_look_infobar) window->win_chat_height = window->win_height - 4; else window->win_chat_height = window->win_height - 3; - window->win_chat_cursor_x = window->win_x; + window->win_chat_cursor_x = window->win_x + add_left; window->win_chat_cursor_y = window->win_y; window->win_nick_x = -1; window->win_nick_y = -1; @@ -229,18 +322,18 @@ gui_window_calculate_pos_size (t_gui_window *window, int force_calculate) void gui_window_draw_separator (t_gui_window *window) { - if (window->win_separator) - delwin (window->win_separator); + if (GUI_CURSES(window)->win_separator) + delwin (GUI_CURSES(window)->win_separator); if (window->win_x > 0) { - window->win_separator = newwin (window->win_height, - 1, - window->win_y, - window->win_x - 1); - gui_window_set_weechat_color (window->win_separator, COLOR_WIN_SEPARATOR); - wborder (window->win_separator, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); - wnoutrefresh (window->win_separator); + GUI_CURSES(window)->win_separator = newwin (window->win_height, + 1, + window->win_y, + window->win_x - 1); + gui_window_set_weechat_color (GUI_CURSES(window)->win_separator, COLOR_WIN_SEPARATOR); + wborder (GUI_CURSES(window)->win_separator, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); + wnoutrefresh (GUI_CURSES(window)->win_separator); refresh (); } } @@ -263,7 +356,7 @@ gui_window_redraw_buffer (t_gui_buffer *buffer) { gui_chat_draw_title (buffer, 1); gui_chat_draw (buffer, 1); - if (ptr_win->win_nick) + if (GUI_CURSES(ptr_win)->win_nick) gui_nicklist_draw (buffer, 1); gui_status_draw (buffer, 1); if (cfg_look_infobar) @@ -271,6 +364,7 @@ gui_window_redraw_buffer (t_gui_buffer *buffer) gui_input_draw (buffer, 1); } } + gui_panel_redraw_buffer (buffer); } /* @@ -298,81 +392,57 @@ gui_window_switch_to_buffer (t_gui_window *window, t_gui_buffer *buffer) gui_window_calculate_pos_size (window, 1); /* destroy Curses windows */ - if (window->win_title) - { - delwin (window->win_title); - window->win_title = NULL; - } - if (window->win_nick) - { - delwin (window->win_nick); - window->win_nick = NULL; - } - if (window->win_status) - { - delwin (window->win_status); - window->win_status = NULL; - } - if (window->win_infobar) - { - delwin (window->win_infobar); - window->win_infobar = NULL; - } - if (window->win_input) - { - delwin (window->win_input); - window->win_input = NULL; - } - + gui_window_objects_free (window, 0); + /* create Curses windows */ - window->win_title = newwin (1, - window->win_width, - window->win_y, - window->win_x); - window->win_input = newwin (1, - window->win_width, - window->win_y + window->win_height - 1, - window->win_x); + GUI_CURSES(window)->win_title = newwin (1, + window->win_width, + window->win_y, + window->win_x); + GUI_CURSES(window)->win_input = newwin (1, + window->win_width, + window->win_y + window->win_height - 1, + window->win_x); if (BUFFER_IS_CHANNEL(buffer)) { - if (window->win_chat) - delwin (window->win_chat); - window->win_chat = newwin (window->win_chat_height, - window->win_chat_width, - window->win_chat_y, - window->win_chat_x); + if (GUI_CURSES(window)->win_chat) + delwin (GUI_CURSES(window)->win_chat); + GUI_CURSES(window)->win_chat = newwin (window->win_chat_height, + window->win_chat_width, + window->win_chat_y, + window->win_chat_x); if (cfg_look_nicklist) - window->win_nick = newwin (window->win_nick_height, - window->win_nick_width, - window->win_nick_y, - window->win_nick_x); + GUI_CURSES(window)->win_nick = newwin (window->win_nick_height, + window->win_nick_width, + window->win_nick_y, + window->win_nick_x); else - window->win_nick = NULL; + GUI_CURSES(window)->win_nick = NULL; } if (!(BUFFER_IS_CHANNEL(buffer))) { - if (window->win_chat) - delwin (window->win_chat); - window->win_chat = newwin (window->win_chat_height, - window->win_chat_width, - window->win_chat_y, - window->win_chat_x); + if (GUI_CURSES(window)->win_chat) + delwin (GUI_CURSES(window)->win_chat); + GUI_CURSES(window)->win_chat = newwin (window->win_chat_height, + window->win_chat_width, + window->win_chat_y, + window->win_chat_x); } /* create status/infobar windows */ if (cfg_look_infobar) { - window->win_infobar = newwin (1, window->win_width, - window->win_y + window->win_height - 2, - window->win_x); - window->win_status = newwin (1, window->win_width, - window->win_y + window->win_height - 3, - window->win_x); + GUI_CURSES(window)->win_infobar = newwin (1, window->win_width, + window->win_y + window->win_height - 2, + window->win_x); + GUI_CURSES(window)->win_status = newwin (1, window->win_width, + window->win_y + window->win_height - 3, + window->win_x); } else - window->win_status = newwin (1, window->win_width, - window->win_y + window->win_height - 2, - window->win_x); + GUI_CURSES(window)->win_status = newwin (1, window->win_width, + window->win_y + window->win_height - 2, + window->win_x); window->start_line = NULL; window->start_line_pos = 0; @@ -633,21 +703,6 @@ gui_window_nick_page_down (t_gui_window *window) } } -/* - * gui_window_init_subwindows: init subviews for a WeeChat window - */ - -void -gui_window_init_subwindows (t_gui_window *window) -{ - window->win_title = NULL; - window->win_chat = NULL; - window->win_nick = NULL; - window->win_status = NULL; - window->win_infobar = NULL; - window->win_input = NULL; -} - /* * gui_window_auto_resize: auto-resize all windows, according to % of global size * This function is called after a terminal resize. @@ -718,7 +773,9 @@ gui_window_refresh_windows () { old_current_window = gui_current_window; - if (gui_window_auto_resize (gui_windows_tree, 0, 0, COLS, LINES, 0) < 0) + if (gui_window_auto_resize (gui_windows_tree, 0, 0, + gui_window_get_width (), + gui_window_get_height (), 0) < 0) gui_window_merge_all (gui_current_window); for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) @@ -839,7 +896,9 @@ gui_window_resize (t_gui_window *window, int pourcentage) parent->split_pct = pourcentage; else parent->split_pct = 100 - pourcentage; - if (gui_window_auto_resize (gui_windows_tree, 0, 0, COLS, LINES, 1) < 0) + if (gui_window_auto_resize (gui_windows_tree, 0, 0, + gui_window_get_width (), + gui_window_get_height (), 1) < 0) parent->split_pct = old_split_pct; else gui_window_refresh_windows (); @@ -898,21 +957,30 @@ gui_window_merge (t_gui_window *window) void gui_window_merge_all (t_gui_window *window) { + int num_deleted; + + num_deleted = 0; while (gui_windows->next_window) { gui_window_free ((gui_windows == window) ? gui_windows->next_window : gui_windows); + num_deleted++; + } + + if (num_deleted > 0) + { + gui_window_tree_free (&gui_windows_tree); + gui_window_tree_init (window); + window->ptr_tree = gui_windows_tree; + window->win_x = 0; + window->win_y = 0; + window->win_width = gui_window_get_width (); + window->win_height = gui_window_get_height (); + window->win_width_pct = 100; + window->win_height_pct = 100; + gui_current_window = window; + gui_window_switch_to_buffer (window, window->buffer); + gui_window_redraw_buffer (window->buffer); } - gui_window_tree_free (&gui_windows_tree); - gui_window_tree_init (window); - window->ptr_tree = gui_windows_tree; - window->win_x = 0; - window->win_y = 0; - window->win_width = COLS; - window->win_height = LINES; - window->win_width_pct = 100; - window->win_height_pct = 100; - gui_window_switch_to_buffer (window, window->buffer); - gui_window_redraw_buffer (window->buffer); } /* @@ -1080,6 +1148,8 @@ gui_window_refresh_screen () if (gui_ok) gui_window_refresh_windows (); + + gui_refresh_screen_needed = 0; } /* @@ -1089,7 +1159,7 @@ gui_window_refresh_screen () void gui_window_refresh_screen_sigwinch () { - gui_window_refresh_screen (); + gui_refresh_screen_needed = 1; signal (SIGWINCH, gui_window_refresh_screen_sigwinch); } @@ -1173,3 +1243,20 @@ gui_window_reset_title () } } } + +/* + * gui_window_objects_print_log: print window Curses objects infos in log + * (usually for crash dump) + */ + +void +gui_window_objects_print_log (t_gui_window *window) +{ + weechat_log_printf (" win_title . . . . . : 0x%X\n", GUI_CURSES(window)->win_title); + weechat_log_printf (" win_chat. . . . . . : 0x%X\n", GUI_CURSES(window)->win_chat); + weechat_log_printf (" win_nick. . . . . . : 0x%X\n", GUI_CURSES(window)->win_nick); + weechat_log_printf (" win_status. . . . . : 0x%X\n", GUI_CURSES(window)->win_status); + weechat_log_printf (" win_infobar . . . . : 0x%X\n", GUI_CURSES(window)->win_infobar); + weechat_log_printf (" win_input . . . . . : 0x%X\n", GUI_CURSES(window)->win_input); + weechat_log_printf (" win_separator . . . : 0x%X\n", GUI_CURSES(window)->win_separator); +}