char curses_query_key(const char *query, int *count) { int width, height, key; WINDOW *win; int cnt = 0; nh_bool hascount = FALSE; height = 3; width = strlen(query) + 4; win = newdialog(height, width); mvwprintw(win, 1, 2, query); wrefresh(win); key = nh_wgetch(win); while ((isdigit(key) || key == KEY_BACKSPACE) && count != NULL) { cnt = 10*cnt + (key - '0'); key = nh_wgetch(win); hascount = TRUE; } if (count != NULL) { if (!hascount && !cnt) cnt = -1; /* signal to caller that no count was given */ *count = cnt; } delwin(win); redraw_game_windows(); return key; }
static int curses_inline_query(const char *msg, int (*validator)(int, void*), void *arg, nh_bool cursor_visible, enum keyreq_context context) { if (!game_is_running) { curses_impossible("Trying to create inline query outside game."); return curses_msgwin_generic(msg, validator, arg, cursor_visible, context); } else if (!msgwin) { curses_impossible("Trying to create inline query without msgwin."); return curses_msgwin_generic(msg, validator, arg, cursor_visible, context); } /* We use a temporary message as the game will send a summary of the decision along later. */ curses_temp_message(msg); draw_msgwin(); /* We do not respect cursor_visible here, since we want the cursor focused on the prompt. We need to leave a space after it, though. */ int y, x; getyx(msgwin, y, x); if (x < COLNO - 1) wmove(msgwin, y, x + 1); int rv = -1; while (rv == -1) rv = validator(nh_wgetch(msgwin, context), arg); curses_clear_temp_messages(); draw_msgwin(); return rv; }
int get_map_key(int place_cursor) { int key = ERR; if (settings.blink) wtimeout(mapwin, 666); /* wait 2/3 of a second before switching */ if (player.x && place_cursor) { /* x == 0 is not a valid coordinate */ wmove(mapwin, player.y, player.x - 1); curs_set(1); } while (1) { key = nh_wgetch(mapwin); draw_map(player.x, player.y); doupdate(); if (key != ERR) break; }; wtimeout(mapwin, -1); return key; }
static void more(void) { int key, attr = A_NORMAL; int cursx, cursy; draw_msgwin(); if (settings.standout) attr = A_STANDOUT; if (getmaxy(msgwin) == 1) { wmove(msgwin, getmaxy(msgwin) - 1, COLNO - 8); wattron(msgwin, attr); waddstr(msgwin, "--More--"); wattroff(msgwin, attr); wrefresh(msgwin); } else { newline(); draw_msgwin(); wmove(msgwin, getmaxy(msgwin) - 1, COLNO / 2 - 4); wattron(msgwin, attr); waddstr(msgwin, "--More--"); wattroff(msgwin, attr); wrefresh(msgwin); } getyx(msgwin, cursy, cursx); wtimeout(msgwin, 666); /* enable blinking */ do { key = nh_wgetch(msgwin); draw_map(player.x, player.y); wmove(msgwin, cursy, cursx); doupdate(); } while (key != '\n' && key != '\r' && key != ' ' && key != KEY_ESC); wtimeout(msgwin, -1); if (getmaxy(msgwin) == 1) newline(); draw_msgwin(); if (key == KEY_ESC) stopprint = TRUE; /* we want to --more-- by screenfuls, not lines */ last_redraw_curline = curline; }
char curses_yn_function(const char *query, const char *resp, char def) { int width, height, key; WINDOW *win; char prompt[QBUFSZ]; char *rb, respbuf[QBUFSZ]; strcpy(respbuf, resp); /* any acceptable responses that follow <esc> aren't displayed */ if ((rb = strchr(respbuf, '\033')) != 0) *rb = '\0'; sprintf(prompt, "%s [%s] ", query, respbuf); if (def) sprintf(prompt + strlen(prompt), "(%c) ", def); height = 3; width = strlen(prompt) + 5; win = newdialog(height, width); mvwprintw(win, 1, 2, prompt); wrefresh(win); do { key = tolower(nh_wgetch(win)); if (key == '\033') { if (strchr(resp, 'q')) key = 'q'; else if (strchr(resp, 'n')) key = 'n'; else key = def; break; } else if (strchr(quit_chars, key)) { key = def; break; } if (!strchr(resp, key)) key = 0; } while (!key); delwin(win); redraw_game_windows(); return key; }
static int curses_msgwin_generic(const char *msg, int (*validator)(int, void *), void *arg, nh_bool cursor_visible, enum keyreq_context context) { int rv; /* We don't know whether the window system is inited right now. So ask. isendwin() is one of the few uncursed functions that works no matter what. */ if (isendwin()) { fprintf(stderr, "%s\n", msg); return validator('\x1b', arg); } /* Don't try to render this on a very small terminal. */ if (COLS < COLNO || LINES < ROWNO) return validator('\x1b', arg); int prevcurs = nh_curs_set(cursor_visible); struct gamewin *gw = alloc_gamewin(sizeof (struct win_msgwin)); struct win_msgwin *wmw = (struct win_msgwin *)gw->extra; wmw->msg = msg; wmw->context = context; gw->draw = draw_curses_msgwin; gw->resize = resize_curses_msgwin; gw->win = 0; /* resize_curses_msgwin sets the layout_{width,height}, and because gw->win is 0, allocates gw->win. */ resize_curses_msgwin(gw); draw_curses_msgwin(gw); rv = -1; while (rv == -1) rv = validator(nh_wgetch(gw->win, context), arg); delete_gamewin(gw); nh_curs_set(prevcurs); redraw_game_windows(); return rv; }
int curses_msgwin(const char *msg) { int key, len; int width = strlen(msg) + 4; int prevcurs = curs_set(0); WINDOW *win = newdialog(3, width); len = strlen(msg); while (isspace(msg[len-1])) len--; mvwaddnstr(win, 1, 2, msg, len); wrefresh(win); key = nh_wgetch(win); /* wait for any key */ delwin(win); curs_set(prevcurs); redraw_game_windows(); return key; }