--- uae/src/svgancui.c 2018/04/24 16:38:39 1.1 +++ uae/src/svgancui.c 2018/04/24 16:40:01 1.1.1.3 @@ -13,12 +13,22 @@ #include "sysconfig.h" #include "sysdeps.h" +#ifdef HAVE_NCURSES_H #include +#else +#include +#endif +#include #include "config.h" #include "options.h" +#include "uae.h" #include "tui.h" +#ifdef DONT_HAVE_ATTR_T +typedef int attr_t; +#endif + static WINDOW *currwin; static WINDOW *winstack[10]; /* more than enough */ @@ -27,7 +37,7 @@ static int winnr = 0; void tui_setup(void) { int i; - + for (i = 0; i < 10; i++) winstack[i] = NULL; /* From the ncurses manpage... */ @@ -39,7 +49,7 @@ void tui_setup(void) wattron(currwin, COLOR_PAIR(1) | A_BOLD); wbkgd(currwin, ' '|COLOR_PAIR(1)); } - + winstack[0] = stdscr; winnr = 1; } @@ -61,7 +71,12 @@ void tui_shutdown(void) void tui_refresh(void) { - wrefresh(currwin); + int w; + for (w = 0; w < winnr; w++) { + touchwin(winstack[w]); + wnoutrefresh(winstack[w]); + } + doupdate(); } void tui_puts(const char *s) @@ -105,7 +120,7 @@ void tui_selwin(int w) void tui_clrwin(int w) { - wclear(winstack[w]); + werase(winstack[w]); } void tui_drawbox(int w) @@ -134,7 +149,7 @@ void tui_dlogdie(int w) winstack[w] = NULL; while (winstack[winnr-1] == NULL) winnr--; - + for (w = 0; w < winnr; w++) redrawwin(winstack[w]), wrefresh(winstack[w]); } @@ -143,21 +158,28 @@ int tui_gets(char *buf, int x, int y, in { int i = 0; for (;;) { - int c = getch(); - int j; + int c, j; + + buf[i] = 0; wmove(currwin, y, x); for (j = 0; j < i; j++) waddch(currwin, buf[j]); for (; j < n; j++) waddch(currwin, ' '); + wmove(currwin, y, x + i); wrefresh(currwin); - buf[i] = 0; + + c = getch(); + + wmove(currwin, y, x + i); if (c == 13) return 1; else if (c == 27) return 0; - else if (i + 1 < n) + else if (i > 0 && c == KEY_BACKSPACE) + i--; + else if (i + 1 < n && !iscntrl(c)) buf[i++] = c; } } @@ -165,14 +187,186 @@ int tui_gets(char *buf, int x, int y, in int tui_wgets(char *buf, const char *title, int n) { int l = strlen(title); - int ww = l > n ? l : n; - int w = tui_dlog((tui_cols()-ww-2)/2, tui_lines()/2-1, (tui_cols()+ww+2)/2, tui_lines()/2+1); + int ww = (l > n ? l : n) + 2; + int w = tui_dlog((tui_cols()-ww)/2, tui_lines()/2-1, (tui_cols()+ww)/2, tui_lines()/2+1); + int result; + tui_selwin(w); tui_drawbox(w); wmove(currwin, 0, (ww-l)/2); waddstr(currwin, title); - return tui_gets(buf, 1, 1, n); + result = tui_gets(buf, 1, 1, n); + tui_dlogdie(w); + return result; +} + +int tui_menubrowse(struct bstring *menu, int xoff, int yoff, int selected, int height) +{ + int count = 0, maxsel = 0, maxw = 0; + int i, j, w, s, yp, oldyp; + chtype moresave[6][2]; + int xpos, ypos; + + const char *mtitle = NULL; + + for (i = 0; menu[i].val != -3; i++) { + int tmp; + if (menu[i].val == -4) { + if (maxsel < selected) + selected--; + continue; + } + if (menu[i].val != 0) { + count++; + if (menu[i].val != -2) + maxsel++; + } else + mtitle = menu[i].data; + if ((tmp = strlen(menu[i].data)) > maxw) + maxw = tmp; + } + if (height > count) + height = count; + maxw += 3; + if (strlen(mtitle ? mtitle : "") + 8 > maxw) + maxw = strlen(mtitle ? mtitle : "") + 8; + if (xoff > 0) + xpos = xoff; + else + xpos = tui_cols() + xoff - maxw - 1; + if (yoff > 0) + ypos = yoff; + else + ypos = tui_lines() + yoff - height - 2; + w = tui_dlog(xpos, ypos, xpos+maxw, ypos+height+1); + tui_selwin(w); + tui_drawbox(w); + if (mtitle != NULL) { + mvwaddstr(currwin, 0, 1, mtitle); + } + for (i = 0; i < 6; i++) { + moresave[i][0] = mvwinch(currwin, 0, maxw-6+i); + moresave[i][1] = mvwinch(currwin, height+1, maxw-6+i); + } + s = yp = 0; oldyp = -1; + for (;;) { + int c; + int s2; + + while (selected < yp) + yp--; + while (selected >= yp + height) + yp++; + if (yp == 0) + for (i = 0; i < 6; i++) + mvwaddch(currwin, 0, maxw-6+i, moresave[i][0]); + else + mvwaddstr(currwin, 0, maxw-6, "(more)"); + if (yp + height == count) + for (i = 0; i < 6; i++) + mvwaddch(currwin, height+1, maxw-6+i, moresave[i][1]); + else + mvwaddstr(currwin, height+1, maxw-6, "(more)"); + for (i = s2 = j = 0; i < count; i++, j++) { + int k, x; + attr_t a = s2 == selected ? A_STANDOUT : 0; + while (menu[j].val == 0 || menu[j].val == -4) + j++; + if (i >= yp && i < yp+height) { + mvwaddch(currwin, 1+i-yp, 1, ' ' | a); + for (k = x = 0; menu[j].data[k]; k++, x++) { + int a2 = 0; + c = menu[j].data[k]; + if (c == '_') + c = menu[j].data[++k], a2 = A_UNDERLINE; + mvwaddch(currwin, 1+i-yp, 2+x, c | a | a2); + } + for (; x < maxw-2; x++) { + mvwaddch(currwin, 1+i-yp, 2+x, ' ' | a); + } + } + if (menu[j].val != -2) + s2++; + } + + tui_refresh(); + c = getch(); + if (c == 27) { + tui_dlogdie(w); + return -1; + } else if (c == KEY_ENTER || c == 13 || c == ' ') { + tui_dlogdie(w); + for (i = s2 = j = 0; s2 <= selected; j++) { + if (menu[j].val == -4) { + i++; j++; continue; + } + while (menu[j].val == 0) + j++; + if (s2 == selected) + return i; + if (menu[j].val != -2) + s2++, i++; + } + abort(); + } else switch (c) { + case KEY_UP: + if (selected > 0) + selected--; + break; + case KEY_DOWN: + if (selected + 1 < count) + selected++; + break; + case KEY_PPAGE: + if (selected > height) + selected -= height; + else + selected = 0; + break; + case KEY_NPAGE: + if (selected + height < count) + selected += height; + else + selected = count-1; + break; + default: + for (j = i = 0; menu[i].val != -3; i++) + if (menu[i].val == toupper(c)) { + tui_dlogdie(w); + return j; + } else if (menu[i].val == -1 || menu[i].val == -4 || menu[i].val > 0) { + j++; + } + + break; + } + } + return -1; /* Can't get here */ } +void tui_errorbox(const char *err) +{ + const char *hak = "Hit any key"; + int n = strlen(hak); + int l = strlen(err); + int ww = (l > n ? l : n) + 2; + int w = tui_dlog((tui_cols()-ww)/2, tui_lines()/2-1, (tui_cols()+ww)/2, tui_lines()/2+1); + tui_selwin(w); tui_drawbox(w); + + wmove(currwin, 0, (ww-6)/2); + waddstr(currwin, "Error!"); + wmove(currwin, 1, (ww-l)/2); + waddstr(currwin, err); + wmove(currwin, 2, (ww-n)/2); + waddstr(currwin, hak); + + wrefresh(currwin); + for (;;) { + int c = getch(); + if (c == 13) + break; + } + tui_dlogdie(w); +} static char *pattern; static int maxlen; @@ -215,12 +409,19 @@ static int selectfn(const struct dirent return 1; } -char *tui_filereq(char *s, char *oldfile) +static int my_alphasort (const void *a, const void *b) +{ + return strcmp ((*(struct dirent **) a)->d_name, + (*(struct dirent **) b)->d_name); +} + +char *tui_filereq(char *s, char *oldfile, const char *title) { char cwd[256]; char *retval = fsbuf; char *tmp; int fin = 0; + chtype moresave[6][2]; /* Save wd */ if (getcwd(cwd, 256) == NULL) @@ -234,7 +435,7 @@ char *tui_filereq(char *s, char *oldfile if (strlen(fsbuf) > 0) chdir(fsbuf); } - + pattern = s; if (s[0] != '*') fprintf(stderr, "Can't handle wildcard %s\n", s); @@ -243,18 +444,26 @@ char *tui_filereq(char *s, char *oldfile for (;!fin;) { struct dirent **names; int i, w, n, l, yp, oldyp, s; - + maxlen = 0; - n = scandir(".", &names, selectfn, alphasort); - + n = scandir(".", &names, selectfn, my_alphasort); + if (n <= 0) return NULL; + if (title != NULL && strlen(title) + 6 > maxlen) + maxlen = strlen(title) + 6; l = n; if (l > 15) l = 15; yp = s = 0; oldyp = -1; - w = tui_dlog(5, 5, 5 + maxlen + 3, 5 + l + 1); + w = tui_dlog(tui_cols() - maxlen - 8, 5, tui_cols() - 5, 5 + l + 1); tui_selwin(w); tui_drawbox(w); + if (title) + mvwaddstr(currwin, 0, 2, title); + for (i = 0; i < 6; i++) { + moresave[i][0] = mvwinch(currwin, 0, maxlen-3+i); + moresave[i][1] = mvwinch(currwin, l+1, maxlen-3+i); + } for (;;) { int c; char tmp[256]; @@ -269,6 +478,18 @@ char *tui_filereq(char *s, char *oldfile } } put_filename(names[s]->d_name, 3, 2 + s - yp, A_STANDOUT); + + if (yp == 0) + for (i = 0; i < 6; i++) + mvwaddch(currwin, 0, maxlen-3+i, moresave[i][0]); + else + mvwaddstr(currwin, 0, maxlen-3, "(more)"); + if (yp + l == n) + for (i = 0; i < 6; i++) + mvwaddch(currwin, l+1, maxlen-3+i, moresave[i][1]); + else + mvwaddstr(currwin, l+1, maxlen-3, "(more)"); + tui_refresh(); c = getch(); put_filename(names[s]->d_name, 3, 2 + s - yp, 0); @@ -277,14 +498,14 @@ char *tui_filereq(char *s, char *oldfile break; } else if (c == KEY_ENTER || c == 13 || c == ' ') { int err; - + if (strcmp(names[s]->d_name, ".") == 0) { fin = 1; strcpy(fsbuf, ""); break; } err = chdir(names[s]->d_name); - + if (err == 0) break; else if (errno == ENOTDIR) { @@ -322,17 +543,24 @@ char *tui_filereq(char *s, char *oldfile s = n - 1; break; default: - for (i = 0; i < n; i++) - if (names[i]->d_name[0] == c) { - s = i; + i = 0; + if (names[s]->d_name[0] == c) + i = s+1; + for (; i < n*2; i++) { + int j = i; + if (i >= n) + j -= n; + if (names[j]->d_name[0] == c) { + s = j; break; } + } } } #if 0 /* @@@ is this right? */ for (i = 0; i < n; i++) - free(names[i]->d_name); + free(names[i]); free(names); #endif tui_dlogdie(w);