summaryrefslogtreecommitdiffstats
path: root/src/fe-text/gui-windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fe-text/gui-windows.c')
-rw-r--r--src/fe-text/gui-windows.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c
new file mode 100644
index 0000000..46be239
--- /dev/null
+++ b/src/fe-text/gui-windows.c
@@ -0,0 +1,327 @@
+/*
+ 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.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "module.h"
+#include <irssi/src/core/signals.h>
+#include <irssi/src/core/misc.h>
+#include <irssi/src/core/settings.h>
+#include <irssi/src/core/special-vars.h>
+#include <irssi/src/core/levels.h>
+
+#include <irssi/src/fe-text/term.h>
+#include <irssi/src/fe-text/gui-entry.h>
+#include <irssi/src/fe-text/gui-windows.h>
+#include <irssi/src/fe-text/gui-printtext.h>
+
+static int window_create_override;
+static int wcwidth_impl;
+
+static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window,
+ MAIN_WINDOW_REC *parent)
+{
+ GUI_WINDOW_REC *gui;
+
+ window->width = parent->width;
+ window->height = MAIN_WINDOW_TEXT_HEIGHT(parent);
+
+ gui = g_new0(GUI_WINDOW_REC, 1);
+ gui->parent = parent;
+ gui->view =
+ textbuffer_view_create(textbuffer_create(window), window->width, window->height,
+ settings_get_bool("scroll"), term_type == TERM_TYPE_UTF8);
+ textbuffer_view_set_default_indent(gui->view,
+ settings_get_int("indent"),
+ !settings_get_bool("indent_always"),
+ get_default_indent_func());
+ textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide"));
+ wcwidth_impl = settings_get_choice("wcwidth_implementation");
+ textbuffer_view_set_hidden_level(gui->view, settings_get_level("window_default_hidelevel"));
+ if (parent->active == window)
+ textbuffer_view_set_window(gui->view, parent->screen_win);
+ 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, void *automatic)
+{
+ MAIN_WINDOW_REC *parent;
+ int new_parent;
+
+ g_return_if_fail(window != NULL);
+
+ new_parent = window_create_override == MAIN_WINDOW_TYPE_DEFAULT ||
+ window_create_override == MAIN_WINDOW_TYPE_SPLIT ||
+ window_create_override == MAIN_WINDOW_TYPE_RSPLIT ||
+ active_win == NULL || WINDOW_GUI(active_win) == NULL;
+ parent = !new_parent ? WINDOW_MAIN(active_win) : mainwindow_create(window_create_override == MAIN_WINDOW_TYPE_RSPLIT);
+ 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_MAIN(active_win);
+ }
+ window_create_override = MAIN_WINDOW_TYPE_NONE;
+
+ if (parent->active == NULL) parent->active = window;
+ window->gui_data = gui_window_init(window, parent);
+
+ /* set only non-automatic windows sticky so that the windows
+ irssi creates at startup wont get sticky. */
+ if (automatic == NULL &&
+ (parent->sticky_windows ||
+ (new_parent && settings_get_bool("autostick_split_windows"))))
+ gui_window_set_sticky(window);
+
+ 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;
+
+ gui_window_set_unsticky(window);
+
+ signal_emit("gui window destroyed", 1, window);
+
+ gui_window_deinit(gui);
+ window->gui_data = NULL;
+
+ if (parent->active == window)
+ mainwindow_change_active(parent, window);
+}
+
+void gui_window_resize(WINDOW_REC *window, int width, int height)
+{
+ GUI_WINDOW_REC *gui;
+
+ if (window->width == width && window->height == height)
+ return;
+
+ gui = WINDOW_GUI(window);
+
+ irssi_set_dirty();
+ WINDOW_MAIN(window)->dirty = TRUE;
+
+ 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 gui_window_set_sticky(WINDOW_REC *window)
+{
+ GUI_WINDOW_REC *gui = WINDOW_GUI(window);
+
+ if (!gui->sticky) {
+ gui->sticky = TRUE;
+ gui->parent->sticky_windows++;
+ }
+}
+
+void gui_window_set_unsticky(WINDOW_REC *window)
+{
+ GUI_WINDOW_REC *gui = WINDOW_GUI(window);
+
+ if (gui->sticky) {
+ gui->sticky = FALSE;
+ gui->parent->sticky_windows--;
+ }
+}
+
+void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
+{
+ MAIN_WINDOW_REC *oldparent;
+
+ oldparent = WINDOW_MAIN(window);
+ if (oldparent == parent)
+ return;
+
+ gui_window_set_unsticky(window);
+ textbuffer_view_set_window(WINDOW_GUI(window)->view, NULL);
+
+ WINDOW_MAIN(window) = parent;
+ if (parent->sticky_windows)
+ gui_window_set_sticky(window);
+
+ if (MAIN_WINDOW_TEXT_HEIGHT(parent) !=
+ MAIN_WINDOW_TEXT_HEIGHT(oldparent) ||
+ parent->width != oldparent->width) {
+ gui_window_resize(window, parent->width,
+ MAIN_WINDOW_TEXT_HEIGHT(parent));
+ }
+}
+
+void gui_windows_reset_settings(void)
+{
+ GSList *tmp;
+ int old_wcwidth_impl = wcwidth_impl;
+
+ wcwidth_impl = settings_get_choice("wcwidth_implementation");
+
+ for (tmp = windows; tmp != NULL; tmp = tmp->next) {
+ WINDOW_REC *rec = tmp->data;
+ GUI_WINDOW_REC *gui = WINDOW_GUI(rec);
+
+ if (old_wcwidth_impl != wcwidth_impl) {
+ textbuffer_view_reset_cache(gui->view);
+ }
+
+ textbuffer_view_set_break_wide(gui->view, settings_get_bool("break_wide"));
+
+ textbuffer_view_set_default_indent(gui->view,
+ settings_get_int("indent"),
+ !settings_get_bool("indent_always"),
+ get_default_indent_func());
+
+ textbuffer_view_set_scroll(gui->view,
+ gui->use_scroll ? gui->scroll :
+ settings_get_bool("scroll"));
+
+ if (old_wcwidth_impl != wcwidth_impl) {
+ textbuffer_view_redraw(gui->view);
+ }
+ }
+}
+
+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)
+ return rec;
+ }
+
+ /* all windows are sticky, fallback to active window */
+ return active_mainwin;
+}
+
+static void signal_window_changed(WINDOW_REC *window)
+{
+ MAIN_WINDOW_REC *parent;
+ WINDOW_REC *old_window;
+
+ g_return_if_fail(window != NULL);
+
+ if (quitting) return;
+
+ parent = WINDOW_MAIN(window);
+ 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 (WINDOW_GUI(window)->sticky) {
+ /* 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) {
+ /* 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);
+ }
+
+ old_window = active_mainwin->active;
+ if (old_window != NULL && old_window != window)
+ textbuffer_view_set_window(WINDOW_GUI(old_window)->view, NULL);
+
+ active_mainwin->active = window;
+
+ textbuffer_view_set_window(WINDOW_GUI(window)->view,
+ active_mainwin->screen_win);
+ if (WINDOW_GUI(window)->view->dirty)
+ active_mainwin->dirty = TRUE;
+}
+
+static void read_settings(void)
+{
+ gui_windows_reset_settings();
+}
+
+void gui_windows_init(void)
+{
+ settings_add_bool("lookandfeel", "autostick_split_windows", FALSE);
+ settings_add_bool("lookandfeel", "autounstick_windows", TRUE);
+ settings_add_int("lookandfeel", "indent", 10);
+ settings_add_bool("lookandfeel", "indent_always", FALSE);
+ settings_add_bool("lookandfeel", "break_wide", FALSE);
+ settings_add_bool("lookandfeel", "scroll", TRUE);
+ settings_add_level("lookandfeel", "window_default_hidelevel", "HIDDEN");
+
+ window_create_override = MAIN_WINDOW_TYPE_NONE;
+
+ 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("setup changed", (SIGNAL_FUNC) read_settings);
+}
+
+void gui_windows_deinit(void)
+{
+ 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("setup changed", (SIGNAL_FUNC) read_settings);
+}