|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * ncurses frontend for a text-based user interface.
5: *
6: * Copyright 1996 Bernd Schmidt
7: * If you find the routines in this file useful, you may use them in your
8: * programs without restrictions. Essentially, it's in the public domain.
9: *
10: */
11:
12:
13: #include "sysconfig.h"
14: #include "sysdeps.h"
15:
16: #include <ncurses.h>
17:
18: #include "config.h"
19: #include "options.h"
20: #include "tui.h"
21:
22: static WINDOW *currwin;
23:
24: static WINDOW *winstack[10]; /* more than enough */
25: static int winnr = 0;
26:
27: void tui_setup(void)
28: {
29: int i;
30:
31: for (i = 0; i < 10; i++)
32: winstack[i] = NULL;
33: /* From the ncurses manpage... */
34: initscr(); start_color(); cbreak(); noecho(); nonl(); intrflush(stdscr, FALSE); keypad(stdscr, TRUE);
35: currwin = stdscr;
36: if (has_colors()) {
37: init_pair(1, COLOR_WHITE, COLOR_BLUE);
38: init_pair(2, COLOR_BLACK, COLOR_WHITE);
39: wattron(currwin, COLOR_PAIR(1) | A_BOLD);
40: wbkgd(currwin, ' '|COLOR_PAIR(1));
41: }
42:
43: winstack[0] = stdscr;
44: winnr = 1;
45: }
46:
47: int tui_lines(void)
48: {
49: return LINES;
50: }
51:
52: int tui_cols(void)
53: {
54: return COLS;
55: }
56:
57: void tui_shutdown(void)
58: {
59: endwin();
60: }
61:
62: void tui_refresh(void)
63: {
64: wrefresh(currwin);
65: }
66:
67: void tui_puts(const char *s)
68: {
69: waddstr(currwin, s);
70: }
71:
72: void tui_cursoff(void)
73: {
74: }
75:
76: void tui_curson(void)
77: {
78: }
79:
80: void tui_putc(char c)
81: {
82: waddch(currwin, c);
83: }
84:
85: void tui_cr(void)
86: {
87: waddch(currwin, '\r');
88: }
89:
90: char tui_getc(void)
91: {
92: return getch();
93: }
94:
95: void tui_gotoxy(int x, int y)
96: {
97: x--; y--;
98: wmove(currwin, y, x);
99: }
100:
101: void tui_selwin(int w)
102: {
103: currwin = winstack[w];
104: }
105:
106: void tui_clrwin(int w)
107: {
108: wclear(winstack[w]);
109: }
110:
111: void tui_drawbox(int w)
112: {
113: wborder(winstack[w], 0, 0, 0, 0, 0, 0, 0, 0);
114: }
115:
116: void tui_hline(int x1, int y1, int x2)
117: {
118: wmove(currwin, y1-1, x1-1);
119: whline(currwin, 0, x2-x1+1);
120: }
121:
122: int tui_dlog(int x1, int y1, int x2, int y2)
123: {
124: x1--; y1--;
125: winstack[winnr] = newwin(y2 - y1, x2 - x1, y1, x1);
126: return winnr++;
127: }
128:
129: void tui_dlogdie(int w)
130: {
131: if (currwin == winstack[w])
132: currwin = stdscr;
133: delwin(winstack[w]);
134: winstack[w] = NULL;
135: while (winstack[winnr-1] == NULL)
136: winnr--;
137:
138: for (w = 0; w < winnr; w++)
139: redrawwin(winstack[w]), wrefresh(winstack[w]);
140: }
141:
142: int tui_gets(char *buf, int x, int y, int n)
143: {
144: int i = 0;
145: for (;;) {
146: int c = getch();
147: int j;
148: wmove(currwin, y, x);
149: for (j = 0; j < i; j++)
150: waddch(currwin, buf[j]);
151: for (; j < n; j++)
152: waddch(currwin, ' ');
153: wmove(currwin, y, x + i);
154: wrefresh(currwin);
155: buf[i] = 0;
156: if (c == 13)
157: return 1;
158: else if (c == 27)
159: return 0;
160: else if (i + 1 < n)
161: buf[i++] = c;
162: }
163: }
164:
165: int tui_wgets(char *buf, const char *title, int n)
166: {
167: int l = strlen(title);
168: int ww = l > n ? l : n;
169: int w = tui_dlog((tui_cols()-ww-2)/2, tui_lines()/2-1, (tui_cols()+ww+2)/2, tui_lines()/2+1);
170: tui_selwin(w); tui_drawbox(w);
171: wmove(currwin, 0, (ww-l)/2);
172: waddstr(currwin, title);
173: return tui_gets(buf, 1, 1, n);
174: }
175:
176:
177: static char *pattern;
178: static int maxlen;
179:
180: static void put_filename(char *s, int x, int y, attr_t a)
181: {
182: char buf[256];
183: int i;
184:
185: tui_gotoxy(x,y);
186: if (strcmp(s, ".") == 0)
187: strcpy(buf, "(none)");
188: else
189: strcpy(buf, s);
190: buf[maxlen] = 0;
191: for (i = 0; i < strlen(buf); i++)
192: waddch(currwin, buf[i] | a);
193: for (; i < maxlen; i++)
194: waddch(currwin, ' ' | a);
195: }
196:
197: static char fsbuf[256];
198:
199: static int selectfn(const struct dirent *de)
200: {
201: int l1, l2;
202:
203: /* l1 = strlen(pattern + 1);*/
204: l2 = strlen(de->d_name);
205:
206: if (l2 >= tui_cols()-10) /* Restrict length of filenames so we won't mess up the display */
207: return 0;
208:
209: /* No pattern matching for now. But we don't show hidden files. */
210: if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0
211: && de->d_name[0] == '.')
212: return 0;
213: if (l2 > maxlen)
214: maxlen = l2;
215: return 1;
216: }
217:
218: char *tui_filereq(char *s, char *oldfile)
219: {
220: char cwd[256];
221: char *retval = fsbuf;
222: char *tmp;
223: int fin = 0;
224:
225: /* Save wd */
226: if (getcwd(cwd, 256) == NULL)
227: return NULL;
228:
229: /* Change into directory of old file */
230: strcpy(fsbuf, oldfile);
231: tmp = strrchr(fsbuf, '/');
232: if (tmp != NULL) {
233: *tmp = 0;
234: if (strlen(fsbuf) > 0)
235: chdir(fsbuf);
236: }
237:
238: pattern = s;
239: if (s[0] != '*')
240: fprintf(stderr, "Can't handle wildcard %s\n", s);
241: if (s[1] != 0 && strchr(s+1, '*') != NULL)
242: fprintf(stderr, "Can't handle wildcard %s\n", s);
243: for (;!fin;) {
244: struct dirent **names;
245: int i, w, n, l, yp, oldyp, s;
246:
247: maxlen = 0;
248: n = scandir(".", &names, selectfn, alphasort);
249:
250: if (n <= 0)
251: return NULL;
252: l = n;
253: if (l > 15)
254: l = 15;
255: yp = s = 0; oldyp = -1;
256: w = tui_dlog(5, 5, 5 + maxlen + 3, 5 + l + 1);
257: tui_selwin(w); tui_drawbox(w);
258: for (;;) {
259: int c;
260: char tmp[256];
261: while (s < yp)
262: yp--;
263: while (s >= yp + l)
264: yp++;
265: if (oldyp != yp) {
266: oldyp = yp;
267: for (i = 0; i < l; i++) {
268: put_filename(names[i + yp]->d_name, 3, 2 + i, 0);
269: }
270: }
271: put_filename(names[s]->d_name, 3, 2 + s - yp, A_STANDOUT);
272: tui_refresh();
273: c = getch();
274: put_filename(names[s]->d_name, 3, 2 + s - yp, 0);
275: if (c == 27) {
276: retval = NULL; fin = 1;
277: break;
278: } else if (c == KEY_ENTER || c == 13 || c == ' ') {
279: int err;
280:
281: if (strcmp(names[s]->d_name, ".") == 0) {
282: fin = 1;
283: strcpy(fsbuf, "");
284: break;
285: }
286: err = chdir(names[s]->d_name);
287:
288: if (err == 0)
289: break;
290: else if (errno == ENOTDIR) {
291: fin = 1;
292: if (getcwd(fsbuf, 256) == NULL)
293: retval = NULL;
294: if (strlen(fsbuf) + strlen(names[s]->d_name) + 2 >= 256)
295: retval = NULL;
296: else {
297: strcat(fsbuf, "/");
298: strcat(fsbuf, names[s]->d_name);
299: }
300: break;
301: } /* else what? */
302: }
303: switch (c) {
304: case KEY_UP:
305: if (s > 0)
306: s--;
307: break;
308: case KEY_DOWN:
309: if (s + 1 < n)
310: s++;
311: break;
312: case KEY_PPAGE:
313: if (s > l)
314: s -= l;
315: else
316: s = 0;
317: break;
318: case KEY_NPAGE:
319: if (s + l < n)
320: s += l;
321: else
322: s = n - 1;
323: break;
324: default:
325: for (i = 0; i < n; i++)
326: if (names[i]->d_name[0] == c) {
327: s = i;
328: break;
329: }
330: }
331: }
332: #if 0
333: /* @@@ is this right? */
334: for (i = 0; i < n; i++)
335: free(names[i]->d_name);
336: free(names);
337: #endif
338: tui_dlogdie(w);
339: }
340: chdir(cwd);
341: return retval;
342: }
343:
344: int tui_backup_optionsfile(void)
345: {
346: char tmp[257];
347: strcpy(tmp, optionsfile);
348: strcat(tmp, "~");
349: return rename(optionsfile, tmp);
350: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.