1 /*
2 Arcan Text-Oriented User Interface Library, Extensions
3 Copyright: 2018-2019, Bjorn Stahl
4 License: 3-clause BSD
5 Description: This widget adds support for transforming a tui context
6 into a line oriented window with scrollback.
7 */
8
9 #ifndef HAVE_TUI_LINEWND
10 #define HAVE_TUI_LINEWND
11
12
13 /*
14 * Description:
15 *
16 * Arguments:
17 * [ctx] (!null) references the context to control
18 *
19 * Returns:
20 * true if context was allocated and setup, false on allocation failure or
21 * argument errors.
22 *
23 * Handlers/Allocation:
24 * This dynamically allocates internally, and replaces the normal set of
25 * handlers. Use _linewnd_restore to return the context to the state it was
26 * in before this function was called.
27 *
28 * This hooks and forwards all the normal table handlers, it is only in the
29 * context of scrollback state where events gets masked and so on.
30 *
31 * Example:
32 * See the #ifdef EXAMPLE block at the bottom of tui_linewnd.c
33 */
34
35 struct tui_linewnd_line;
36 struct tui_linewnd_line {
37 size_t n_cells;
38 struct tui_cell* cells;
39 };
40
41 #ifndef ARCAN_TUI_DYNAMIC
42 bool arcan_tui_linewnd_setup(
43 struct tui_context*, struct tui_constraints* cons);
44
45 /*
46 * Layout / render function, this can be used on a non-linewnd context
47 * as well in order to get consistent wrapping modes, in other widgets.
48 *
49 * If [start_row] or [start_col] is out-of-bounds, 0 will be returned and
50 * no drawing will be performed.
51 *
52 * If [end_row, end_col] is out-of-bounds or less than [start_row, start_col]
53 * it will be set to the context dimensions.
54 *
55 * Returns the row-advance after processing the line buffer
56 * if > n_lines wrapping was applied on long lines.
57 * if < n_lines rendering was cancelled due to reaching the end of the screen.
58 */
59
60 enum linewnd_render_flags {
61 LINEWND_RENDER_NOTAB = 1,
62 LINEWND_RENDER_WRAP = 2
63 };
64
65 size_t arcan_tui_linewnd_render(struct tui_context*,
66 struct tui_linewnd_line*, size_t n_lines,
67 size_t start_row, size_t start_col,
68 size_t end_row, size_t end_col,
69 size_t* tabs, size_t n_tabs,
70 int flags
71 );
72
73 /*
74 * Replace the current history buffer with a new one
75 */
76 void arcan_tui_linewnd_set_buffer(
77 struct tui_context*, struct tui_linewnd_line*, size_t n_lines);
78
79 /*
80 * Retrieve a snapshot of the last n_lines of the history buffer,
81 * returns the actual number of lines in the buffer.
82 */
83 size_t arcan_tui_linewnd_get_buffer(
84 struct tui_context*, struct tui_linewnd_line*, size_t n_lines);
85
86 /*
87 * Commit the set line(s) to the currently active buffer,
88 * this will create an internal copy as part of the buffer management
89 */
90 void arcan_tui_linewnd_add_line(
91 struct tui_context*, const struct tui_linewnd_line*);
92
93 /*
94 * Return handler set to the state it was before the linewindow was
95 * setup.
96 */
97 void arcan_tui_linewnd_release(struct tui_context*);
98
99 /*
100 * The cases where we want to dynamically load the library as a plugin
101 */
102 #else
103 typedef size_t(* PTUILINEWND_RENDER)(
104 struct tui_context*, struct tui_linewnd_line*, size_t n_line,
105 size_t start_row, size_t start_col, size_t end_row, size_t end_col,
106 size_t* tabs, size_t n_tabs, int flags);
107 typedef bool(* PTUILINEWND_SETUP)(
108 struct tui_context*, struct tui_list_entry*, size_t n_entries);
109 typedef void(* PTUILINEWND_SETBUFFER)(
110 struct tui_context*, struct tui_linewnd_line*, size_t n_lines);
111 typedef void(* PTUILINEWND_RELEASE)(struct tui_context*);
112
113 static PTUILINEWND_RENDER arcan_tui_linewnd_render;
114 static PTUILINEWND_SETUP arcan_tui_linewnd_setup;
115 static PTUILINEWND_SETBUFFER arcan_tui_linewnd_set_buffer;
116 static PTUILINEWND_ADDLINE arcan_tui_linewnd_add_line;
117 static PTUILINEWND_RELEASE arcan_tui_linewnd_release;
118
arcan_tui_linewnd_dynload(void * (* lookup)(void *,const char *),void * tag)119 static bool arcan_tui_linewnd_dynload(
120 void*(*lookup)(void*, const char*), void* tag)
121 {
122 #define M(TYPE, SYM) if (! (SYM = (TYPE) lookup(tag, #SYM)) ) return false
123 M(PTUILINEWND_SETUP, arcan_tui_linewnd_setup);
124 M(PTUILINEWND_SETBUFFER, arcan_tui_linewnd_set_buffer);
125 M(PTUILINEWND_ADDLINE, arcan_tui_linewnd_add_line);
126 M(PTUILINEWND_RELEASE, arcan_tui_linewnd_release);
127 M(PTUILINEWND_RENDER, arcan_tui_linewnd_render);
128 #undef M
129 return true;
130 }
131 #endif
132 #endif
133