pt_menuitem showmenus(char startmenu) { pt_menuitem rv; char oldpage,tpos; // Setup screen for menusystem oldpage = getdisppage(); setdisppage(ms->menupage); cls(); clearwindow(ms->minrow, ms->mincol, ms->maxrow, ms->maxcol, ms->menupage, ms->fillchar, ms->fillattr); tpos = (ms->numcols - strlen(ms->title) - 1) >> 1; // center it on line gotoxy(ms->minrow,ms->mincol,ms->menupage); cprint(ms->tfillchar,ms->titleattr,ms->numcols,ms->menupage); gotoxy(ms->minrow,ms->mincol+tpos,ms->menupage); csprint(ms->title,ms->titleattr); cursoroff(); // Doesn't seem to work? // Go, main menu cannot be a radio menu rv = runmenusystem(ms->minrow+MENUROW, ms->mincol+MENUCOL, ms->menus[(unsigned int)startmenu], 0, NORMALMENU); // Hide the garbage we left on the screen cursoron(); if (oldpage == ms->menupage) cls(); else setdisppage(oldpage); // Return user choice return rv; }
/* called from devmouse */ void setcursor(Cursor* curs) { cursoroff(0); swload(curs); cursoron(0); }
/* * Print a formatted colour message at the bottom of the screen, wait a while */ void wait_message( unsigned int sdelay, const char *fmt, ...) { va_list ap; va_start(ap, fmt); clear_message(); #ifdef HAVE_COLOR fcol(tinrc.col_message); #endif /* HAVE_COLOR */ vsnprintf(mesg, sizeof(mesg), fmt, ap); my_fputs(mesg, stdout); #ifdef HAVE_COLOR fcol(tinrc.col_normal); #endif /* HAVE_COLOR */ cursoron(); my_flush(); (void) sleep(sdelay); /* clear_message(); would be nice, but tin doesn't expect this yet */ va_end(ap); }
static void vgactl(Cmdbuf *cb) { int align, i, size, x, y, z; char *chanstr, *p; ulong chan; Cmdtab *ct; VGAscr *scr; extern VGAdev *vgadev[]; extern VGAcur *vgacur[]; scr = &vgascreen[0]; ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg)); switch(ct->index) { case CMhwgc: if(strcmp(cb->f[1], "off") == 0) { lock(&cursor); if(scr->cur) { if(scr->cur->disable) scr->cur->disable(scr); scr->cur = nil; } unlock(&cursor); return; } if(strcmp(cb->f[1], "soft") == 0) { lock(&cursor); swcursorinit(); if(scr->cur && scr->cur->disable) scr->cur->disable(scr); scr->cur = &swcursor; if(scr->cur->enable) scr->cur->enable(scr); unlock(&cursor); return; } for(i = 0; vgacur[i]; i++) { if(strcmp(cb->f[1], vgacur[i]->name)) continue; lock(&cursor); if(scr->cur && scr->cur->disable) scr->cur->disable(scr); scr->cur = vgacur[i]; if(scr->cur->enable) scr->cur->enable(scr); unlock(&cursor); return; } break; case CMtype: for(i = 0; vgadev[i]; i++) { if(strcmp(cb->f[1], vgadev[i]->name)) continue; if(scr->dev && scr->dev->disable) scr->dev->disable(scr); scr->dev = vgadev[i]; if(scr->dev->enable) scr->dev->enable(scr); return; } break; case CMtextmode: screeninit(); return; case CMsize: x = strtoul(cb->f[1], &p, 0); if(x == 0 || x > 10240) error(Ebadarg); if(*p) p++; y = strtoul(p, &p, 0); if(y == 0 || y > 10240) error(Ebadarg); if(*p) p++; z = strtoul(p, &p, 0); chanstr = cb->f[2]; if((chan = strtochan(chanstr)) == 0) error("bad channel"); if(chantodepth(chan) != z) error("depth, channel do not match"); cursoroff(1); deletescreenimage(); if(screensize(x, y, z, chan)) error(Egreg); vgascreenwin(scr); resetscreenimage(); cursoron(1); return; case CMactualsize: if(scr->gscreen == nil) error("set the screen size first"); x = strtoul(cb->f[1], &p, 0); if(x == 0 || x > 2048) error(Ebadarg); if(*p) p++; y = strtoul(p, nil, 0); if(y == 0 || y > 2048) error(Ebadarg); if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y) error("physical screen bigger than virtual"); physgscreenr = Rect(0,0,x,y); scr->gscreen->clipr = physgscreenr; return; case CMpalettedepth: x = strtoul(cb->f[1], &p, 0); if(x != 8 && x != 6) error(Ebadarg); scr->palettedepth = x; return; case CMdrawinit: memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP, S); if(scr && scr->dev && scr->dev->drawinit) scr->dev->drawinit(scr); return; case CMlinear: if(cb->nf!=2 && cb->nf!=3) error(Ebadarg); size = strtoul(cb->f[1], 0, 0); if(cb->nf == 2) align = 0; else align = strtoul(cb->f[2], 0, 0); if(screenaperture(size, align) < 0) error("not enough free address space"); return; /* case CMmemset: memset((void*)strtoul(cb->f[1], 0, 0), atoi(cb->f[2]), atoi(cb->f[3])); return; */ case CMblank: drawblankscreen(1); return; case CMunblank: drawblankscreen(0); return; case CMblanktime: blanktime = strtoul(cb->f[1], 0, 0); return; case CMpanning: if(strcmp(cb->f[1], "on") == 0) { if(scr == nil || scr->cur == nil) error("set screen first"); if(!scr->cur->doespanning) error("panning not supported"); scr->gscreen->clipr = scr->gscreen->r; panning = 1; } else if(strcmp(cb->f[1], "off") == 0) { scr->gscreen->clipr = physgscreenr; panning = 0; } else break; return; case CMhwaccel: if(strcmp(cb->f[1], "on") == 0) hwaccel = 1; else if(strcmp(cb->f[1], "off") == 0) hwaccel = 0; else break; return; case CMhwblank: if(strcmp(cb->f[1], "on") == 0) hwblank = 1; else if(strcmp(cb->f[1], "off") == 0) hwblank = 0; else break; return; } cmderror(cb, "bad VGA control message"); }
static void vgactl(char* a) { int align, i, n, size, x, y, z; char *chanstr, *field[6], *p; ulong chan; VGAscr *scr; extern VGAdev *vgadev[]; extern VGAcur *vgacur[]; Rectangle r; n = tokenize(a, field, nelem(field)); if(n < 1) error(Ebadarg); scr = &vgascreen[0]; if(strcmp(field[0], "hwgc") == 0){ if(n < 2) error(Ebadarg); if(strcmp(field[1], "off") == 0){ lock(&cursor); if(scr->cur){ if(scr->cur->disable) scr->cur->disable(scr); scr->cur = nil; } unlock(&cursor); return; } for(i = 0; vgacur[i]; i++){ if(strcmp(field[1], vgacur[i]->name)) continue; lock(&cursor); if(scr->cur && scr->cur->disable) scr->cur->disable(scr); scr->cur = vgacur[i]; if(scr->cur->enable) scr->cur->enable(scr); unlock(&cursor); return; } } else if(strcmp(field[0], "type") == 0){ if(n < 2) error(Ebadarg); for(i = 0; vgadev[i]; i++){ if(strcmp(field[1], vgadev[i]->name)) continue; if(scr->dev && scr->dev->disable) scr->dev->disable(scr); scr->dev = vgadev[i]; if(scr->dev->enable) scr->dev->enable(scr); return; } } else if(strcmp(field[0], "size") == 0){ if(n < 3) error(Ebadarg); if(drawhasclients()) error(Ebusy); x = strtoul(field[1], &p, 0); if(x == 0 || x > 2048) error(Ebadarg); if(*p) p++; y = strtoul(p, &p, 0); if(y == 0 || y > 2048) error(Ebadarg); if(*p) p++; z = strtoul(p, &p, 0); chanstr = field[2]; if((chan = strtochan(chanstr)) == 0) error("bad channel"); if(chantodepth(chan) != z) error("depth, channel do not match"); cursoroff(1); deletescreenimage(); if(screensize(x, y, z, chan)) error(Egreg); vgascreenwin(scr); cursoron(1); return; } else if(strcmp(field[0], "actualsize") == 0){ if(scr->gscreen == nil) error("set the screen size first"); if(n < 2) error(Ebadarg); x = strtoul(field[1], &p, 0); if(x == 0 || x > 2048) error(Ebadarg); if(*p) p++; y = strtoul(p, nil, 0); if(y == 0 || y > 2048) error(Ebadarg); if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y) error("physical screen bigger than virtual"); r = Rect(0,0,x,y); if(!eqrect(r, scr->gscreen->r)){ if(scr->cur == nil || scr->cur->doespanning == 0) error("virtual screen not supported"); } physgscreenr = r; return; } else if(strcmp(field[0], "palettedepth") == 0){ if(n < 2) error(Ebadarg); x = strtoul(field[1], &p, 0); if(x != 8 && x != 6) error(Ebadarg); scr->palettedepth = x; return; } else if(strcmp(field[0], "drawinit") == 0){ if(scr && scr->dev && scr->dev->drawinit) scr->dev->drawinit(scr); return; } else if(strcmp(field[0], "linear") == 0){ if(n < 2) error(Ebadarg); size = strtoul(field[1], 0, 0); if(n < 3) align = 0; else align = strtoul(field[2], 0, 0); if(screenaperture(size, align)) error("not enough free address space"); return; } /* else if(strcmp(field[0], "memset") == 0){ if(n < 4) error(Ebadarg); memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3])); return; } */ else if(strcmp(field[0], "blank") == 0){ if(n < 1) error(Ebadarg); drawblankscreen(1); return; } else if(strcmp(field[0], "blanktime") == 0){ if(n < 2) error(Ebadarg); blanktime = strtoul(field[1], 0, 0); return; } else if(strcmp(field[0], "hwaccel") == 0){ if(n < 2) error(Ebadarg); if(strcmp(field[1], "on") == 0) hwaccel = 1; else if(strcmp(field[1], "off") == 0) hwaccel = 0; return; } else if(strcmp(field[0], "hwblank") == 0){ if(n < 2) error(Ebadarg); if(strcmp(field[1], "on") == 0) hwblank = 1; else if(strcmp(field[1], "off") == 0) hwblank = 0; return; } error(Ebadarg); }
int runmenu(char x, char y, const char *menu[], int defaultitem) { int key, i,j, itemno; int nitems, width; char *s; itemno = defaultitem-1; width = 20; width = 10; nitems = 0; while (menu[nitems] != 0) { for (j=0;menu[nitems][j];j++); if (j>width) width = j; nitems++; } width+=2; if (itemno < 0 || itemno > nitems) itemno = 0; while (1) { cursoroff(); textattr(CYAN<<4 | BLACK); gotoxy(x,y); _putch(ACS_ULCORNER); for (i=0;i<width+2;i++) _putch(ACS_HLINE); _putch(ACS_URCORNER); for (i = 0;i<nitems;i++) { gotoxy(x,y+i+1); _putch(ACS_VLINE); _putch(' '); if (i == itemno) textattr(YELLOW); s = 0; for (j=0;j<width;j++) { if (s && *s) _putch(*s++); else _putch(' '); if (s == 0) s = (char *)menu[i]; } textattr(CYAN<<4 | BLACK); _putch(' '); _putch(ACS_VLINE); } gotoxy(x,y+nitems+1); _putch(ACS_LLCORNER); for (i=0;i<width+2;i++) _putch(ACS_HLINE); _putch(ACS_LRCORNER); while (!_kbhit()) ; if (_kbhit()) { key = _getch(); switch(key) { case KB_UP: if (itemno>0) itemno--; else itemno = nitems-1; break; case KB_DOWN: itemno++; itemno %= nitems; break; case KB_ESC: cursoron(); return 0; case KB_ENTER: cursoron(); return itemno+1; } } } }
char * tin_getline( const char *prompt, int number_only, /* 1=positive numbers only, 2=negative too */ const char *str, int max_chars, t_bool passwd, int which_hist) { int c, i, loc, tmp, gl_max; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wint_t wc; #else char *buf = gl_buf; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ is_passwd = passwd; set_xclick_off(); if (prompt == NULL) prompt = ""; gl_buf[0] = 0; /* used as end of input indicator */ gl_fixup(-1, 0); /* this resets gl_fixup */ gl_width = cCOLS - strlen(prompt); gl_prompt = prompt; gl_pos = gl_cnt = 0; if (max_chars == 0) { if (number_only) gl_max = 6; else gl_max = BUF_SIZE; } else gl_max = max_chars; my_fputs(prompt, stdout); cursoron(); my_flush(); if (gl_in_hook) { loc = gl_in_hook(gl_buf); if (loc >= 0) gl_fixup(0, BUF_SIZE); } if (!cmd_line && gl_max == BUF_SIZE) CleartoEOLN(); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (str != NULL) { wchar_t wbuf[LEN]; if (mbstowcs(wbuf, str, ARRAY_SIZE(wbuf) - 1) != (size_t) -1) { wbuf[ARRAY_SIZE(wbuf) - 1] = (wchar_t) '\0'; for (i = 0; wbuf[i]; i++) gl_addwchar(wbuf[i]); } } while ((wc = ReadWch()) != WEOF) { if ((gl_cnt < gl_max) && iswprint(wc)) { if (number_only) { if (iswdigit(wc)) { gl_addwchar(wc); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && wc == (wint_t) '-') { gl_addwchar(wc); } else { ring_bell(); } } else gl_addwchar(wc); } else { c = (int) wc; switch (wc) { #else if (str != NULL) { for (i = 0; str[i]; i++) gl_addchar(str[i]); } while ((c = ReadCh()) != EOF) { c &= 0xff; if ((gl_cnt < gl_max) && my_isprint(c)) { if (number_only) { if (isdigit(c)) { gl_addchar(c); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && c == '-') { gl_addchar(c); } else { ring_bell(); } } else gl_addchar(c); } else { switch (c) { #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ case ESC: /* abort */ #ifdef HAVE_KEY_PREFIX case KEY_PREFIX: #endif /* HAVE_KEY_PREFIX */ switch (get_arrow_key(c)) { case KEYMAP_UP: case KEYMAP_PAGE_UP: hist_prev(which_hist); break; case KEYMAP_PAGE_DOWN: case KEYMAP_DOWN: hist_next(which_hist); break; case KEYMAP_RIGHT: gl_fixup(-1, gl_pos + 1); break; case KEYMAP_LEFT: gl_fixup(-1, gl_pos - 1); break; case KEYMAP_HOME: gl_fixup(-1, 0); break; case KEYMAP_END: gl_fixup(-1, gl_cnt); break; case KEYMAP_DEL: gl_del(0); break; case KEYMAP_INS: #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar((wint_t) ' '); #else gl_addchar(' '); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ break; default: return (char *) 0; } break; case '\n': /* newline */ case '\r': gl_newline(which_hist); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; case CTRL_A: gl_fixup(-1, 0); break; case CTRL_B: gl_fixup(-1, gl_pos - 1); break; case CTRL_D: if (gl_cnt == 0) { gl_buf[0] = 0; my_fputc('\n', stdout); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } else gl_del(0); break; case CTRL_E: gl_fixup(-1, gl_cnt); break; case CTRL_F: gl_fixup(-1, gl_pos + 1); break; case CTRL_H: case DEL: gl_del(-1); break; case TAB: if (gl_tab_hook) { tmp = gl_pos; loc = gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp); if (loc >= 0 || tmp != gl_pos) gl_fixup(loc, tmp); } break; case CTRL_W: gl_kill_back_word(); break; case CTRL_U: gl_fixup(-1, 0); /* FALLTHROUGH */ case CTRL_K: gl_kill(); break; case CTRL_L: case CTRL_R: gl_redraw(); break; case CTRL_N: hist_next(which_hist); break; case CTRL_P: hist_prev(which_hist); break; default: ring_bell(); break; } } } #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } /* * adds the character c to the input buffer at current location if * the character is in the allowed template of characters */ static void #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar( wint_t wc) #else gl_addchar( int c) #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ { int i; /* * Crashing is always the worst solution IMHO. So as a quick hack, * ignore characters silently, if buffer is full. To allow a final * newline, leave space for one more character. Just a hack too. * This was the original code: * if (gl_cnt >= BUF_SIZE - 1) { error_message("tin_getline: input buffer overflow"); giveup(); } */ if (gl_cnt >= BUF_SIZE - 2) return; for (i = gl_cnt; i >= gl_pos; i--) gl_buf[i + 1] = gl_buf[i]; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[gl_pos] = (wchar_t) wc; #else gl_buf[gl_pos] = c; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ gl_fixup(gl_pos, gl_pos + 1); } /* * Cleans up entire line before returning to caller. A \n is appended. * If line longer than screen, we redraw starting at beginning */ static void gl_newline( int w) { int change = gl_cnt; int len = gl_cnt; int loc = gl_width - 5; /* shifts line back to start position */ if (gl_cnt >= BUF_SIZE - 1) { /* * Like above: avoid crashing if possible. gl_addchar() now * leaves one space left for the newline, so this part of the * code should never be reached. A proper implementation is * desirable though. */ error_message("tin_getline: input buffer overflow"); giveup(); } hist_add(w); /* only adds if nonblank */ if (gl_out_hook) { change = gl_out_hook(gl_buf); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) len = wcslen(gl_buf); #else len = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (loc > len) loc = len; gl_fixup(change, loc); /* must do this before appending \n */ #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[len] = (wchar_t) '\0'; #else gl_buf[len] = '\0'; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } /* * Delete a character. The loc variable can be: * -1 : delete character to left of cursor * 0 : delete character under cursor */ static void gl_del( int loc) { int i; if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) { for (i = gl_pos + loc; i < gl_cnt; i++) gl_buf[i] = gl_buf[i + 1]; gl_fixup(gl_pos + loc, gl_pos + loc); } else ring_bell(); }