|
|
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.