Python: Give goto_url_hook only one argument, like follow_url_hook.
[elinks.git] / src / terminal / window.c
blob3bad556d96a31b17e4ef12df103c57ca6750bd5a
1 /* Terminal windows stuff. */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include "elinks.h"
9 #include "bfu/menu.h"
10 #include "terminal/event.h"
11 #include "terminal/tab.h"
12 #include "terminal/terminal.h"
13 #include "terminal/window.h"
14 #include "util/error.h"
15 #include "util/memory.h"
18 void
19 redraw_from_window(struct window *win)
21 struct terminal *term = win->term;
22 struct term_event ev;
23 struct window *end = (struct window *) &term->windows;
25 if (term->redrawing != TREDRAW_READY) return;
27 set_redraw_term_event(&ev, term->width, term->height);
28 term->redrawing = TREDRAW_BUSY;
29 for (win = win->prev; win != end; win = win->prev) {
30 if (!inactive_tab(win))
31 win->handler(win, &ev);
33 term->redrawing = TREDRAW_READY;
36 void
37 redraw_below_window(struct window *win)
39 struct terminal *term = win->term;
40 struct term_event ev;
41 struct window *end = win;
42 enum term_redrawing_state saved_redraw_state = term->redrawing;
44 if (term->redrawing == TREDRAW_DELAYED) return;
46 set_redraw_term_event(&ev, term->width, term->height);
47 term->redrawing = TREDRAW_DELAYED;
48 for (win = term->windows.prev; win != end; win = win->prev) {
49 if (!inactive_tab(win))
50 win->handler(win, &ev);
52 term->redrawing = saved_redraw_state;
55 void
56 add_window(struct terminal *term, window_handler_T handler, void *data)
58 struct term_event ev;
59 struct window *win = mem_calloc(1, sizeof(*win));
61 if (!win) {
62 mem_free_if(data);
63 return;
66 win->handler = handler;
67 win->data = data; /* freed later in delete_window() */
68 win->term = term;
69 win->type = WINDOW_NORMAL;
70 add_at_pos((struct window *) &term->windows, win);
71 set_init_term_event(&ev, term->width, term->height);
72 win->handler(win, &ev);
75 void
76 delete_window(struct window *win)
78 struct term_event ev;
80 /* Updating the status when destroying tabs needs this before the win
81 * handler call. */
82 del_from_list(win);
83 set_abort_term_event(&ev);
84 win->handler(win, &ev);
85 mem_free_if(win->data);
86 redraw_terminal(win->term);
87 mem_free(win);
90 void
91 delete_window_ev(struct window *win, struct term_event *ev)
93 struct window *w;
95 w = list_has_next(win->term->windows, win) ? win->next : NULL;
97 delete_window(win);
99 if (!ev || !w) return;
101 /* If next is a tab send it to the current tab */
102 if (w->type == WINDOW_TAB) {
103 w = get_current_tab(w->term);
106 if (w) w->handler(w, ev);
109 void
110 get_parent_ptr(struct window *win, int *x, int *y)
112 struct window *parent = win->next;
114 if (parent->type == WINDOW_TAB)
115 parent = get_tab_by_number(win->term, win->term->current_tab);
117 if (parent) {
118 *x = parent->x;
119 *y = parent->y;
120 } else {
121 *x = 0;
122 *y = 0;
127 struct ewd {
128 void (*fn)(void *);
129 void *data;
130 unsigned int called_once:1;
133 static void
134 empty_window_handler(struct window *win, struct term_event *ev)
136 struct terminal *term = win->term;
137 struct ewd *ewd = win->data;
138 void (*fn)(void *) = ewd->fn;
139 void *data = ewd->data;
141 if (ewd->called_once) return;
143 switch (ev->ev) {
144 case EVENT_INIT:
145 case EVENT_RESIZE:
146 case EVENT_REDRAW:
147 get_parent_ptr(win, &win->x, &win->y);
148 return;
149 case EVENT_ABORT:
150 fn(data);
151 return;
152 case EVENT_KBD:
153 case EVENT_MOUSE:
154 /* Silence compiler warnings */
155 break;
158 ewd->called_once = 1;
159 delete_window(win);
160 fn(data);
161 term_send_event(term, ev);
164 void
165 add_empty_window(struct terminal *term, void (*fn)(void *), void *data)
167 struct ewd *ewd = mem_alloc(sizeof(*ewd));
169 if (!ewd) return;
170 ewd->fn = fn;
171 ewd->data = data;
172 ewd->called_once = 0;
173 add_window(term, empty_window_handler, ewd);
176 #if CONFIG_DEBUG
177 /* Check that term->windows are in the documented order. */
178 void
179 assert_window_stacking(struct terminal *term)
181 enum { WANT_ANY, WANT_TAB, WANT_NONE } want = WANT_ANY;
182 const struct window *win;
183 const struct window *main_menu_win;
185 /* The main menu can be either above or below the tabs. */
186 main_menu_win = term->main_menu ? term->main_menu->win : NULL;
188 foreach (win, term->windows) {
189 switch (want) {
190 case WANT_ANY:
191 if (win->type == WINDOW_TAB)
192 want = WANT_TAB;
193 break;
194 case WANT_TAB:
195 if (win == main_menu_win)
196 want = WANT_NONE;
197 else
198 assert(win->type == WINDOW_TAB);
199 break;
200 case WANT_NONE:
201 assert(0);
202 break;
206 #endif /* CONFIG_DEBUG */