Esempio n. 1
0
//void Vid::screen_swap (void)
void screen_swap (void)
{
  USHORT bufsize = Screen.get_vidbufsize();
  static bool buf_ok = FALSE;
  static bool save_screen = TRUE;

  if(!buf_ok) {
    screen_buf = (char*)malloc(bufsize);
   buf_ok = TRUE;
  }
  if(save_screen) {
     rc = VioReadCellStr(screen_buf, &bufsize, 0,0,0);
     DBG_WIN1(dout<<"screen swap save VioReadCellStr rc = "<< rc<<endl);
     rc = VioWrtCellStr(Screen.get_save_buf(), bufsize, 0,0,0);
     DBG_WIN1(dout<<"screen swap save VioWrtCellStr rc = "<<rc<<endl);
//     set_cursor(63, 0);                        /* hide cursor   */
     video_int (0x0200,0,0,0);  //hide cursor 
     save_screen = FALSE;
  }
  else {
     rc = VioWrtCellStr(screen_buf, bufsize, 0,0,0); 
     DBG_WIN1(dout<<"screen swap restore VioWrtCellStr rc = "<< rc<<endl);
     DBG_WIN1(dout<<"screen_swap set_cursor OK  "<<endl);
     save_screen = TRUE;
  }
}
Esempio n. 2
0
void vm_puttext(char x1, char y1, char x2, char y2, char *srce)
{
    if (_osmode == DOS_MODE)
    {
        char x, y;
        for (y = y1; y <= y2; y++)
        {
            for (x = x1; x <= x2; x++)
            {
                vm_xputch(x, y, *(srce + 1), *srce);
                srce += 2;
            }
        }
    }
    else
    {
        USHORT width;
        char y;
        width = (USHORT) ((x2 - x1 + 1) * 2);
        for (y = y1; y <= y2; y++)
        {
            VioWrtCellStr((PBYTE) srce, width, (USHORT) (y - 1), (USHORT) (x1 - 1), 0);
            srce += width;
        }
    }
}
Esempio n. 3
0
/* return ElvTrue if VIO is available. */
static int 
vio_test (void)
{
  VIOMODEINFO info;
  USHORT rc;

#if 0
  {
    static char digits[] = "0123456789abcdef";
    char buffer[32];
    int i, j;

    for (i = 0; i < 16; i++)
      {
        for (j = 0; j < 16; j++)
          {
            buffer[j * 2] = digits[j];
            buffer[j * 2 + 1] = i * 16 + j;
            buffer[j * 2 + 1] = 0x07;
            buffer[j * 2 ] = i * 16 + j;
          }
        VioWrtCellStr (buffer, 32, i, 0, 0);
      }
    vio_read (buffer, 1, 0);
  }
#endif

  info.cb = sizeof (info);
  rc = VioGetMode (&info, 0);

  return rc == NO_ERROR;
}
Esempio n. 4
0
int ConPutBox(int X, int Y, int W, int H, PCell Cell) {
  int I;
  int MX, MY;
  int MouseHidden  = 0;
  unsigned char *p = (unsigned char *)Cell;

  if (MouseVisible) ConQueryMousePos(&MX, &MY);

  for (I = 0; I < H; I++) {
    if (MouseVisible)
      if (Y + I == MY)
        if ((MX >= X) && (MX <= X + W)) {
          DrawMouse(0);
          MouseHidden = 1;
        }
    VioWrtCellStr((PCH)p, (USHORT)(W << 1), (USHORT)(Y + I), (USHORT)X, 0);

    if (MouseHidden) {
          DrawMouse(1);
      MouseHidden = 0;
    }
    p += W << 1;
  }
  return 0;
}
Esempio n. 5
0
void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
{
    /* this should be enough for the maximum width of a screen. */

    struct {unsigned char text, attr;} temp_line[256];
    int j;

    PDC_LOG(("PDC_transform_line() - called: line %d\n", lineno));

    /* replace the attribute part of the chtype with the 
       actual color value for each chtype in the line */

    for (j = 0; j < len; j++)
    {
        chtype ch = srcp[j];

        temp_line[j].attr = pdc_atrtab[ch >> PDC_ATTR_SHIFT];

#ifdef CHTYPE_LONG
        if (ch & A_ALTCHARSET && !(ch & 0xff80))
            ch = acs_map[ch & 0x7f];
#endif
        temp_line[j].text = ch & 0xff;
    }

#ifdef EMXVIDEO
    v_putline((char *)temp_line, x, lineno, len);
#else
    VioWrtCellStr((PCH)temp_line, (USHORT)(len * sizeof(unsigned short)),
                  (USHORT)lineno, (USHORT)x, 0);
#endif
}
Esempio n. 6
0
void Restore_area(PAREA parea)
{
int i,s;
   if (parea)
      {
      s=CELL_SIZE * parea->width;                  // размер строки в байтах
      for (i=0; i < parea->height; i++)
         VioWrtCellStr(parea->store + (i * s),s,parea->row+i,parea->col,hvio);
      }
}
Esempio n. 7
0
void vm_puttext(char x1, char y1, char x2, char y2, char *srce)
{
    USHORT width;
    char y;
    width = (USHORT) ((x2 - x1 + 1) * 2);
    for (y = y1; y <= y2; y++)
    {
        VioWrtCellStr((PBYTE) srce, width, (USHORT) (y - 1), (USHORT) (x1 - 1), 0);
        srce += width;
    }
}
Esempio n. 8
0
void FlipScreenCursor( void )
/***************************/
{
    char        buffer[2];
    USHORT      length;

    length = 2;
    VioReadCellStr( buffer, &length, Row+RowOffset, StartCol+ColOffset, 0 );
    buffer[1] ^= 0x77;
    VioWrtCellStr( buffer, length, Row+RowOffset, StartCol+ColOffset, 0 );
}
Esempio n. 9
0
/* --------------------------------------------------------------------------
 Display a menu of choices, returning the ordinal (0 based) of the selected
 choice.
- Parameters -------------------------------------------------------------
 INT iRow      : line position (0 = top of screen, -1 = current position).
 PSZ pszPrompt : prompt message.
 PSZ choices   : array of choice characters (max 5 characters).
 PMENUFN pfunc : optional callback function used when the menu has a
                 'retry' item. When pfunc() returns FALSE the loop is
                 terminated.
 PVOID pparm   : optional pfunc() parameters.
- Return value -----------------------------------------------------------
 ULONG : number of the selected choice.
- Note: ------------------------------------------------------------------
 If pszPrompt is NULL the area where the prompt message is printed is
 cleared and no other action is performed.
-------------------------------------------------------------------------- */
ULONG showMenu(PSZ pszPrompt, PSZ choices) {
   CHAR achscr[1760];
   CHAR achmenu[1760];
   CHAR buf[4];
   ULONG key;
   USHORT row, col, irow, cb;
   PSZ pChoice, pLine, pEnd;

   buf[0] = ' ';
   buf[1] = VIOB_GRAY | VIOF_DARKBLUE;
   DosBeep(220, 50);
   DosBeep(440, 50);
   DosBeep(880, 50);
   cb = sizeof(achscr);
   VioReadCellStr(achscr, &cb, 7, 0, 0);
   VioScrollUp(7, 0, 17, 80, 11, buf, 0);
   sprintf(achmenu, pszPrompt,
           choices[0], choices[1], choices[2], choices[3], choices[4]);
   VioGetCurPos(&row, &col, 0);
   for (pLine = pEnd = achmenu, irow = 8; pEnd; ++irow)
   {
      if (NULL != (pEnd = strchr(pLine, '\r')))
      {
         *pEnd = '\0';
         if (*++pEnd == '\n') ++pEnd;
      }
      // skip empty lines
      if (*pLine)
         VioWrtCharStrAtt(pLine, strlen(pLine), irow, 0, buf + 1, 0);
      pLine = pEnd;
   }
   VioSetCurPos(irow, 0, 0);
//   VioWrtCharStrAtt(pszPrompt, strlen(pszPrompt), 8, 0, buf + 1, 0);
   for (;;)
   {
      key = kbdKeyChar(kbdKey()) & ~0x20;
      if (NULL != (pChoice = strchr(choices, (INT)key)))
         break;
      DosBeep(440, 100);
   }
   VioWrtCellStr(achscr, cb, 7, 0, 0);
   VioSetCurPos(row, col, 0);
   return (ULONG)(pChoice - choices);
}
Esempio n. 10
0
/* This function writes the contents of 'ttybuf' to the screen */
static void 
do_flush (void)
{
  if (ttycount > 0)
    {
      if (raw_mode)
        {
          VioWrtCellStr (ttybuf, ttycount, c_row, c_col, 0);
          if ((c_col += ttycount / 2) >= o_ttycolumns)
            {
              c_col -= o_ttycolumns;
              c_row++;
            }
        }
      else
        {
          VioWrtTTY (ttybuf, ttycount, 0);
        }
      ttycount = 0;
    }
}
Esempio n. 11
0
static void os2vio_flush(aa_context * c)
{
  char data[] = {
    (WM_BLACK << 4) + WM_PALEGRAY,    /* NORMAL?   0 */
    (WM_BLACK << 4) + WM_DKGREY,      /* DIM?      1 */
    (WM_BLACK << 4) + WM_WHITE,       /* BOLD?     2 */
    (WM_RED << 4) + WM_PALEGRAY,      /* BOLDFONT? 3 */
    (WM_PALEGRAY << 4) + WM_BLACK,    /* REVERSE?  4 */
    (WM_BLUE << 4) + WM_WHITE         /* SPECIAL?  5 */
  };

  int x, y;
  for (y = 0; y < aa_scrheight(c); y++) {
    for (x = 0; x < aa_scrwidth(c); x++) {
      if(c->attrbuffer[x + y * aa_scrwidth(c)] < 7)
	RowStr[x*2+1] = data[c->attrbuffer[x + y * aa_scrwidth(c)]];
      else
	RowStr[x*2+1] = (WM_BLACK << 4) + WM_PALEGRAY;
      RowStr[x*2] = c->textbuffer[x + y * aa_scrwidth(c)];
    }
    VioWrtCellStr(RowStr, 2*width, y, 0, (HVIO)0);
  }
}
Esempio n. 12
0
USHORT __pascal VIOWRTCELLSTR(const PCHAR CellStr, const USHORT Count, const USHORT Row, const USHORT Column, const HVIO Handle)
{
  return VioWrtCellStr(CellStr, Count, Row, Column, Handle);
}
int EditAttributes (FILES *f) {

  char  *buf;
  USHORT len = (vio.col * 7) * 2,curpos = 0;
  char   nattr = (1 << 4) | (7 | 8);
  char   sattr = 8;
  int    ret = 0,x,key;
  BOOL   okay = TRUE;
  char   attrs[5] = "----";

  if(!f)
    return -1;
  buf = malloc(len);
  if(!buf)
    return -1;

  ThreadMsg(" ");

  VioReadCellStr(buf,&len,(vio.row / 2) - 1,0,0);

  VioWrtCharStrAtt("ÚÄ Attributes: Ä¿",17,(vio.row / 2) - 1,
                   34,&nattr,0);
  VioWrtCharStrAtt("³ Readonly: [ ] ³",17,vio.row / 2,
                   34,&nattr,0);
  VioWrtCharStrAtt("³ Hidden:   [ ] ³",17,(vio.row / 2) + 1,
                   34,&nattr,0);
  VioWrtCharStrAtt("³ System:   [ ] ³",17,(vio.row / 2) + 2,
                   34,&nattr,0);
  VioWrtCharStrAtt("³ Archived: [ ] ³",17,(vio.row / 2) + 3,
                   34,&nattr,0);
  VioWrtCharStrAtt("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ",17,(vio.row / 2) + 4,
                   34,&nattr,0);
  VioWrtNAttr(&sattr,1,vio.row / 2,51,0);
  VioWrtNAttr(&sattr,1,(vio.row / 2) + 1,51,0);
  VioWrtNAttr(&sattr,1,(vio.row / 2) + 2,51,0);
  VioWrtNAttr(&sattr,1,(vio.row / 2) + 3,51,0);
  VioWrtNAttr(&sattr,1,(vio.row / 2) + 4,51,0);
  VioWrtNAttr(&sattr,16,(vio.row / 2) + 5,36,0);
  if(f->attrFile & FILE_READONLY)
    attrs[0] = 'x';
  if(f->attrFile & FILE_HIDDEN)
    attrs[1] = 'x';
  if(f->attrFile & FILE_SYSTEM)
    attrs[2] = 'x';
  if(f->attrFile & FILE_ARCHIVED)
    attrs[3] = 'x';
  for(x = 0;x < 4;x++)
    VioWrtCharStr(attrs + x,1,x + (vio.row / 2),47,0);
  VioSetCurPos(curpos + (vio.row / 2),47,0);
  ShowCursor(FALSE);
  while(okay) {
    VioWrtCharStr(attrs + curpos,1,curpos + (vio.row / 2),47,0);
    VioSetCurPos(curpos + (vio.row / 2),47,0);
    key = get_ch(-1);
    switch(key) {
      case 256:
        break;

      case 45 | 256:
      case 61 | 256:
      case '\x1b':  /* abort */
        okay = FALSE;
        ret = -1;
        break;

      case '\r':      /* process */
        okay = FALSE;
        {
          FILESTATUS3 fs3;

          if(!DosQueryPathInfo(f->filename,FIL_STANDARD,&fs3,sizeof(fs3))) {
            fs3.attrFile &= (~FILE_DIRECTORY);
            if(attrs[0] == 'x')
              fs3.attrFile |= FILE_READONLY;
            else
              fs3.attrFile &= (~FILE_READONLY);
            if(attrs[1] == 'x')
              fs3.attrFile |= FILE_HIDDEN;
            else
              fs3.attrFile &= (~FILE_HIDDEN);
            if(attrs[2] == 'x')
              fs3.attrFile |= FILE_SYSTEM;
            else
              fs3.attrFile &= (~FILE_SYSTEM);
            if(attrs[3] == 'x')
              fs3.attrFile |= FILE_ARCHIVED;
            else
              fs3.attrFile &= (~FILE_ARCHIVED);
            if(DosSetPathInfo(f->filename,FIL_STANDARD,&fs3,sizeof(fs3),
                              DSPI_WRTTHRU))
              DosBeep(50,100);
            else
              ret = 1;
          }
          else
            DosBeep(50,100);
        }
        break;

      case 72 | 256:  /* up */
        curpos--;
        if(curpos > 3)
          curpos = 3;
        break;

      case 'x':
      case 'X':
      case '+':
        attrs[curpos] = 'x';
        break;

      case '-':
        attrs[curpos] = '-';
        break;

      case ' ':       /* toggle */
        attrs[curpos] = (attrs[curpos] == 'x') ? '-' : 'x';
        VioWrtCharStr(attrs + curpos,1,curpos + (vio.row / 2),47,0);
        /* intentional fallthru */
      case 80 | 256:  /* down */
        curpos++;
        if(curpos > 3)
          curpos = 0;
        break;
    }
  }

  ShowCursor(TRUE);
  VioWrtCellStr(buf,len,(vio.row / 2) - 1,0,0);
  free(buf);
  SetupConsole();
  ThreadMsg(NULL);
  return ret;
}
int EnterLine (char *buf,ULONG len,USHORT y,char *filename,
               char **choices,int numc,int start) {

  ULONG         pos = 0,c,nm,numchars = 0,tpos,wl;
  APIRET        rc;
  int           key,attr = ((7 << 4) << 8) | ' ',ret = 0;
  BOOL          okay = TRUE,insert = TRUE,lasttab = FALSE;
  char         *sav,*k = NULL,*p;
  static char   keybuf[1026];
  USHORT        t;
  FILEFINDBUF3  fb3;
  HDIR          hdir = HDIR_CREATE;

  wl = 0;

  sav = malloc(vio.col * 2);
  if(!sav) {
    DosBeep(50,100);
    *buf = 0;
    return -1;
  }

  ThreadMsg(" ");

  t = vio.col * 2;
  VioReadCellStr(sav,&t,y,0,0);
  VioWrtNCell((char *)&attr,vio.col,y,0,0);
  ShowCursor(FALSE);
  VioSetCurPos(y,0,0);

  for(c = 0;c < len - 1;c++) {          /* find end of default string */
    if(!buf[c])
      break;
  }
  pos = c;
  for(;c < len - 1;c++)                 /* space-pad remainder of buf */
    buf[c] = ' ';

  while(okay) {
    /* assure buffer is null terminated (cluck, cluck) */
    buf[len - 1] = 0;

    /* assure pos hasn't gone past our limit */
    if(pos > len - 1)
      pos = len - 1;

    /* set left side of entry field */
    if(pos < wl)
      wl = pos;
    if(pos >= wl + vio.col)
      wl = (pos - vio.col) + 1;

    /* set cursor position */
    VioSetCurPos(y,pos - wl,0);

    /* display buf */
    tpos = min(vio.col,len - wl); /* max length of displayable text */
    VioWrtCharStr(buf + wl,tpos,y,0,0); /* show text */
    if(tpos < vio.col)                  /* space-pad? */
      VioWrtNChar(" ",vio.col - tpos,y,tpos,0);

    if(k && *k)   /* "macros" waiting to be entered? */
      key = *k++; /* yep, skip keyboard input */
    else {        /* nope, go to the keyboard */
      k = NULL;   /* clear macro pointer */
      key = get_ch(-1);
    }

    switch(key) {
      case 256:       /* shiftstate changed -- ignore */
        break;

      case '\r':      /* accept input */
        okay = FALSE;
        break;

      case 45 | 256:
      case 61 | 256:
      case '\x1b':    /* Escape -- exit editor */
        memset(buf,' ',len - 1);
        buf[len - 1] = 0;
        okay = FALSE;
        ret = -1;
        break;

      case '\b':
        if(pos) {
          pos--;
          memmove(buf + pos,buf + (pos + 1),len - (pos + 1));
          buf[len - 2] = ' ';
        }
        lasttab = FALSE;
        break;

      case 25:          /* ctrl+y -- clear input */
        VioWrtNCell((char *)&attr,vio.col,y,0,0);
        memset(buf,' ',len - 1);
        buf[len - 1] = 0;
        wl = pos = 0;
        lasttab = FALSE;
        break;

      case 59 | 256:    /* F1 -- insert directory */
        k = directory;
        lasttab = FALSE;
        break;

      case 60 | 256:    /* F2 -- insert filename */
        if(filename)
          k = filename;
        lasttab = FALSE;
        break;

      case 62 | 256:    /* F4 -- insert target */
        k = target;
        lasttab = FALSE;
        break;

      case 15:          /* shift+tab */
        if(hdir != (HDIR)HDIR_CREATE) {
          DosFindClose(hdir);
          hdir = HDIR_CREATE;
          lasttab = FALSE;
        }
        /* intentional fallthru */
      case 9:           /* tab -- auto-complete */
        if(!pos || pos >= len - 1)
          break;
        if(lasttab && numchars) {
          lasttab = FALSE;
          for(tpos = 0;tpos < numchars;tpos++)
            keybuf[tpos] = '\b';
          keybuf[tpos++] = '\01';
          keybuf[tpos] = 0;
          numchars = 0;
          k = keybuf;
          break;
        }
        else {
          if(hdir != (HDIR)HDIR_CREATE)
            DosFindClose(hdir);
          hdir = HDIR_CREATE;
        }
        /* intentional fallthru */
      case 1:           /* cheat! */
        k = NULL;
        if(!pos || pos >= len - 1)
          break;
        tpos = pos - 1;
        while(tpos && buf[tpos] != ' ')
          tpos--;
        if(buf[tpos] == ' ')
          tpos++;
        strcpy(keybuf,buf + tpos);
        tpos = 0;
        while(keybuf[tpos] && keybuf[tpos] != ' ')
          tpos++;
        keybuf[tpos] = 0;
        lstrip(rstrip(keybuf));
        if(*keybuf) {
          strcat(keybuf,"*");
          nm = 1;
          if(hdir == (HDIR)HDIR_CREATE)
            rc = DosFindFirst(keybuf,
                              &hdir,
                              FILE_NORMAL    | FILE_HIDDEN   | FILE_SYSTEM |
                              FILE_DIRECTORY | FILE_ARCHIVED | FILE_READONLY,
                              &fb3,
                              sizeof(fb3),
                              &nm,
                              FIL_STANDARD);
          else
            rc = DosFindNext(hdir,&fb3,sizeof(fb3),&nm);
          if(!rc) {
            while((fb3.attrFile & FILE_DIRECTORY) &&
                  (*fb3.achName == '.' && (!fb3.achName[1] ||
                                           (fb3.achName[1] == '.' &&
                                            !fb3.achName[2])))) {
              nm = 1;
              if(DosFindNext(hdir,&fb3,sizeof(fb3),&nm)) {
                DosFindClose(hdir);
                hdir = HDIR_CREATE;
                *fb3.achName = 0;
                break;
              }
            }
            if(*fb3.achName) {
              keybuf[strlen(keybuf) - 1] = 0;
              p = strchr(keybuf,'\\');
              if(p)
                p++;
              else
                p = keybuf;
              tpos = 0;
              while(*p && fb3.achName[tpos] &&
                    toupper(*p) == toupper(fb3.achName[tpos])) {
                p++;
                tpos++;
              }
              if(fb3.achName[tpos]) {
                strcpy(keybuf,fb3.achName + tpos);
                numchars = strlen(keybuf);
                lasttab = TRUE;
                k = keybuf;
              }
              else if(hdir != (HDIR)HDIR_CREATE) {
                DosFindClose(hdir);
                hdir = HDIR_CREATE;
              }
            }
          }
          else if(hdir != (HDIR)HDIR_CREATE) {
            DosBeep(50,50);
            DosFindClose(hdir);
            hdir = HDIR_CREATE;
          }
        }
        break;

      case 83 | 256:    /* delete */
        memmove(buf + pos,buf + (pos + 1),len - (pos + 1));
        buf[len - 2] = ' ';
        lasttab = FALSE;
        break;

      case 82 | 256:    /* insert */
        insert = (insert) ? FALSE : TRUE;
        break;

      case 71 | 256:    /* home */
        wl = pos = 0;
        lasttab = FALSE;
        break;

      case 79 | 256:    /* end */
        pos = len - 2;
        while(pos && buf[pos] == ' ')
          pos--;
        if(pos && buf[pos] != ' ')
          pos++;
        lasttab = FALSE;
        break;

      case 75 | 256:    /* left */
        if(pos)
          pos--;
        lasttab = FALSE;
        break;

      case 77 | 256:    /* right */
        if(pos < len - 1)
          pos++;
        lasttab = FALSE;
        break;

      case 72 | 256:    /* up */
        lasttab = FALSE;
        if(choices) {
          if(choices[start]) {
            VioWrtNCell((char *)&attr,vio.col,y,0,0);
            memset(buf,' ',len - 1);
            buf[len - 1] = 0;
            wl = pos = 0;
            k = choices[start];
            start++;
            while(start < numc && !choices[start])
              start++;
            if(start > (numc - 1))
              start = 0;
            if(!choices[start]) {
              while(start < numc && !choices[start])
                start++;
            }
            if(start > (numc - 1))
              start = 0;
          }
        }
        break;

      case 80 | 256:    /* down */
        lasttab = FALSE;
        if(choices) {
          if(choices[start]) {
            VioWrtNCell((char *)&attr,vio.col,y,0,0);
            memset(buf,' ',len - 1);
            buf[len - 1] = 0;
            wl = pos = 0;
            k = choices[start];
            start--;
            while(start >= 0 && !choices[start])
              start--;
            if(start < 0)
              start = numc - 1;
            if(!choices[start]) {
              while(start >= 0 && !choices[start])
                start--;
            }
            if(start < 0)
              start = numc - 1;
          }
        }
        break;

      case 115 | 256:   /* ctrl+left */
        while(pos && buf[pos] == ' ')
          pos--;
        while(pos && buf[pos] != ' ')
          pos--;
        lasttab = FALSE;
        break;

      case 116 | 256:   /* ctrl + right */
        while(pos < len - 1 && buf[pos] == ' ')
          pos++;
        while(pos < len - 1 && buf[pos] != ' ')
          pos++;
        lasttab = FALSE;
        break;

      default:
        if(pos < len - 1 && !(key & 256) && !iscntrl(key)) {
          if(insert) {
            if(pos < len - 2) {
              memmove(buf + (pos + 1),buf + pos,len - (pos + 2));
              buf[len - 2] = ' ';
            }
            buf[pos] = (char)key;
          }
          else
            buf[pos] = (char)key;
          pos++;
        }
        else if(pos >= len - 1)
          DosBeep(250,25);
        break;
    }
  }

  if(hdir != (HDIR)HDIR_CREATE)
    DosFindClose(hdir);

  ShowCursor(TRUE);
  VioWrtCellStr(sav,vio.col * 2,y,0,0);
  free(sav);
  SetupConsole();

  ThreadMsg(NULL);

  buf[len - 1] = 0;
  lstrip(rstrip(buf));
  return (ret) ? ret : strlen(buf);
}
int SimpleInput (char *title,char *text,ULONG beep,ULONG dur,ULONG wait,
                 int *responses) {

  char  *buf;
  int    xlen,key = 0,x;
  USHORT len = (vio.col * 7) * 2,start,mlen,cell;
  char   sattr = 8;
  BOOL   okay = TRUE;

  if(!title)
    title = "";
  if(!text)
    return key;
  xlen = min(max(strlen(title),strlen(text)),vio.col - 6);
  mlen = xlen + 6;
  start = (vio.col - xlen) / 2;

  buf = malloc(len);
  if(buf) {
    /* save screen under */
    VioReadCellStr(buf,&len,(vio.row / 2) - 2,0,0);
    /* draw borders */
    /* first, bright white left and top */
    cell = ((((7 | 8) << 4) | 7) << 8) | ' ';
    VioWrtNCell((char *)&cell,mlen,(vio.row / 2) - 2,start,0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2) - 1,start,0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2),start,0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 1,start,0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 2,start,0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 3,start,0);
    /* now dark grey right and bottom */
    cell = (((8 << 4) | 7) << 8) | ' ';
    VioWrtNCell((char *)&cell,1,(vio.row / 2) - 1,start + (mlen - 1),0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2),start + (mlen - 1),0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 1,start + (mlen - 1),0);
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 2,start + (mlen - 1),0);
    VioWrtNCell((char *)&cell,mlen - 1,(vio.row / 2) + 3,start + 1,0);
    /* fill title area with light grey foreground, red background */
    cell = (((7 << 4) | 4) << 8) | ' ';
    VioWrtNCell((char *)&cell,mlen - 2,(vio.row / 2) - 1,start + 1,0);
    /* fill text area with light grey foreground, black background */
    cell = (((7 << 4) | 0) << 8) | ' ';
    VioWrtNCell((char *)&cell,mlen - 4,(vio.row / 2) + 1,start + 2,0);
    /* make interior border -- first white on light grey */
    cell = (((7 << 4) | (7 | 8)) << 8) | 'Ú';
    VioWrtNCell((char *)&cell,1,(vio.row / 2),start + 1,0);
    cell = (((7 << 4) | (7 | 8)) << 8) | '¿';
    VioWrtNCell((char *)&cell,1,(vio.row / 2),start + (mlen - 2),0);
    cell = (((7 << 4) | (7 | 8)) << 8) | 'Ä';
    VioWrtNCell((char *)&cell,mlen - 4,(vio.row / 2),start + 2,0);
    cell = (((7 << 4) | (7 | 8)) << 8) | '³';
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 1,start + 1,0);
    cell = (((7 << 4) | (7 | 8)) << 8) | 'À';
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 2,start + 1,0);
    /* now dark grey on light grey */
    cell = (((7 << 4) | 8) << 8) | 'Ä';
    VioWrtNCell((char *)&cell,mlen - 4,(vio.row / 2) + 2,start + 2,0);
    cell = (((7 << 4) | 8) << 8) | 'Ù';
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 2,start + (mlen - 2),0);
    cell = (((7 << 4) | 8) << 8) | '³';
    VioWrtNCell((char *)&cell,1,(vio.row / 2) + 1,start + (mlen - 2),0);

    /* insert title */
    VioWrtCharStr(title,
                  min(xlen,strlen(title)),
                  (vio.row / 2) - 1,
                  (start + (mlen / 2)) - (min(xlen,strlen(title)) / 2),
                  0);
    /* insert text */
    VioWrtCharStr(text,
                  min(xlen,strlen(text)),
                  (vio.row / 2) + 1,
                  (start + (mlen / 2)) - (min(xlen,strlen(text)) / 2),
                  0);
    /* draw shadow */
    VioWrtNAttr(&sattr,1,(vio.row / 2) - 1,start + mlen,0);
    VioWrtNAttr(&sattr,1,(vio.row / 2),start + mlen,0);
    VioWrtNAttr(&sattr,1,(vio.row / 2) + 1,start + mlen,0);
    VioWrtNAttr(&sattr,1,(vio.row / 2) + 2,start + mlen,0);
    VioWrtNAttr(&sattr,1,(vio.row / 2) + 3,start + mlen,0);
    VioWrtNAttr(&sattr,mlen,(vio.row / 2) + 4,start + 1,0);
    VioSetCurPos((vio.row / 2) + 1,start + (mlen - 3),0);
    if(responses)
      ShowCursor(FALSE);
    if(beep)
      DosBeep(beep,dur);
    if(!responses)
      DosSleep(wait);
    else {
      KbdFlushBuffer(0);
      while(okay) {
        key = get_ch(-1);
        if(!*responses)
          break;
        for(x = 0;responses[x];x++) {
          if(key == responses[x]) {
            okay = FALSE;
            break;
          }
        }
      }
    }
    ShowCursor(TRUE);
    VioWrtCellStr(buf,len,(vio.row / 2) - 2,0,0);
    free(buf);
    KbdFlushBuffer(0);
    ThreadMsg(NULL);
  }
  return key;
}
void RestoreScreen (char *buf) {

  VioSetMode(&vio,0);
  if(buf) 
    VioWrtCellStr(buf,((vio.col + 1) * (vio.row + 1)) * 2,0,0,0);
}