|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * conio frontend for a text-based user interface. ! 5: * ! 6: * Copyright 1996 Tim Gunn, Gustavo Goedert ! 7: */ ! 8: ! 9: #include "sysconfig.h" ! 10: #include "sysdeps.h" ! 11: ! 12: #include <conio.h> ! 13: #include <ctype.h> ! 14: #include <crt0.h> ! 15: ! 16: #include "config.h" ! 17: #include "options.h" ! 18: #include "uae.h" ! 19: #include "tui.h" ! 20: ! 21: void save_state(void); ! 22: void drawbox(int,int,int,int); ! 23: int alphasort(const void *a, const void *b); ! 24: int scandir(const char *dir, struct dirent ***namelist); ! 25: ! 26: #define TB textbackground ! 27: #define TC textcolor ! 28: #define CURSON _setcursortype(_NORMALCURSOR); ! 29: #define CURSOFF _setcursortype(_NOCURSOR); ! 30: #define SCRON _wscroll = 1; ! 31: #define SCROFF _wscroll = 0; ! 32: ! 33: int SETTC=15; //standard text colour. ! 34: int SETTB=1; //standard background color. ! 35: int SETHL=14; //text hilight. ! 36: ! 37: typedef struct { ! 38: int left; ! 39: int top; ! 40: int right; ! 41: int bottom; ! 42: char *memory; ! 43: } WINDOW; ! 44: ! 45: static int currwin; ! 46: ! 47: static WINDOW winstack[10]; /* more than enough */ ! 48: static int winnr = 0; ! 49: ! 50: void save_state(void) { ! 51: int x1, y1, x2, y2; ! 52: ! 53: if (winstack[currwin].memory != NULL) ! 54: free(winstack[currwin].memory); ! 55: x1 = winstack[currwin].left; ! 56: y1 = winstack[currwin].top; ! 57: x2 = winstack[currwin].right; ! 58: y2 = winstack[currwin].bottom; ! 59: winstack[currwin].memory = malloc((x2-x1+1)*(y2-y1+1)*2); ! 60: gettext(x1, y1, x2, y2, winstack[currwin].memory); ! 61: } ! 62: ! 63: void tui_setup(void) ! 64: { ! 65: int i; ! 66: ! 67: /* enable case on LFN systems (eg. win95) */ ! 68: if (_USE_LFN) ! 69: _crt0_startup_flags = _CRT0_FLAG_PRESERVE_FILENAME_CASE; ! 70: _set_screen_lines(50); ! 71: SCROFF ! 72: CURSOFF ! 73: for (i = 0; i < 10; i++) ! 74: winstack[i].memory = NULL; ! 75: highvideo(); ! 76: TC(SETTC); TB(SETTB); clrscr(); ! 77: ! 78: winstack[0].left = 1; ! 79: winstack[0].top = 1; ! 80: winstack[0].right = tui_cols(); ! 81: winstack[0].bottom = tui_lines(); ! 82: winstack[0].memory = malloc(tui_cols()*tui_lines()*2); ! 83: gettext(1, 1, tui_cols(), tui_lines(), winstack[0].memory); ! 84: window(1, 1, tui_cols(), tui_lines()); ! 85: currwin = 0; ! 86: winnr = 1; ! 87: } ! 88: ! 89: int tui_lines(void) ! 90: { ! 91: return 50; ! 92: } ! 93: ! 94: int tui_cols(void) ! 95: { ! 96: return 80; ! 97: } ! 98: ! 99: void tui_shutdown(void) ! 100: { ! 101: int i; ! 102: ! 103: for (i = 0; i < 10; i++) { ! 104: if (winstack[i].memory != NULL) { ! 105: free(winstack[i].memory); ! 106: winstack[i].memory = NULL; ! 107: } ! 108: } ! 109: winnr = 0; ! 110: normvideo(); ! 111: SCRON ! 112: CURSON ! 113: window(1, 1, tui_cols(), tui_lines()); ! 114: TC(LIGHTGRAY); TB(BLACK); clrscr(); ! 115: _set_screen_lines(25); ! 116: } ! 117: ! 118: void tui_refresh(void) ! 119: { ! 120: int i, x1, y1, x2, y2; ! 121: ! 122: for (i=0; i<=currwin; i++) { ! 123: if (winstack[i].memory != NULL) { ! 124: x1 = winstack[i].left; ! 125: y1 = winstack[i].top; ! 126: x2 = winstack[i].right; ! 127: y2 = winstack[i].bottom; ! 128: puttext(x1, y1, x2, y2, winstack[i].memory); ! 129: } ! 130: } ! 131: } ! 132: ! 133: void tui_puts(const char *s) ! 134: { ! 135: cputs(s); ! 136: save_state(); ! 137: } ! 138: ! 139: void tui_cursoff(void) ! 140: { ! 141: } ! 142: ! 143: void tui_curson(void) ! 144: { ! 145: } ! 146: ! 147: void tui_putc(char c) ! 148: { ! 149: putch(c); ! 150: save_state(); ! 151: } ! 152: ! 153: void tui_cr(void) ! 154: { ! 155: tui_puts("\r\n"); ! 156: save_state(); ! 157: } ! 158: ! 159: char tui_getc(void) ! 160: { ! 161: return getch(); ! 162: // save_state(); ! 163: } ! 164: ! 165: void tui_gotoxy(int x, int y) ! 166: { ! 167: gotoxy(x, y); ! 168: // save_state(); ! 169: } ! 170: ! 171: void tui_selwin(int w) ! 172: { ! 173: window(winstack[w].left, winstack[w].top, winstack[w].right, winstack[w].bottom); ! 174: currwin = w; ! 175: tui_refresh(); ! 176: } ! 177: ! 178: void tui_clrwin(int w) ! 179: { ! 180: tui_selwin(w); ! 181: clrscr(); ! 182: save_state(); ! 183: } ! 184: ! 185: void drawbox(int x, int y, int x2, int y2) { ! 186: int i; ! 187: clrscr(); ! 188: gotoxy(x,y); cprintf("�"); ! 189: for(i=0;i<x2-x-1;i++){ cprintf("�"); } ! 190: cprintf("�"); ! 191: gotoxy(x,y2); cprintf("�"); ! 192: for(i=0;i<x2-x-1;i++){ cprintf("�"); } ! 193: cprintf("�"); ! 194: for(i=y+1;i<y2;i++) { ! 195: gotoxy(x,i); cprintf("�"); ! 196: gotoxy(x2,i); cprintf("�"); ! 197: } ! 198: } ! 199: ! 200: void tui_drawbox(int w) ! 201: { ! 202: tui_selwin(w); ! 203: drawbox(1, 1, winstack[w].right-winstack[w].left+1, winstack[w].bottom-winstack[w].top+1); ! 204: save_state(); ! 205: } ! 206: ! 207: void tui_hline(int x1, int y1, int x2) ! 208: { ! 209: int i; ! 210: gotoxy(x1,y1); ! 211: for (i=x1; i<=x2; i++) ! 212: putch('�'); ! 213: save_state(); ! 214: } ! 215: ! 216: int tui_dlog(int x1, int y1, int x2, int y2) ! 217: { ! 218: winstack[winnr].left = x1; ! 219: winstack[winnr].top = y1; ! 220: winstack[winnr].right = x2; ! 221: winstack[winnr].bottom = y2; ! 222: window(x1, y1, x2, y2); ! 223: currwin = winnr; ! 224: return winnr++; ! 225: } ! 226: ! 227: void tui_dlogdie(int w) ! 228: { ! 229: tui_selwin(w); ! 230: if (winstack[w].memory != NULL) { ! 231: free(winstack[w].memory); ! 232: winstack[w].memory = NULL; ! 233: } ! 234: winnr--; ! 235: currwin = w-1; ! 236: } ! 237: ! 238: int tui_gets(char *buf, int x, int y, int n) ! 239: { ! 240: int i = 0; ! 241: tui_gotoxy(x+1, y+1); ! 242: CURSON ! 243: for (;;) { ! 244: int c = getch(); ! 245: int j; ! 246: if (c == 13) { ! 247: { ! 248: char *tmp; ! 249: ! 250: while ((tmp = strchr(buf, '\\'))) ! 251: *tmp = '/'; ! 252: } ! 253: CURSOFF ! 254: return 1; ! 255: } else if (c == 27) { ! 256: CURSOFF ! 257: return 0; ! 258: } else if (c == 8) { ! 259: if (i>0) ! 260: i--; ! 261: } else if (i + 1 < n) ! 262: buf[i++] = c; ! 263: tui_gotoxy(x+1, y+1); ! 264: for (j = 0; j < i; j++) ! 265: tui_putc(buf[j]); ! 266: for (; j < n; j++) ! 267: tui_putc(' '); ! 268: tui_gotoxy(x+i+1, y+1); ! 269: buf[i] = 0; ! 270: } ! 271: } ! 272: ! 273: int tui_wgets(char *buf, const char *title, int n) ! 274: { ! 275: int result; ! 276: int l = strlen(title); ! 277: int ww = l > n ? l : n; ! 278: // int w = tui_dlog((tui_cols()-ww-2)/2, tui_lines()/2-1, (tui_cols()+ww+2)/2, tui_lines()/2+1); ! 279: int w = tui_dlog((tui_cols()-ww-2)/2+1, tui_lines()/2-1, (tui_cols()+ww+2)/2, tui_lines()/2+1); ! 280: tui_drawbox(w); ! 281: tui_gotoxy((ww-l)/2+2, 1); ! 282: tui_puts(title); ! 283: result = tui_gets(buf, 1, 1, n); ! 284: tui_dlogdie(w); ! 285: return result; ! 286: } ! 287: ! 288: ! 289: int tui_menubrowse(struct bstring *menu, int xoff, int yoff, int selected, int XXX) //FIXME!!! ! 290: { ! 291: int count = 0, maxsel = 0, maxw = 0; ! 292: int i, j, w; ! 293: ! 294: const char *mtitle = NULL; ! 295: ! 296: for (i = 0; menu[i].val != -3; i++) { ! 297: int tmp; ! 298: if (menu[i].val != 0) { ! 299: count++; ! 300: if (menu[i].val != -2) ! 301: maxsel++; ! 302: } else ! 303: mtitle = menu[i].data; ! 304: if ((tmp = strlen(menu[i].data)) > maxw) ! 305: maxw = tmp; ! 306: } ! 307: maxw += 3; ! 308: w = tui_dlog(xoff, yoff, xoff+maxw, yoff+count+1); ! 309: tui_selwin(w); ! 310: tui_drawbox(w); ! 311: if (mtitle != NULL) { ! 312: tui_gotoxy(2, 1); ! 313: tui_puts(mtitle); ! 314: } ! 315: ! 316: for (;;) { ! 317: int c; ! 318: int s2; ! 319: ! 320: for (i = j = s2 = 0; i < count; i++, j++) { ! 321: int k, x; ! 322: int a = s2 == selected ? 1 : 0; ! 323: ! 324: while (menu[j].val == 0) ! 325: j++; ! 326: tui_gotoxy(2, 2+i); ! 327: if (a) { ! 328: TC(SETTB); ! 329: TB(SETTC); ! 330: } ! 331: tui_putc(' '); ! 332: for (k = x = 0; menu[j].data[k]; k++, x++) { ! 333: int a2 = 0; ! 334: c = menu[j].data[k]; ! 335: if (c == '_') ! 336: c = menu[j].data[++k], a2 = 1; ! 337: tui_gotoxy(3+x, 2+i); ! 338: if (a2) ! 339: TC(SETHL); ! 340: tui_putc(c); ! 341: if (a2) { ! 342: if (a) ! 343: TC(SETTB); ! 344: else ! 345: TC(SETTC); ! 346: } ! 347: } ! 348: for (; x < maxw-2; x++) { ! 349: tui_gotoxy(3+x, 2+i); ! 350: tui_putc(' '); ! 351: } ! 352: if (a) { ! 353: TC(SETTC); ! 354: TB(SETTB); ! 355: } ! 356: if (menu[j].val != -1) ! 357: s2++; ! 358: } ! 359: ! 360: tui_refresh(); ! 361: c = getch(); ! 362: if (c == 27) { ! 363: tui_dlogdie(w); ! 364: return -1; ! 365: } else if (c == 13 || c == ' ') { ! 366: tui_dlogdie(w); ! 367: return selected; ! 368: } else if (c == 0) { ! 369: c = getch(); ! 370: switch (c) { ! 371: case 72: ! 372: if (selected > 0) ! 373: selected--; ! 374: break; ! 375: case 80: ! 376: if (selected + 1 < count) ! 377: selected++; ! 378: break; ! 379: case 73: ! 380: selected = 0; ! 381: break; ! 382: case 81: ! 383: selected = count - 1; ! 384: break; ! 385: default: ! 386: for (j = i = 0; menu[i].val != -3; i++) ! 387: if (menu[i].val == toupper(c)) { ! 388: tui_dlogdie(w); ! 389: return j; ! 390: } else if (menu[i].val == -1 || menu[i].val > 0) { ! 391: j++; ! 392: } ! 393: ! 394: break; ! 395: } ! 396: } else { ! 397: for (j = i = 0; menu[i].val != -3; i++) ! 398: if (menu[i].val == toupper(c)) { ! 399: tui_dlogdie(w); ! 400: return j; ! 401: } else if (menu[i].val == -1 || menu[i].val > 0) { ! 402: j++; ! 403: } ! 404: ! 405: } ! 406: } ! 407: return -1; /* Can't get here */ ! 408: } ! 409: ! 410: void tui_errorbox(const char *err) ! 411: { ! 412: const char *hak = "Hit any key"; ! 413: int n = strlen(hak); ! 414: int l = strlen(err); ! 415: int ww = (l > n ? l : n) + 2; ! 416: int w = tui_dlog((tui_cols()-ww)/2, tui_lines()/2-1, (tui_cols()+ww)/2, tui_lines()/2+1); ! 417: tui_selwin(w); tui_drawbox(w); ! 418: ! 419: tui_gotoxy((ww-6)/2+2, 1); ! 420: tui_puts("Error!"); ! 421: tui_gotoxy((ww-l)/2+2, 2); ! 422: tui_puts(err); ! 423: tui_gotoxy((ww-n)/2+2, 3); ! 424: tui_puts(hak); ! 425: ! 426: tui_refresh(); ! 427: for (;;) { ! 428: int c = getch(); ! 429: if (c == 13) ! 430: break; ! 431: } ! 432: tui_dlogdie(w); ! 433: } ! 434: ! 435: static char *pattern; ! 436: static int maxlen; ! 437: ! 438: static void put_filename(char *s, int x, int y, int HL) ! 439: { ! 440: char buf[256]; ! 441: int i; ! 442: ! 443: tui_gotoxy(x,y); ! 444: if (strcmp(s, ".") == 0) ! 445: strcpy(buf, "(none)"); ! 446: else ! 447: strcpy(buf, s); ! 448: buf[maxlen] = 0; ! 449: TC(SETHL); ! 450: if (HL) ! 451: TB(SETTC); ! 452: for (i = 0; i < (int) strlen(buf); i++) ! 453: tui_putc(buf[i]); ! 454: for (; i < maxlen; i++) ! 455: tui_putc(' '); ! 456: TC(SETTC); ! 457: if (HL) ! 458: TB(SETTB); ! 459: } ! 460: ! 461: static char fsbuf[256]; ! 462: ! 463: static int selectfn(const struct dirent *de) ! 464: { ! 465: int l1, l2; ! 466: ! 467: /* l1 = strlen(pattern + 1);*/ ! 468: l2 = strlen(de->d_name); ! 469: ! 470: if (l2 >= tui_cols()-10) /* Restrict length of filenames so we won't mess up the display */ ! 471: return 0; ! 472: ! 473: /* No pattern matching for now. But we don't show hidden files. */ ! 474: if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0 ! 475: && de->d_name[0] == '.') ! 476: return 0; ! 477: if (l2 > maxlen) ! 478: maxlen = l2; ! 479: return 1; ! 480: } ! 481: ! 482: char *tui_filereq(char *s, char *oldfile, const char *title) //FIXME!!! ! 483: { ! 484: char cwd[256]; ! 485: char *retval = fsbuf; ! 486: char *tmp; ! 487: int fin = 0; ! 488: // chtype moresave[6][2]; ! 489: ! 490: /* Save wd */ ! 491: if (getcwd(cwd, 256) == NULL) ! 492: return NULL; ! 493: ! 494: /* Change into directory of old file */ ! 495: strcpy(fsbuf, oldfile); ! 496: tmp = strrchr(fsbuf, '/'); ! 497: if (tmp != NULL) { ! 498: *tmp = 0; ! 499: if (strlen(fsbuf) > 0) ! 500: chdir(fsbuf); ! 501: } ! 502: ! 503: pattern = s; ! 504: if (s[0] != '*') ! 505: fprintf(stderr, "Can't handle wildcard %s\n", s); ! 506: if (s[1] != 0 && strchr(s+1, '*') != NULL) ! 507: fprintf(stderr, "Can't handle wildcard %s\n", s); ! 508: for (;!fin;) { ! 509: struct dirent **names; ! 510: int i, w, n, l, yp, oldyp, s; ! 511: ! 512: maxlen = 0; ! 513: n = scandir(".", &names); ! 514: ! 515: if (n <= 0) ! 516: return NULL; ! 517: if (title != NULL && strlen(title) + 6 > maxlen) ! 518: maxlen = strlen(title) + 6; ! 519: l = n; ! 520: if (l > 40) ! 521: l = 40; ! 522: yp = s = 0; oldyp = -1; ! 523: w = tui_dlog(tui_cols() - maxlen - 8, 5, tui_cols() - 5, 5 + l + 1); ! 524: tui_selwin(w); tui_drawbox(w); ! 525: /* if (title) ! 526: mvwaddstr(currwin, 0, 2, title); ! 527: for (i = 0; i < 6; i++) { ! 528: moresave[i][0] = mvwinch(currwin, 0, maxlen-3+i); ! 529: moresave[i][1] = mvwinch(currwin, l+1, maxlen-3+i); ! 530: }*/ ! 531: for (;;) { ! 532: int c; ! 533: char tmp[256]; ! 534: while (s < yp) ! 535: yp--; ! 536: while (s >= yp + l) ! 537: yp++; ! 538: if (oldyp != yp) { ! 539: oldyp = yp; ! 540: for (i = 0; i < l; i++) { ! 541: put_filename(names[i + yp]->d_name, 3, 2 + i, 0); ! 542: } ! 543: } ! 544: put_filename(names[s]->d_name, 3, 2 + s - yp, 1); ! 545: ! 546: /* if (yp == 0) ! 547: for (i = 0; i < 6; i++) ! 548: mvwaddch(currwin, 0, maxlen-3+i, moresave[i][0]); ! 549: else ! 550: mvwaddstr(currwin, 0, maxlen-3, "(more)"); ! 551: if (yp + l == n) ! 552: for (i = 0; i < 6; i++) ! 553: mvwaddch(currwin, l+1, maxlen-3+i, moresave[i][1]); ! 554: else ! 555: mvwaddstr(currwin, l+1, maxlen-3, "(more)"); ! 556: tui_refresh();*/ ! 557: c = getch(); ! 558: put_filename(names[s]->d_name, 3, 2 + s - yp, 0); ! 559: if (c == 27) { ! 560: retval = NULL; fin = 1; ! 561: break; ! 562: } else if (c == 13 || c == ' ') { ! 563: int err; ! 564: ! 565: if (strcmp(names[s]->d_name, ".") == 0) { ! 566: fin = 1; ! 567: strcpy(fsbuf, ""); ! 568: break; ! 569: } ! 570: err = chdir(names[s]->d_name); ! 571: ! 572: if (err == 0) ! 573: break; ! 574: else /*if (errno == ENOTDIR)*/ { ! 575: fin = 1; ! 576: if (getcwd(fsbuf, 256) == NULL) ! 577: retval = NULL; ! 578: if (strlen(fsbuf) + strlen(names[s]->d_name) + 2 >= 256) ! 579: retval = NULL; ! 580: else { ! 581: strcat(fsbuf, "/"); ! 582: strcat(fsbuf, names[s]->d_name); ! 583: } ! 584: break; ! 585: } /* else what? */ ! 586: } ! 587: if (c==0) { ! 588: c = getch(); ! 589: switch (c) { ! 590: case 72: ! 591: if (s > 0) ! 592: s--; ! 593: break; ! 594: case 80: ! 595: if (s + 1 < n) ! 596: s++; ! 597: break; ! 598: case 73: ! 599: if (s > l) ! 600: s -= l; ! 601: else ! 602: s = 0; ! 603: break; ! 604: case 81: ! 605: if (s + l < n) ! 606: s += l; ! 607: else ! 608: s = n - 1; ! 609: break; ! 610: } ! 611: } else { ! 612: for (i = 0; i < n; i++) ! 613: if (names[i]->d_name[0] == c) { ! 614: s = i; ! 615: break; ! 616: } ! 617: } ! 618: } ! 619: #if 0 ! 620: /* @@@ is this right? */ ! 621: for (i = 0; i < n; i++) ! 622: free(names[i]->d_name); ! 623: free(names); ! 624: #endif ! 625: tui_dlogdie(w); ! 626: } ! 627: chdir(cwd); ! 628: return retval; ! 629: } ! 630: ! 631: int tui_backup_optionsfile(void) ! 632: { ! 633: char tmp[257]; ! 634: char *ptr; ! 635: if (access(optionsfile, 00) == 0) ! 636: return 0; ! 637: strcpy(tmp, optionsfile); ! 638: ptr = strrchr(tmp, '.'); ! 639: if (ptr != NULL) ! 640: *ptr = 0; ! 641: strcat(tmp, ".bak"); ! 642: return rename(optionsfile, tmp); ! 643: } ! 644: ! 645: int alphasort(const void *a, const void *b) ! 646: { ! 647: return strcmp ((*((struct dirent **)a))->d_name, (*((struct dirent **)b))->d_name); ! 648: } ! 649: ! 650: int scandir(const char *dir, struct dirent ***namelist) ! 651: { ! 652: DIR *dp = opendir (dir); ! 653: struct dirent **v = NULL; ! 654: size_t vsize = 0, i; ! 655: struct dirent *d; ! 656: int save; ! 657: ! 658: if (dp == NULL) ! 659: return -1; ! 660: ! 661: save = errno; ! 662: errno = 0; ! 663: ! 664: i = 0; ! 665: while ((d = readdir (dp)) != NULL) ! 666: if (selectfn(d)) ! 667: { ! 668: if (i == vsize) ! 669: { ! 670: struct dirent **new; ! 671: if (vsize == 0) ! 672: vsize = 10; ! 673: else ! 674: vsize *= 2; ! 675: new = (struct dirent **) realloc (v, vsize * sizeof (*v)); ! 676: if (new == NULL) ! 677: { ! 678: lose: ! 679: (void) closedir (dp); ! 680: while (i > 0) ! 681: free (v[--i]); ! 682: free (v); ! 683: errno = ENOMEM; ! 684: return -1; ! 685: } ! 686: v = new; ! 687: } ! 688: ! 689: v[i] = (struct dirent *) malloc (sizeof (**v)); ! 690: if (v[i] == NULL) ! 691: goto lose; ! 692: ! 693: *v[i++] = *d; ! 694: } ! 695: ! 696: if (errno != 0) ! 697: { ! 698: save = errno; ! 699: ! 700: (void) closedir (dp); ! 701: ! 702: while (i > 0) free(v[--i]); ! 703: free(v); ! 704: ! 705: errno = save; ! 706: return -1; ! 707: } ! 708: ! 709: (void) closedir (dp); ! 710: errno = save; ! 711: ! 712: qsort (v, i, sizeof (*v), alphasort); ! 713: *namelist = v; ! 714: return i; ! 715: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.