X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Ffe-text%2Fgui-windows.c;fp=apps%2Firssi%2Fsrc%2Ffe-text%2Fgui-windows.c;h=9a199cdded559dc24af7bd7c350264dbb378f05b;hb=23c5df1c8b0bfe539d3fa65802186e6e09e044aa;hp=0000000000000000000000000000000000000000;hpb=0f9738ce962b8498bbed0a75d5fb6fa127e3577f;p=silc.git diff --git a/apps/irssi/src/fe-text/gui-windows.c b/apps/irssi/src/fe-text/gui-windows.c new file mode 100644 index 00000000..9a199cdd --- /dev/null +++ b/apps/irssi/src/fe-text/gui-windows.c @@ -0,0 +1,333 @@ +/* + gui-windows.c : irssi + + Copyright (C) 1999-2001 Timo Sirainen + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "signals.h" +#include "misc.h" +#include "settings.h" +#include "special-vars.h" + +#include "screen.h" +#include "gui-entry.h" +#include "gui-windows.h" +#include "gui-printtext.h" + +static int window_create_override; + +static char *prompt, *prompt_window; + +static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window, + MAIN_WINDOW_REC *parent) +{ + GUI_WINDOW_REC *gui; + + window->width = parent->width; + window->height = parent->height; + + gui = g_new0(GUI_WINDOW_REC, 1); + gui->parent = parent; + gui->view = textbuffer_view_create(textbuffer_create(), + window->width, window->height, + settings_get_int("indent"), + settings_get_bool("indent_always")); + return gui; +} + +static void gui_window_deinit(GUI_WINDOW_REC *gui) +{ + textbuffer_view_destroy(gui->view); + g_free(gui); +} + +static void sig_window_create_override(gpointer tab) +{ + window_create_override = GPOINTER_TO_INT(tab); +} + +static void gui_window_created(WINDOW_REC *window) +{ + MAIN_WINDOW_REC *parent; + + g_return_if_fail(window != NULL); + + parent = window_create_override != 0 && + active_win != NULL && WINDOW_GUI(active_win) != NULL ? + WINDOW_GUI(active_win)->parent : mainwindow_create(); + if (parent == NULL) { + /* not enough space for new window, but we really can't + abort creation of the window anymore, so create hidden + window instead. */ + parent = WINDOW_GUI(active_win)->parent; + } + window_create_override = -1; + + if (settings_get_bool("autostick_split_windows") && + (parent->sticky_windows != NULL || + (mainwindows->next != NULL && parent->active == NULL))) { + /* set the window sticky */ + parent->sticky_windows = + g_slist_append(parent->sticky_windows, window); + } + + if (parent->active == NULL) parent->active = window; + window->gui_data = gui_window_init(window, parent); + signal_emit("gui window created", 1, window); +} + +static void gui_window_destroyed(WINDOW_REC *window) +{ + MAIN_WINDOW_REC *parent; + GUI_WINDOW_REC *gui; + + g_return_if_fail(window != NULL); + + gui = WINDOW_GUI(window); + parent = gui->parent; + + signal_emit("gui window destroyed", 1, window); + + gui_window_deinit(gui); + window->gui_data = NULL; + + if (parent->active == window && mainwindows->next != NULL) + mainwindow_destroy(parent); +} + +void gui_window_resize(WINDOW_REC *window, int width, int height) +{ + GUI_WINDOW_REC *gui; + + gui = WINDOW_GUI(window); + + window->width = width; + window->height = height; + textbuffer_view_resize(gui->view, width, height); +} + +void gui_window_scroll(WINDOW_REC *window, int lines) +{ + g_return_if_fail(window != NULL); + + textbuffer_view_scroll(WINDOW_GUI(window)->view, lines); + signal_emit("gui page scrolled", 1, window); +} + +void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line) +{ + g_return_if_fail(window != NULL); + g_return_if_fail(line != NULL); + + textbuffer_view_scroll_line(WINDOW_GUI(window)->view, line); + signal_emit("gui page scrolled", 1, window); +} + +void window_update_prompt(void) +{ + const char *special; + char *prompt, *text; + int var_used; + + special = settings_get_str(active_win->active != NULL ? + "prompt" : "prompt_window"); + if (*special == '\0') { + gui_entry_set_prompt(""); + return; + } + + prompt = parse_special_string(special, active_win->active_server, + active_win->active, "", &var_used, + PARSE_FLAG_ISSET_ANY | + PARSE_FLAG_ESCAPE_VARS); + if (!var_used && strchr(special, '$') != NULL) { + /* none of the $vars had non-empty values, use empty prompt */ + *prompt = '\0'; + } + + /* set prompt */ + text = show_lowascii(prompt); + gui_entry_set_prompt(text); + g_free(text); + + g_free(prompt); +} + +static void window_update_prompt_server(SERVER_REC *server) +{ + if (server == active_win->active_server) + window_update_prompt(); +} + +static void window_update_prompt_window(WINDOW_REC *window) +{ + if (window == active_win) + window_update_prompt(); +} + +static void window_update_prompt_window_item(WI_ITEM_REC *item) +{ + if (item == active_win->active) + window_update_prompt(); +} + +void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent) +{ + MAIN_WINDOW_REC *oldparent; + + oldparent = WINDOW_GUI(window)->parent; + if (oldparent == parent) + return; + + textbuffer_view_set_window(WINDOW_GUI(window)->view, NULL); + + WINDOW_GUI(window)->parent = parent; + if (parent->height != oldparent->height || + parent->width != oldparent->width) + gui_window_resize(window, parent->width, parent->height); +} + +static MAIN_WINDOW_REC *mainwindow_find_unsticky(void) +{ + GSList *tmp; + + for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { + MAIN_WINDOW_REC *rec = tmp->data; + + if (rec->sticky_windows == NULL) + return rec; + } + + /* all windows are sticky, fallback to active window */ + return active_mainwin; +} + +static void signal_window_changed(WINDOW_REC *window, WINDOW_REC *old_window) +{ + MAIN_WINDOW_REC *parent; + + g_return_if_fail(window != NULL); + + if (quitting) return; + + parent = WINDOW_GUI(window)->parent; + if (is_window_visible(window)) { + /* already visible */ + active_mainwin = parent; + } else if (active_mainwin == NULL) { + /* no main window set yet */ + active_mainwin = parent; + } else if (g_slist_find(parent->sticky_windows, window) != NULL) { + /* window is sticky, switch to correct main window */ + if (parent != active_mainwin) + active_mainwin = parent; + } else { + /* move window to active main window */ + if (active_mainwin->sticky_windows != NULL) { + /* active mainwindow is sticky, we'll need to + set the window active somewhere else */ + active_mainwin = mainwindow_find_unsticky(); + } + gui_window_reparent(window, active_mainwin); + } + active_mainwin->active = window; + + if (old_window != NULL && !is_window_visible(old_window)) + textbuffer_view_set_window(WINDOW_GUI(old_window)->view, NULL); + + textbuffer_view_set_window(WINDOW_GUI(window)->view, + parent->curses_win); + + window_update_prompt(); +} + +static void sig_check_window_update(WINDOW_REC *window) +{ + if (window == active_win) + window_update_prompt(); +} + +static void read_settings(void) +{ + GSList *tmp; + + SIGNAL_FUNC funcs[] = { + (SIGNAL_FUNC) window_update_prompt, + (SIGNAL_FUNC) window_update_prompt_server, + (SIGNAL_FUNC) window_update_prompt_window, + (SIGNAL_FUNC) window_update_prompt_window_item + }; + + if (prompt != NULL) { + special_vars_remove_signals(prompt, 4, funcs); + special_vars_remove_signals(prompt_window, 4, funcs); + g_free(prompt); + g_free(prompt_window); + } + prompt = g_strdup(settings_get_str("prompt")); + prompt_window = g_strdup(settings_get_str("prompt_window")); + + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + textbuffer_view_set_default_indent(WINDOW_GUI(rec)->view, + settings_get_int("indent"), + settings_get_bool("indent_always")); + } + + special_vars_add_signals(prompt, 4, funcs); + special_vars_add_signals(prompt_window, 4, funcs); + + if (active_win != NULL) window_update_prompt(); +} + +void gui_windows_init(void) +{ + settings_add_bool("lookandfeel", "autostick_split_windows", TRUE); + settings_add_int("lookandfeel", "indent", 10); + settings_add_bool("lookandfeel", "indent_always", FALSE); + settings_add_str("lookandfeel", "prompt", "[$[.15]T] "); + settings_add_str("lookandfeel", "prompt_window", "[$winname] "); + + prompt = NULL; prompt_window = NULL; + window_create_override = -1; + + read_settings(); + signal_add("gui window create override", (SIGNAL_FUNC) sig_window_create_override); + signal_add("window created", (SIGNAL_FUNC) gui_window_created); + signal_add("window destroyed", (SIGNAL_FUNC) gui_window_destroyed); + signal_add_first("window changed", (SIGNAL_FUNC) signal_window_changed); + signal_add("window item remove", (SIGNAL_FUNC) sig_check_window_update); + signal_add("setup changed", (SIGNAL_FUNC) read_settings); +} + +void gui_windows_deinit(void) +{ + g_free_not_null(prompt); + g_free_not_null(prompt_window); + + while (windows != NULL) + window_destroy(windows->data); + + signal_remove("gui window create override", (SIGNAL_FUNC) sig_window_create_override); + signal_remove("window created", (SIGNAL_FUNC) gui_window_created); + signal_remove("window destroyed", (SIGNAL_FUNC) gui_window_destroyed); + signal_remove("window changed", (SIGNAL_FUNC) signal_window_changed); + signal_remove("window item remove", (SIGNAL_FUNC) sig_check_window_update); + signal_remove("setup changed", (SIGNAL_FUNC) read_settings); +}