blob: d40bf014202f472203d27528ad05d486a341f6c1 [file] [log] [blame]
Steve Kondikae271bc2015-11-15 02:50:53 +01001/****************************************************************************
2 * Copyright (c) 2008-2012,2014 Free Software Foundation, Inc. *
3 * *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
11 * *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
14 * *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
22 * *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
26 * authorization. *
27 ****************************************************************************/
28/*
29 * $Id: clip_printw.c,v 1.10 2014/08/02 23:13:29 tom Exp $
30 *
31 * demonstrate how to use printw without wrapping.
32 */
33
34#include <test.priv.h>
35
36#ifdef HAVE_VW_PRINTW
37
38#define SHOW(n) ((n) == ERR ? "ERR" : "OK")
39#define COLOR_DEFAULT (-1)
40
41typedef struct {
42 unsigned c;
43 unsigned v;
44 int status;
45 int pair;
46 attr_t attr;
47 int count;
48 int ch;
49 const char *c_msg;
50 const char *v_msg;
51 int y_val;
52 int x_val;
53 int y_beg, x_beg;
54 int y_max, x_max;
55} STATUS;
56
57static int
58clip_wprintw(WINDOW *win, NCURSES_CONST char *fmt,...)
59{
60 int y0, x0, y1, x1, width;
61 WINDOW *sub;
62 va_list ap;
63 int rc;
64
65 /*
66 * Allocate a single-line derived window extending from the current
67 * cursor position to the end of the current line in the given window.
68 * Disable scrolling in the derived window.
69 */
70 getyx(win, y0, x0);
71 width = getmaxx(win) - x0;
72 sub = derwin(win, 1, width, y0, x0);
73 scrollok(sub, FALSE);
74
75 /*
76 * Print the text.
77 */
78 va_start(ap, fmt);
79 rc = vw_printw(sub, fmt, ap);
80 va_end(ap);
81
82 getyx(sub, y1, x1);
83 delwin(sub);
84
85 wmove(win, y1 + y0, x1 + x0);
86
87 return rc;
88}
89
90static const char *
91color_params(unsigned state, int *pair)
92{
93 /* *INDENT-OFF* */
94 static struct {
95 int pair;
96 int fg, bg;
97 const char *msg;
98 } table[] = {
99 { 0, COLOR_DEFAULT, COLOR_DEFAULT, "default" },
100 { 1, COLOR_RED, COLOR_BLACK, "red/black" },
101 { 2, COLOR_WHITE, COLOR_BLUE, "white/blue" },
102 };
103 /* *INDENT-ON* */
104
105 static bool first = TRUE;
106 const char *result = 0;
107
108 if (has_colors()) {
109 if (first) {
110 unsigned n;
111
112 start_color();
113 for (n = 0; n < SIZEOF(table); ++n) {
114 init_pair((short) table[n].pair,
115 (short) table[n].fg,
116 (short) table[n].bg);
117 }
118 }
119 if (state < SIZEOF(table)) {
120 *pair = table[state].pair;
121 result = table[state].msg;
122 }
123 }
124 return result;
125}
126
127static const char *
128video_params(unsigned state, attr_t *attr)
129{
130 /* *INDENT-OFF* */
131 static struct {
132 attr_t attr;
133 const char *msg;
134 } table[] = {
135 { A_NORMAL, "normal" },
136 { A_BOLD, "bold" },
137 { A_REVERSE, "reverse" },
138 { A_UNDERLINE, "underline" },
139 { A_BLINK, "blink" },
140 };
141 /* *INDENT-ON* */
142
143 const char *result = 0;
144
145 if (state < SIZEOF(table)) {
146 *attr = table[state].attr;
147 result = table[state].msg;
148 }
149 return result;
150}
151
152/* fill the window with a test-pattern */
153static void
154fill_window(WINDOW *win)
155{
156 int y, x;
157 int y0 = -1, x0 = -1;
158
159 getyx(win, y, x);
160 wmove(win, 0, 0);
161 while (waddstr(win, "0123456789 abcdefghijklmnopqrstuvwxyz ") != ERR) {
162 int y1, x1;
163 getyx(win, y1, x1);
164 if (y1 == y0 && x1 == x0)
165 break;
166 x0 = x1;
167 y0 = y1;
168 }
169 wmove(win, y, x);
170}
171
172static void
173show_status(WINDOW *win, STATUS * sp)
174{
175 int y, x;
176
177 getyx(win, y, x);
178 wmove(win, 0, 0);
179 wprintw(win, "Count %d", sp->count);
180 if (sp->v_msg != 0)
181 wprintw(win, " Video %s", sp->v_msg);
182 if (sp->c_msg != 0)
183 wprintw(win, " Color %s", sp->c_msg);
184 wprintw(win, " (%d)", sp->status);
185 wclrtoeol(win);
186 wmove(win, y, x);
187}
188
189static void
190do_subwindow(WINDOW *win, STATUS * sp, void func(WINDOW *))
191{
192 WINDOW *win1 = newwin(sp->y_max - 2, sp->x_max - 2,
193 sp->y_beg + 1, sp->x_beg + 1);
194
195 if (win1 != 0 && sp->y_max > 4 && sp->x_max > 4) {
196 WINDOW *win2 = derwin(win1, sp->y_max - 4, sp->x_max - 4, 1, 1);
197
198 if (win2 != 0) {
199 box(win1, 0, 0);
200 wrefresh(win1);
201 func(win2);
202
203 delwin(win2);
204 } else {
205 beep();
206 }
207 delwin(win1);
208 touchwin(win);
209 } else {
210 if (win1)
211 delwin(win1);
212 beep();
213 }
214}
215
216static void
217init_status(WINDOW *win, STATUS * sp)
218{
219 memset(sp, 0, sizeof(*sp));
220 sp->c = 99;
221 sp->v = 99;
222 sp->ch = ' ';
223
224 keypad(win, TRUE);
225 fill_window(win);
226
227 getbegyx(win, sp->y_beg, sp->x_beg);
228 getmaxyx(win, sp->y_max, sp->x_max);
229}
230
231static void
232show_help(WINDOW *win)
233{
234 static const char *table[] =
235 {
236 "Basic commands:"
237 ,"Use h/j/k/l or arrow keys to move the cursor."
238 ,"Set the count parameter for clip_wprintw by entering digits 0-9."
239 ,""
240 ,"Other commands:"
241 ,"space toggles through the set of video attributes and colors."
242 ,"t touches (forces repaint) of the current line."
243 ,". calls clip_wprintw at the current position with the given count."
244 ,"= resets count to zero."
245 ,"? shows this help-window"
246 ,""
247 };
248
249 int y_max, x_max;
250 int row;
251
252 getmaxyx(win, y_max, x_max);
253 for (row = 0; row < (int) SIZEOF(table) && row < y_max; ++row) {
254 MvWPrintw(win, row, 0, "%.*s", x_max, table[row]);
255 }
256 while (wgetch(win) != 'q')
257 beep();
258}
259
260static void
261update_status(WINDOW *win, STATUS * sp)
262{
263 switch (sp->ch) {
264 case ' ': /* next test-iteration */
265 if (has_colors()) {
266 if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) {
267 sp->c_msg = color_params(sp->c = 0, &(sp->pair));
268 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
269 sp->v_msg = video_params(sp->v = 0, &(sp->attr));
270 }
271 }
272 } else {
273 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
274 sp->v_msg = video_params(sp->v = 0, &(sp->attr));
275 }
276 }
277 sp->count = 0;
278 show_status(win, sp);
279 break;
280 case KEY_LEFT:
281 case 'h':
282 if (sp->x_val > 0)
283 wmove(win, sp->y_val, --(sp->x_val));
284 break;
285 case KEY_DOWN:
286 case 'j':
287 if (sp->y_val < sp->y_max)
288 wmove(win, ++(sp->y_val), sp->x_val);
289 break;
290 case KEY_UP:
291 case 'k':
292 if (sp->y_val > 0)
293 wmove(win, --(sp->y_val), sp->x_val);
294 break;
295 case KEY_RIGHT:
296 case 'l':
297 if (sp->x_val < sp->x_max)
298 wmove(win, sp->y_val, ++(sp->x_val));
299 break;
300 case 't':
301 touchline(win, sp->y_val, 1);
302 break;
303 case '=':
304 sp->count = 0;
305 show_status(win, sp);
306 break;
307 case '?':
308 do_subwindow(win, sp, show_help);
309 break;
310 default:
311 if (isdigit(sp->ch)) {
312 sp->count = (sp->count * 10) + (sp->ch - '0');
313 show_status(win, sp);
314 } else {
315 beep();
316 }
317 break;
318 }
319}
320
321static void
322test_clipping(WINDOW *win)
323{
324 STATUS st;
325 char fmt[80];
326 char *buffer;
327 unsigned j, need;
328
329 init_status(win, &st);
330
331 do {
332 switch (st.ch) {
333 case '.': /* change from current position */
334 (void) wattrset(win, AttrArg(COLOR_PAIR(st.pair), st.attr));
335 if (st.count > 0) {
336 need = (unsigned) st.count + 1;
337 sprintf(fmt, "%%c%%%ds%%c", st.count);
338 } else {
339 need = (unsigned) getmaxx(win) - 1;
340 strcpy(fmt, "%c%s%c");
341 }
342 if ((buffer = typeMalloc(char, need + 1)) != 0) {
343 for (j = 0; j < need; ++j) {
344 buffer[j] = (char) ('A' + (j % 26));
345 }
346 buffer[need - 1] = '\0';
347 st.status = clip_wprintw(win, fmt, '[', buffer, ']');
348 free(buffer);
349 }
350 break;
351 case 'w':
352 do_subwindow(win, &st, test_clipping);
353 break;
354 case 'q':
355 return;
356 default:
357 update_status(win, &st);
358 break;
359 }
360 } while ((st.ch = wgetch(win)) != ERR);
361}
362
363int
364main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
365{
366 initscr();
367 cbreak();
368 noecho();
369
370 test_clipping(stdscr);
371 endwin();
372
373 ExitProgram(EXIT_SUCCESS);
374}
375
376#else
377int
378main(void)
379{
380 printf("This program requires the curses vw_printw function\n");
381 ExitProgram(EXIT_FAILURE);
382}
383#endif