1 /* src/client/windows.h
3 * A tiled window manager for the terminal.
5 * It provides a virtual screen that can be scrolled horizontally and may carry
6 * any number of windows to be appeared, disappeared, resized and moved around.
7 * They have borders and a title bar and are positioned automatically.
9 * Windows can be any width between 1 and 2^16 cells. The virtual screen grows
10 * with them as needed -- but only horizontally and only up to 2^16 cells. Their
11 * height is limited by the height of the terminal screen (maximum 2^16 cells).
13 * Windows' positioning can be influenced only indirectly: by resizing them, and
14 * by shifting their relative position inside the (currently invisible) chain
15 * that the window manager treats their plurality as. The first window goes into
16 * the top left corner of the virtual screen. Further windows are fitted as
17 * left-aligned as possible below their (chain-wise) closest predecessor that
18 * thrones over enough space to contain them and that is open to the right. If
19 * that fails, they're fitted up-right to the window with the rightmost border.
21 * TODO: Think up a more intuitive window positioning algorithm.
27 #include <ncurses.h> /* WINDOW, chtype */
28 #include <stdint.h> /* uint8_t, int16_t, uint16_t, uint32_t */
29 #include "../common/yx_uint16.h" /* yx_uint16 struct */
30 #include "keybindings.h" /* struct KeyBindingDB */
36 WINDOW * t_screen; /* ncurses' pointer to the terminal screen */
37 WINDOW * v_screen; /* virtual screen (ncurses pad) */
38 struct Win * wins; /* array of windows */
39 struct yx_uint16 v_screen_size; /* virtual screen size */
40 char * legal_ids; /* ids allowed to be used */
41 char * ids; /* all windows' ids, followed by \0 */
42 char * order; /* visible windows' id's order, followed by \0 */
43 uint16_t v_screen_offset; /* how many cells v_screen view moved rightwards*/
44 char active; /* id of window selected as active */
49 struct KeyBindingDB kb; /* window-specific keybindings */
50 char * title; /* title to be used in window title bar */
51 struct yx_uint16 target_center; /* saves .center when toggling .view */
52 struct yx_uint16 frame_size; /* size of window/frame to see winmap through*/
53 struct yx_uint16 start; /* upper left corner of window in v_screen */
54 struct yx_uint16 center; /* winnap cell to center frame on if < winmap */
55 struct yx_uint16 winmap_size; /* delimits .winmap, sorts it into lines */
56 chtype * winmap; /* window content in sequence of chtype's to write */
57 int16_t target_height; /* window size / .frame_size description in config */
58 int16_t target_width; /* file format, i.e. values <= 0 may be used */
59 char id; /* Win identifier; also maps to default window drawing function. */
60 uint8_t target_height_type; /* 0: read .height/.width as positive size; */
61 uint8_t target_width_type; /* 1: as negative diff to v_screen size */
62 uint8_t view; /* winde view mode: 0: use default draw function set by .id */
63 }; /* 1/2: use one of the two config view draw function */
67 /* Return yx offset to focus map of "mapsize" on "position" in "frame_size". */
68 extern uint16_t center_offset(uint16_t position,
69 uint32_t mapsize, uint32_t frame_size);
71 /* Get Win of "id". */
72 extern struct Win * get_win_by_id(char id);
74 /* Read/write individual Win (identified by "c") and world.winDB.order /
75 * world.winDB.active from/to "file" up to the world.delim delimiter. Use "line"
76 * and "linemax" as expected by try_fgets().
78 * Note that read_winconf_from_file() returns 1 on success and 0 if it detects
79 * having found the end of the valid interface configuration file by either
80 * hitting a EOF or a newline (so empty newlines at the end of the file are ok).
82 * Note that read_order_wins_visible_active() only reads the promised values
83 * into pointers for temporary storage. This is due to the order in which window
84 * data is initialized: winDB.order and winDB.active should only be set when all
85 * windows have been initialized, so cleaning up on error is not confused.
87 extern uint8_t read_winconf_from_file(char * line, uint32_t linemax,
89 extern void write_winconf_of_id_to_file(FILE * file, char c);
90 extern void read_order_wins_visible_active(char * line, uint32_t linemax,
91 FILE * file, char ** tmp_order,
93 extern void write_order_wins_visible_active(FILE * file);
95 /* Builds virtual sreen from .t_screen's size, fits win's sizes to them.*/
96 extern void make_v_screen_and_init_win_sizes();
98 /* Free all winDB data. */
99 extern void free_winDB();
101 /* The SIGWINCH handler winch_called() merely sets world.winch to 1. This info
102 * is used by io_loop() to call reset_windows_on_winch(), which adapts the
103 * currently loaded interface configuration to the new .t_screen size.
105 extern void winch_called();
106 extern void reset_windows_on_winch();
108 /* Draw .v_screen and its windows. Add scroll hints where edges of .t_screen hit
109 * .non-edges inside the virtual screen. Then update .t_screen.
111 extern void draw_all_wins();
113 /* Toggle display of a window of "id". */
114 extern void toggle_window(char id);
116 /* Toggle "window configuration" view for active window. Sets sensible .center
117 * values for each configuration view (for winconf_geometry: y=0, x=0; for
118 * winconf_keys: x=0 (y is set by draw_winconf_keybindings()); stores default
119 * view's .center in .target_center to return to it when toggling back.
121 extern void toggle_winconfig();
123 /* Toggle active window's .target_(height/width)_type ("axis" = "y": height;
124 * else: width). Don't toggle to .target_width_type of 1 (saving the width as a
125 * diff to the .t_screen's width) if window's width is larger than .t_screen's
126 * width, for such width is better saved directly with .target_width_type of 0.
128 extern void toggle_win_size_type(char axis);
130 /* Grow or shrink active window horizontally ("change" = "*"/"_") or vertically
131 * ("change" = "+"/"-") if the new size was at least 1x1, the height at least
132 * one cell smaller than .v_screen's vertical hight (to provide space for the
133 * title bar) and the width max. (2^16) - 1 cells. If a new window width would
134 * surpass that of .t_screen, set active window's .target_width_type to 0.
136 extern void resize_active_win(char c);
138 /* Move active window forwards ("dir" == "f") or backwards (any other "dir") in
139 * window chain. Wrap around in the window chain if start / end of it is met.
141 extern void shift_active_win(char dir);
143 /* Sroll .v_screen one cell to the left if "dir" is "-" and .v_screen_offset is
144 * more than 1, or to the right if "dir" is "+" and .v_screen's right edge would
145 * not move (further, if suspension of windows has moved it to the left already)
146 * leftwards to .t_screen's right edge.
148 extern void scroll_v_screen(char dir);
150 /* Cycle active window selection forwards ("dir" == "f") or backwards (any
151 * other "dir"). Wrap around in the windows chain if start / end of it is met.
153 extern void cycle_active_win(char dir);