Category : C Source Code
Archive   : CURSESNT.ZIP
Filename : CHARGET.C

 
Output of file : CHARGET.C contained in archive : CURSESNT.ZIP
/****************************************************************/
/* Getch() routines of the PCcurses package */
/* */
/****************************************************************/
/* This version of curses is based on ncurses, a curses version */
/* originally written by Pavel Curtis at Cornell University. */
/* I have made substantial changes to make it run on IBM PC's, */
/* and therefore consider myself free to make it public domain. */
/* Bjorn Larsson ([email protected]) */
/****************************************************************/
/* 1.4: Routines that ended in while-loops now end */
/* with return(ERR) to avoid compiler warnings. */
/* Use of short wherever possible. Portability */
/* improvements: 900114 */
/* 1.3: MSC -W3, Turbo'C' -w -w-pro checkes: 881005 */
/* 1.2: #undef:ine of getch now covers all the file, to */
/* make sure this module's getch() calls go to DOS, */
/* not to the PCCurses 'getch()' function. Fixed */
/* thanks to N.D. Pentcheff: 881002 */
/* 1.1: Bug fixes: call to _curseskeytest() changed */
/* _curseskeytst(). Test of that routine also */
/* lacked () in one place: 870907 */
/* 1.0: Release: 870515 */
/****************************************************************/

#include
#include

#undef getch /* We use MSC getch() below */
#undef ungetch

#ifdef WIN32
#define getch getchar
#define kbhit _curseskeytst
#else
#include
#endif


static short rawgetch(); /* get raw char via BIOS */
static short sysgetch(); /* get char via system */
static short validchar(); /* keypad xlate and char check */

char _curses_charget_rcsid[] = "@(#)charget.c v.1.4 - 900114";

static short buffer[_INBUFSIZ]; /* character buffer */
static short pindex = 0; /* putter index */
static short gindex = 1; /* getter index */
static WINDOW *w; /* to reduce stack usage */
static short ungind = 0; /* wungetch() push index */
static short ungch[NUNGETCH]; /* array of ungotten chars */

/* Table for key code translation of function keys in keypad mode */
/* These values are for strict IBM keyboard compatibles only */

static short kptab[] =
{
0x3b,KEY_F(1), 0x3c,KEY_F(2), 0x3d,KEY_F(3), 0x3e,KEY_F(4),
0x3f,KEY_F(5), 0x40,KEY_F(6), 0x41,KEY_F(7), 0x42,KEY_F(8),
0x43,KEY_F(9), 0x44,KEY_F(10), 0x47,KEY_HOME, 0x48,KEY_UP,
0x49,KEY_PPAGE, 0x4b,KEY_LEFT, 0x4d,KEY_RIGHT, 0x4f,KEY_LL,
0x50,KEY_DOWN, 0x51,KEY_NPAGE, 0x52,KEY_IC, 0x53,KEY_DC,
0x54,KEY_F(11), 0x55,KEY_F(12), 0x56,KEY_F(13), 0x57,KEY_F(14),
0x58,KEY_F(15), 0x59,KEY_F(16), 0x5a,KEY_F(17), 0x5b,KEY_F(18),
0x5c,KEY_F(19), 0x5d,KEY_F(20), 0x5e,KEY_F(21), 0x5f,KEY_F(22),
0x60,KEY_F(23), 0x61,KEY_F(24), 0x62,KEY_F(25), 0x63,KEY_F(26),
0x64,KEY_F(27), 0x65,KEY_F(28), 0x66,KEY_F(29), 0x67,KEY_F(30),
0x73,KEY_LEFT, 0x74,KEY_RIGHT, 0x75,KEY_LL, 0x76,KEY_NPAGE,
0x77,KEY_HOME, 0x84,KEY_PPAGE, 0x100, -1
};

/****************************************************************/
/* Wgetch(win) gets a character from the terminal, in normal, */
/* cbreak or raw mode, optionally echoing to window 'win'. */
/****************************************************************/

int wgetch(win)
WINDOW *win;
{
short key;
short cbr;

if (ungind) /* if ungotten char exists */
return(ungch[--ungind]); /* remove and return it */

if ((!_cursvar.raw) && (!_cursvar.cbreak)) /* if normal */
if (gindex < pindex) /* and data in buffer */
return(buffer[gindex++]);

w = win; /* static for speed & stack */
pindex = 0; /* prepare to buffer data */
gindex = 0;
while(1) /* loop for any buffering */
{
if (_cursvar.raw) /* get a raw character */
key = rawgetch();
else /* get a system character */
{
cbr = _cursesgcb(); /* get ^BREAK status */
_cursesscb(_cursvar.orgcbr); /* if break return proper */
key = sysgetch();
_cursesscb(cbr); /* restore as it was */
}
if (w->_nodelay && (key == -1)) /* if nodelay and no char */
return(-1);
if ((key == '\r') && _cursvar.autocr && !_cursvar.raw) /* translate cr */
key = '\n';
if (_cursvar.echo && (key < 0x100)) /* check if echo */
{
waddch(w,key);
wrefresh(w);
}
if (_cursvar.raw || _cursvar.cbreak) /* if no buffering */
return(key);
if (pindex < _INBUFSIZ-2) /* if no overflow, */
buffer[pindex++] = key; /* put data in buffer */
if ((key == '\n') || (key == '\r')) /* if we got a line */
return(buffer[gindex++]);
} /* while */
return (ERR); /* Can't happen */
} /* wgetch */

/****************************************************************/
/* Flushinp() kills any pending input characters. */
/****************************************************************/

void flushinp()
{
while(_curseskeytst()) /* empty keyboard buffer */
_curseskey();
while(kbhit()) /* empty system's buffers */
(void) getch();
gindex = 1; /* set indices to kill buffer */
pindex = 0;
ungind = 0; /* clear ungch array */
} /* flushinp */

/****************************************************************/
/* Wungetch() pushes back it's argument on the input stream. If */
/* OK, returns 1, otherwise returns 0. */
/****************************************************************/

int wungetch(ch)
int ch;
{
if (ungind >= NUNGETCH) /* pushback stack full */
return(0);
ungch[ungind++] = ch;
return(1);
} /* wungetch() */

/****************************************************************/
/* Mvgetch() first moves the stdscr cursor to a new location, */
/* then does a wgetch() on stdscr. */
/****************************************************************/

int mvgetch(y,x)
int y;
int x;
{
wmove(stdscr,y,x);
return(wgetch(stdscr));
} /* mvgetch */

/****************************************************************/
/* Mvwgetch() first moves the cursor of window 'win' to a new */
/* location, then does a wgetch() in 'win'. */
/****************************************************************/

int mvwgetch(win,y,x)
WINDOW *win;
int y;
int x;
{
wmove(win,y,x);
return(wgetch(win));
} /* mvwgetch */

/****************************************************************/
/* rawgetch() gets a character without any interpretation at */
/* all and returns it. If keypad mode is active for the desig- */
/* nated window, function key translation will be performed. */
/* Otherwise, function keys are ignored.If nodelay mode is */
/* active in the window, then rawgetch() returns -1 if no cha- */
/* racter is available. */
/****************************************************************/

static short rawgetch()
{
short c;

if (w->_nodelay && !_curseskeytst())
return(-1);
while(1) /* loop to get valid char */
{
if ((c = validchar(_curseskey())) >= 0)
return(c);
} /* while */
return (ERR); /* Can't happen */
} /* rawgetch */

/****************************************************************/
/* Sysgetch() gets a character with normal ^S, ^Q, ^P and ^C */
/* interpretation and returns it. If keypad mode is active for */
/* the designated window, function key translation will be per- */
/* formed. Otherwise, function keys are ignored. If nodelay */
/* mode is active in the window, then sysgetch() returns -1 if */
/* no character is available. */
/****************************************************************/

static short sysgetch()
{
short c;

#ifndef WIN32 /* temp hack */
if (w->_nodelay && !kbhit())
return(-1);
#endif
while(1)
{
c = getch();
if (c) /* if not a function key */
return(c & 0xff); /* avoids sign-extending */
c = getch();
if ((c = validchar(c << 8)) >= 0) /* get & check next char */
return(c);
} /* while */
return (ERR); /* Can't happen */
} /* sysgetch */

/****************************************************************/
/* Validchar(c) chacks that 'c' is a valid character, and */
/* if so returns it, with function key translation applied if */
/* 'w' has keypad mode set. If char is invalid, returns -1. */
/****************************************************************/

static short validchar(c)
int c;
{
short *scanp;

if (c == 0x0300) /* special case, ^@ = NULL */
return(0);
if (!(c & 0xff00)) /* normal character */
return(c);
if (!(w->_keypad)) /* skip f keys if not keypad mode */
return(-1);
c = (c >> 8) & 0xff;
scanp = kptab;
while(*scanp <= c) /* search for value */
{ /* (stops on table entry 0x100) */
if (*scanp++ == c)
return(*scanp); /* found, return it */
scanp++;
}
return(-1); /* not found, invalid */
} /* validchar */

/****************************************************************/
/* _cursespendch() returns 1 if there is any character avai- */
/* lable, and 0 if there is none. This is not for programmer */
/* usage, but for the updatew routines. */
/****************************************************************/

bool _cursespendch()
{
if (ungind) /* ungotten char */
return(TRUE);
if (pindex > gindex) /* buffered char */
return(TRUE);
if (_cursvar.raw) /* raw mode test */
return(_curseskeytst());
return((bool)kbhit()); /* normal mode test */
} /* _cursespendch */


  3 Responses to “Category : C Source Code
Archive   : CURSESNT.ZIP
Filename : CHARGET.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/