1 /** Terminal windows stuff.
11 #include "terminal/event.h"
12 #include "terminal/tab.h"
13 #include "terminal/terminal.h"
14 #include "terminal/window.h"
15 #include "util/error.h"
16 #include "util/memory.h"
20 redraw_from_window(struct window
*win
)
22 struct terminal
*term
= win
->term
;
24 struct window
*end
= (struct window
*) &term
->windows
;
26 if (term
->redrawing
!= TREDRAW_READY
) return;
28 set_redraw_term_event(&ev
, term
->width
, term
->height
);
29 term
->redrawing
= TREDRAW_BUSY
;
30 for (win
= win
->prev
; win
!= end
; win
= win
->prev
) {
31 if (!inactive_tab(win
))
32 win
->handler(win
, &ev
);
34 term
->redrawing
= TREDRAW_READY
;
38 redraw_below_window(struct window
*win
)
40 struct terminal
*term
= win
->term
;
42 struct window
*end
= win
;
43 enum term_redrawing_state saved_redraw_state
= term
->redrawing
;
45 if (term
->redrawing
== TREDRAW_DELAYED
) return;
47 set_redraw_term_event(&ev
, term
->width
, term
->height
);
48 term
->redrawing
= TREDRAW_DELAYED
;
49 for (win
= term
->windows
.prev
; 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 */