]> git.ipfire.org Git - thirdparty/newt.git/blob - newt.c
1) took color changes from Kit
[thirdparty/newt.git] / newt.c
1 #include <slang/slang.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/time.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8
9 #include "newt.h"
10 #include "newt_pr.h"
11
12 /* this function will be in a future version of slang - I'll just prototype
13 it myself for now XXX */
14 void SLsmg_write_color_chars (unsigned short *s, unsigned int len);
15
16 struct Window {
17 int height, width, top, left;
18 short * buffer;
19 };
20
21 struct keymap {
22 char * str;
23 int code;
24 char * tc;
25 };
26
27 struct Window windowStack[20];
28 struct Window * currentWindow = NULL;
29
30 struct newtColors newtDefaultColorPalette = {
31 "white", "blue", /* root fg, bg */
32 "black", "lightgray", /* border fg, bg */
33 "black", "lightgray", /* window fg, bg */
34 "white", "black", /* shadow fg, bg */
35 "red", "lightgray", /* title fg, bg */
36 "lightgray", "red", /* button fg, bg */
37 "red", "lightgray", /* active button fg, bg */
38 "yellow", "blue", /* checkbox fg, bg */
39 "blue", "yellow", /* active checkbox fg, bg */
40 "yellow", "blue", /* entry box fg, bg */
41 "blue", "lightgray", /* label fg, bg */
42 "black", "lightgray", /* listbox fg, bg */
43 "yellow", "blue", /* active listbox fg, bg */
44 "black", "lightgray", /* textbox fg, bg */
45 "lightgray", "black", /* active textbox fg, bg */
46 };
47
48 static struct keymap keymap[] = {
49 { "\033OA", NEWT_KEY_UP, "kh" },
50 { "\033[A", NEWT_KEY_UP, "ku" },
51 { "\033OB", NEWT_KEY_DOWN, "kd" },
52 { "\033[B", NEWT_KEY_DOWN, "kd" },
53 { "\033[C", NEWT_KEY_RIGHT, "kr" },
54 { "\033OC", NEWT_KEY_RIGHT, "kr" },
55 { "\033[D", NEWT_KEY_LEFT, "kl" },
56 { "\033OD", NEWT_KEY_LEFT, "kl" },
57 { "\033[H", NEWT_KEY_HOME, "kh" },
58 { "\033[1~", NEWT_KEY_HOME, "kh" },
59 { "\033Ow", NEWT_KEY_END, "kH" },
60 { "\033[4~", NEWT_KEY_END, "kH" },
61
62 { "\033[3~", NEWT_KEY_DELETE, "kl" },
63
64 { "\033\t", NEWT_KEY_UNTAB, NULL },
65
66 { "\033[5~", NEWT_KEY_PGUP, NULL },
67 { "\033[6~", NEWT_KEY_PGDN, NULL },
68
69 { NULL, 0, NULL }, /* LEAVE this one */
70 };
71 static char keyPrefix = '\033';
72
73 static char * version = "Newt windowing library version " VERSION
74 " - (C) 1996 Red Hat Software. "
75 "Redistributable under the term of the Library "
76 "GNU Public Library. "
77 "written by Erik Troan\n";
78
79 void newtRefresh(void) {
80 SLsmg_refresh();
81 }
82
83 void newtCls(void) {
84 SLsmg_set_color(COLORSET_ROOT);
85 SLsmg_gotorc(0, 0);
86 SLsmg_erase_eos();
87
88 newtRefresh();
89 }
90
91 int newtInit(void) {
92 /* use the version variable just to be sure it gets included */
93 strlen(version);
94
95 SLtt_get_terminfo();
96
97 SLtt_Use_Ansi_Colors = 1;
98
99 SLsmg_init_smg();
100 SLang_init_tty(0, 0, 0);
101
102 newtSetColors(newtDefaultColorPalette);
103 /*initKeymap();*/
104
105 /*SLtt_set_cursor_visibility(0);*/
106
107 return 0;
108 }
109
110 int newtFinished(void) {
111 SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
112 SLsmg_refresh();
113 SLsmg_reset_smg();
114 SLang_reset_tty();
115
116 return 0;
117 }
118
119 void newtSetColors(struct newtColors colors) {
120 SLtt_set_color(COLORSET_ROOT, "", colors.rootFg, colors.rootBg);
121 SLtt_set_color(COLORSET_BORDER, "", colors.borderFg, colors.borderBg);
122 SLtt_set_color(COLORSET_WINDOW, "", colors.windowFg, colors.windowBg);
123 SLtt_set_color(COLORSET_SHADOW, "", colors.shadowFg, colors.shadowBg);
124 SLtt_set_color(COLORSET_TITLE, "", colors.titleFg, colors.titleBg);
125 SLtt_set_color(COLORSET_BUTTON, "", colors.buttonFg, colors.buttonBg);
126 SLtt_set_color(COLORSET_ACTBUTTON, "", colors.actButtonFg,
127 colors.actButtonBg);
128 SLtt_set_color(COLORSET_CHECKBOX, "", colors.checkboxFg, colors.checkboxBg);
129 SLtt_set_color(COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg,
130 colors.actCheckboxBg);
131 SLtt_set_color(COLORSET_ENTRY, "", colors.entryFg, colors.entryBg);
132 SLtt_set_color(COLORSET_LABEL, "", colors.labelFg, colors.labelBg);
133 SLtt_set_color(COLORSET_LISTBOX, "", colors.listboxFg, colors.listboxBg);
134 SLtt_set_color(COLORSET_ACTLISTBOX, "", colors.actListboxFg,
135 colors.actListboxBg);
136 SLtt_set_color(COLORSET_TEXTBOX, "", colors.textboxFg, colors.textboxBg);
137 SLtt_set_color(COLORSET_ACTTEXTBOX, "", colors.actTextboxFg,
138 colors.actTextboxBg);
139 }
140
141 int newtGetKey(void) {
142 int key;
143 char buf[10], * chptr = buf;
144 struct keymap * curr;
145
146 key = SLang_getkey();
147
148 switch (key) {
149 case 0x7f:
150 return NEWT_KEY_BKSPC;
151
152 case 0x08:
153 return NEWT_KEY_BKSPC;
154
155 default:
156 if (key != keyPrefix) return key;
157 }
158
159 memset(buf, 0, sizeof(buf));
160
161 *chptr++ = key;
162 while (SLang_input_pending(5)) {
163 key = SLang_getkey();
164 *chptr++ = key;
165
166 /* this search should use bsearch(), but when we only look through
167 a list of 20 (or so) keymappings, it's probably faster just to
168 do a inline linear search */
169
170 for (curr = keymap; curr->code; curr++) {
171 if (curr->str) {
172 if (!strcmp(curr->str, buf))
173 return curr->code;
174 }
175 }
176 }
177
178 for (curr = keymap; curr->code; curr++) {
179 if (curr->str) {
180 if (!strcmp(curr->str, buf))
181 return curr->code;
182 }
183 }
184
185 /* Looks like we were a bit overzealous in reading characters. Return
186 just the first character, and put everything else back in the buffer
187 for later */
188
189 chptr--;
190 while (chptr > buf)
191 SLang_ungetkey(*chptr--);
192
193 return *chptr;
194 }
195
196 void newtWaitForKey(void) {
197 newtRefresh();
198
199 SLang_getkey();
200 newtClearKeyBuffer();
201 }
202
203 void newtClearKeyBuffer(void) {
204 while (SLang_input_pending(1)) {
205 SLang_getkey();
206 }
207 }
208
209 int newtOpenWindow(int left, int top, int width, int height,
210 char * title) {
211 int i, j, row, col;
212 int n = 0;
213
214 if (!currentWindow) {
215 currentWindow = windowStack;
216 } else {
217 currentWindow++;
218 }
219
220 currentWindow->left = left;
221 currentWindow->top = top;
222 currentWindow->width = width;
223 currentWindow->height = height;
224
225 currentWindow->buffer = malloc(sizeof(short) * (width + 3) * (height + 3));
226
227 row = top - 1;
228 for (j = 0; j < height + 3; j++, row++) {
229 col = left - 1;
230 for (i = 0; i < width + 3; i++, col++) {
231 SLsmg_gotorc(row, col);
232 currentWindow->buffer[n++] = SLsmg_char_at();
233 }
234 }
235
236 SLsmg_set_color(COLORSET_BORDER);
237 SLsmg_draw_box(top - 1, left - 1, height + 2, width + 2);
238
239 if (title) {
240 i = strlen(title) + 4;
241 i = ((width - i) / 2) + left;
242 SLsmg_gotorc(top - 1, i);
243 SLsmg_set_char_set(1);
244 SLsmg_write_char(SLSMG_RTEE_CHAR);
245 SLsmg_set_char_set(0);
246 SLsmg_write_char(' ');
247 SLsmg_set_color(COLORSET_TITLE);
248 SLsmg_write_string(title);
249 SLsmg_set_color(COLORSET_BORDER);
250 SLsmg_write_char(' ');
251 SLsmg_set_char_set(1);
252 SLsmg_write_char(SLSMG_LTEE_CHAR);
253 SLsmg_set_char_set(0);
254 }
255
256 SLsmg_set_color(COLORSET_WINDOW);
257 SLsmg_fill_region(top, left, height, width, ' ');
258
259 SLsmg_set_color(COLORSET_SHADOW);
260 SLsmg_fill_region(top + height + 1, left, 1, width + 2, ' ');
261 SLsmg_fill_region(top, left + width + 1, height + 1, 1, ' ');
262
263 for (i = top; i < (top + height + 1); i++) {
264 SLsmg_gotorc(i, left + width + 1);
265 SLsmg_write_string(" ");
266 }
267
268 return 0;
269 }
270
271 void newtPopWindow(void) {
272 int j, row, col;
273 int n = 0;
274
275 row = col = 0;
276
277 row = currentWindow->top - 1;
278 col = currentWindow->left - 1;
279 for (j = 0; j < currentWindow->height + 3; j++, row++) {
280 SLsmg_gotorc(row, col);
281 SLsmg_write_color_chars(currentWindow->buffer + n,
282 currentWindow->width + 3);
283 n += currentWindow->width + 3;
284 }
285
286 free(currentWindow->buffer);
287
288 if (currentWindow == windowStack)
289 currentWindow = NULL;
290 else
291 currentWindow--;
292
293 SLsmg_set_char_set(0);
294
295 newtRefresh();
296 }
297
298 void newtGotorc(int row, int col) {
299 if (!currentWindow)
300 SLsmg_gotorc(row, col);
301 else
302 SLsmg_gotorc(row + currentWindow->top, col + currentWindow->left);
303 }
304
305 void newtDrawBox(int left, int top, int width, int height, int shadow) {
306 if (currentWindow) {
307 top += currentWindow->top;
308 left += currentWindow->left;
309 }
310
311 SLsmg_draw_box(top, left, height, width);
312
313 if (shadow) {
314 SLsmg_set_color(COLORSET_SHADOW);
315 SLsmg_fill_region(top + height, left + 1, 1, width - 1, ' ');
316 SLsmg_fill_region(top + 1, left + width, height, 1, ' ');
317 }
318 }
319
320 void newtClearBox(int left, int top, int width, int height) {
321 if (currentWindow) {
322 top += currentWindow->top;
323 left += currentWindow->left;
324 }
325
326 SLsmg_fill_region(top, left, height, width, ' ');
327 }
328
329 #if 0
330 /* This doesn't seem to work quite right. I don't know why not, but when
331 I rsh from an rxvt into a box and run this code, the machine returns
332 console key's (\033[B) rather then xterm ones (\033OB). */
333 static void initKeymap(void) {
334 struct keymap * curr;
335
336 for (curr = keymap; curr->code; curr++) {
337 if (!curr->str)
338 curr->str = SLtt_tgetstr(curr->tc);
339 }
340
341 /* Newt's keymap handling is a bit broken. It assumes that any extended
342 keystrokes begin with ESC. If you're using a homebrek terminal you
343 will probably need to fix this, or just yell at me and I'll be so
344 ashamed of myself for doing it this way I'll fix it */
345
346 keyPrefix = 0x1b; /* ESC */
347 }
348 #endif
349
350 void newtDelay(int usecs) {
351 fd_set set;
352 struct timeval tv;
353
354 FD_ZERO(&set);
355
356 tv.tv_sec = usecs / 1000000;
357 tv.tv_usec = usecs % 1000000;
358
359 select(0, &set, &set, &set, &tv);
360 }
361
362 struct eventResult newtDefaultEventHandler(struct newtComponent * c,
363 struct event ev) {
364 struct eventResult er;
365
366 er.result = ER_IGNORED;
367 return er;
368 }