1 /** Terminal windows stuff.
10 #include "bfu/dialog.h"
12 #include "terminal/event.h"
13 #include "terminal/tab.h"
14 #include "terminal/terminal.h"
15 #include "terminal/window.h"
16 #include "util/error.h"
17 #include "util/memory.h"
21 redraw_windows(enum windows_to_redraw which
, struct window
*win
)
23 struct terminal
*term
= win
->term
;
26 enum term_redrawing_state saved_redraw_state
= term
->redrawing
;
29 case REDRAW_IN_FRONT_OF_WINDOW
:
32 case REDRAW_WINDOW_AND_FRONT
:
33 end
= (struct window
*) &term
->windows
;
34 if (term
->redrawing
!= TREDRAW_READY
) return;
35 term
->redrawing
= TREDRAW_BUSY
;
37 case REDRAW_BEHIND_WINDOW
:
39 win
= (struct window
*) term
->windows
.prev
;
40 if (term
->redrawing
== TREDRAW_DELAYED
) return;
41 term
->redrawing
= TREDRAW_DELAYED
;
44 ERROR("invalid enum windows_to_redraw: which==%d", (int) which
);
48 set_redraw_term_event(&ev
, term
->width
, term
->height
);
49 for (; win
!= end
; win
= win
->prev
) {
50 if (!inactive_tab(win
))
51 win
->handler(win
, &ev
);
53 term
->redrawing
= saved_redraw_state
;
57 add_window(struct terminal
*term
, window_handler_T handler
, void *data
)
60 struct window
*win
= mem_calloc(1, sizeof(*win
));
67 win
->handler
= handler
;
68 win
->data
= data
; /* freed later in delete_window() */
70 win
->type
= WINDOW_NORMAL
;
71 add_at_pos((struct window
*) &term
->windows
, win
);
72 set_init_term_event(&ev
, term
->width
, term
->height
);
73 win
->handler(win
, &ev
);
77 delete_window(struct window
*win
)
81 /* Updating the status when destroying tabs needs this before the win
84 set_abort_term_event(&ev
);
85 win
->handler(win
, &ev
);
86 mem_free_if(win
->data
);
87 redraw_terminal(win
->term
);
92 delete_window_ev(struct window
*win
, struct term_event
*ev
)
96 w
= list_has_next(win
->term
->windows
, win
) ? win
->next
: NULL
;
100 if (!ev
|| !w
) return;
102 /* If next is a tab send it to the current tab */
103 if (w
->type
== WINDOW_TAB
) {
104 w
= get_current_tab(w
->term
);
107 if (w
) w
->handler(w
, ev
);
111 get_parent_ptr(struct window
*win
, int *x
, int *y
)
113 struct window
*parent
= win
->next
;
115 if (parent
->type
== WINDOW_TAB
)
116 parent
= get_tab_by_number(win
->term
, win
->term
->current_tab
);
131 unsigned int called_once
:1;
135 empty_window_handler(struct window
*win
, struct term_event
*ev
)
137 struct terminal
*term
= win
->term
;
138 struct ewd
*ewd
= win
->data
;
139 void (*fn
)(void *) = ewd
->fn
;
140 void *data
= ewd
->data
;
142 if (ewd
->called_once
) return;
148 get_parent_ptr(win
, &win
->x
, &win
->y
);
155 /* Silence compiler warnings */
159 ewd
->called_once
= 1;
162 term_send_event(term
, ev
);
166 add_empty_window(struct terminal
*term
, void (*fn
)(void *), void *data
)
168 struct ewd
*ewd
= mem_alloc(sizeof(*ewd
));
173 ewd
->called_once
= 0;
174 add_window(term
, empty_window_handler
, ewd
);
178 /** Check that terminal.windows are in the documented order. */
180 assert_window_stacking(struct terminal
*term
)
182 enum { WANT_ANY
, WANT_TAB
, WANT_NONE
} want
= WANT_ANY
;
183 const struct window
*win
;
184 const struct window
*main_menu_win
;
186 /* The main menu can be either above or below the tabs. */
187 main_menu_win
= term
->main_menu
? term
->main_menu
->win
: NULL
;
189 foreach (win
, term
->windows
) {
192 if (win
->type
== WINDOW_TAB
)
196 if (win
== main_menu_win
)
199 assert(win
->type
== WINDOW_TAB
);
207 #endif /* CONFIG_DEBUG */
210 set_dlg_window_ptr(struct dialog_data
*dlg_data
, struct window
*window
, int x
, int y
)
212 struct box
*box
= &dlg_data
->real_box
;
215 int y_max
= box
->y
+ box
->height
;
218 if (y
< box
->y
|| y
>= y_max
) return;
220 set_window_ptr(window
, x
, y
);
223 #if CONFIG_SCRIPTING_SPIDERMONKEY
224 /** Check whether keypress events would be directed to @a win. */
226 would_window_receive_keypresses(const struct window
*win
)
228 struct terminal
*const term
= win
->term
;
229 const struct window
*selected
;
231 /* At least @win must be in the list. */
232 assert(!list_empty(term
->windows
));
233 if_assert_failed
return 0;
235 selected
= term
->windows
.next
;
236 if (selected
->type
!= WINDOW_TAB
) return 0;
238 selected
= get_current_tab(term
);
239 if (selected
!= win
) return 0;
243 #endif /* CONFIG_SCRIPTING_SPIDERMONKEY */