Subject: lib/3969: Updates to libcurses in a more friendly format (supercedes 3962 & 3966)
To: None <gnats-bugs@gnats.netbsd.org>
From: Brett Lymn (Master of the Siren) <blymn@baea.com.au>
List: netbsd-bugs
Date: 08/12/1997 11:17:21
>Number: 3969
>Category: lib
>Synopsis: Correct problems with 3962 submission
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: lib-bug-people (Library Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Aug 11 18:50:02 1997
>Last-Modified:
>Originator: Brett Lymn (Master of the Siren)
>Organization:
Brett Lymn
>Release: 2nd August 1997
>Environment:
System: NetBSD siren 1.2G NetBSD 1.2G (SIREN) #0: Sat Aug 9 17:10:14 CST 1997 toor@siren:/usr/src/sys/arch/i386/compile/SIREN i386
>Description:
My original send-pr (3962) was a compressed uuencoded tar file
which is not reviewer friendly. Below is the patch file uncompressed, this
patch also folds in send-pr 3966 which corrects an endian bug in the original
submission.
>How-To-Repeat:
n/a
>Fix:
Index: src/lib/libcurses/Makefile
diff -c src/lib/libcurses/Makefile:1.1.1.2 src/lib/libcurses/Makefile:1.5
*** src/lib/libcurses/Makefile:1.1.1.2 Tue Aug 5 19:33:59 1997
--- src/lib/libcurses/Makefile Sun Aug 10 17:58:21 1997
***************
*** 8,16 ****
SRCS= addbytes.c addch.c addnstr.c box.c clear.c clrtobot.c clrtoeol.c \
cr_put.c ctrace.c cur_hash.c curses.c delch.c deleteln.c delwin.c \
erase.c fullname.c getch.c getstr.c id_subwins.c idlok.c initscr.c \
! insch.c insertln.c longname.c move.c mvwin.c newwin.c overlay.c \
! overwrite.c printw.c putchar.c refresh.c scanw.c scroll.c setterm.c \
! standout.c toucholap.c touchwin.c tscroll.c tstp.c tty.c unctrl.c
MAN= curses.3
INCS= curses.h unctrl.h
INCSDIR=/usr/include
--- 8,17 ----
SRCS= addbytes.c addch.c addnstr.c box.c clear.c clrtobot.c clrtoeol.c \
cr_put.c ctrace.c cur_hash.c curses.c delch.c deleteln.c delwin.c \
erase.c fullname.c getch.c getstr.c id_subwins.c idlok.c initscr.c \
! insch.c insertln.c keypad.c longname.c move.c mvwin.c newwin.c \
! nodelay.c notimeout.c overlay.c overwrite.c printw.c putchar.c \
! refresh.c scanw.c scroll.c setterm.c standout.c toucholap.c \
! touchwin.c tscroll.c tstp.c tty.c unctrl.c
MAN= curses.3
INCS= curses.h unctrl.h
INCSDIR=/usr/include
Index: src/lib/libcurses/curses.3
diff -c src/lib/libcurses/curses.3:1.1.1.2 src/lib/libcurses/curses.3:1.2
*** src/lib/libcurses/curses.3:1.1.1.2 Tue Aug 5 19:34:11 1997
--- src/lib/libcurses/curses.3 Sun Aug 10 17:55:08 1997
***************
*** 87,93 ****
.It delch() delete a character
.It deleteln() delete a line
.It delwin(win) delete
! .Em stdscr
.It echo() set echo mode
.It endwin() end window modes
.It erase() erase
--- 87,93 ----
.It delch() delete a character
.It deleteln() delete a line
.It delwin(win) delete
! .Em win
.It echo() set echo mode
.It endwin() end window modes
.It erase() erase
***************
*** 106,111 ****
--- 106,113 ----
.It initscr() initialize screens
.It insch(c) insert a char
.It insertln() insert a line
+ .It keypad(win, boolf) set keypad flag for
+ .Em win
.It leaveok(win,boolf) set leave flag for
.Em stdscr
.It longname(termbuf,name) get long name from
***************
*** 116,124 ****
--- 118,130 ----
.It newwin(lines,cols,begin_y,begin_x)\ create a new window
.It nl() set newline mapping
.It nocbreak() unset cbreak mode
+ .It nodelay(win, boolf) unset blocking reads for
+ .Em win
.It noecho() unset echo mode
.It nonl() unset newline mapping
.It noraw() unset raw mode
+ .It notimeout(win, boolf) unset infinite timeout on keypad assembly for
+ .Em win
.It overlay(win1,win2) overlay win1 on win2
.It overwrite(win1,win2) overwrite win1 on top of win2
.It printw(fmt,arg1,arg2,...) printf on
Index: src/lib/libcurses/curses.h
diff -c src/lib/libcurses/curses.h:1.1.1.2 src/lib/libcurses/curses.h:1.4
*** src/lib/libcurses/curses.h:1.1.1.2 Tue Aug 5 19:34:13 1997
--- src/lib/libcurses/curses.h Tue Aug 5 20:16:49 1997
***************
*** 93,98 ****
--- 93,204 ----
/* END BACKWARD COMPATIBILITY ONLY. */
+ /* symbols for values returned by getch in keypad mode */
+ #define KEY_BREAK 0x101 /* break key */
+ #define KEY_DOWN 0x102 /* down arrow */
+ #define KEY_UP 0x103 /* up arrow */
+ #define KEY_LEFT 0x104 /* left arrow */
+ #define KEY_RIGHT 0x105 /* right arrow*/
+ #define KEY_HOME 0x106 /* home key */
+ #define KEY_BACKSPACE 0x107 /* Backspace */
+
+ /* First function key (block of 64 follow) */
+ #define KEY_F0 0x108
+ /* Function defining other function key values*/
+ #define KEY_F(n) (KEY_F0+(n))
+
+ #define KEY_DL 0x148 /* Delete Line */
+ #define KEY_IL 0x149 /* Insert Line*/
+ #define KEY_DC 0x14A /* Delete Character */
+ #define KEY_IC 0x14B /* Insert Character */
+ #define KEY_EIC 0x14C /* Exit Insert Char mode */
+ #define KEY_CLEAR 0x14D /* Clear screen */
+ #define KEY_EOS 0x14E /* Clear to end of screen */
+ #define KEY_EOL 0x14F /* Clear to end of line */
+ #define KEY_SF 0x150 /* Scroll one line forward */
+ #define KEY_SR 0x151 /* Scroll one line back */
+ #define KEY_NPAGE 0x152 /* Next Page */
+ #define KEY_PPAGE 0x153 /* Prev Page */
+ #define KEY_STAB 0x154 /* Set Tab */
+ #define KEY_CTAB 0x155 /* Clear Tab */
+ #define KEY_CATAB 0x156 /* Clear All Tabs */
+ #define KEY_ENTER 0x157 /* Enter or Send */
+ #define KEY_SRESET 0x158 /* Soft Reset */
+ #define KEY_RESET 0x159 /* Hard Reset */
+ #define KEY_PRINT 0x15A /* Print */
+ #define KEY_LL 0x15B /* Home Down */
+
+ /*
+ * "Keypad" keys arranged like this:
+ *
+ * A1 up A3
+ * left B2 right
+ * C1 down C3
+ *
+ */
+ #define KEY_A1 0x15C /* Keypad upper left */
+ #define KEY_A3 0x15D /* Keypad upper right */
+ #define KEY_B2 0x15E /* Keypad centre key */
+ #define KEY_C1 0x15F /* Keypad lower left */
+ #define KEY_C3 0x160 /* Keypad lower right */
+
+ #define KEY_BTAB 0x161 /* Back Tab */
+ #define KEY_BEG 0x162 /* Begin key */
+ #define KEY_CANCEL 0x163 /* Cancel key */
+ #define KEY_CLOSE 0x164 /* Close Key */
+ #define KEY_COMMAND 0x165 /* Command Key */
+ #define KEY_COPY 0x166 /* Copy key */
+ #define KEY_CREATE 0x167 /* Create key */
+ #define KEY_END 0x168 /* End key */
+ #define KEY_EXIT 0x169 /* Exit key */
+ #define KEY_FIND 0x16A /* Find key */
+ #define KEY_HELP 0x16B /* Help key */
+ #define KEY_MARK 0x16C /* Mark key */
+ #define KEY_MESSAGE 0x16D /* Message key */
+ #define KEY_MOVE 0x16E /* Move key */
+ #define KEY_NEXT 0x16F /* Next Object key */
+ #define KEY_OPEN 0x170 /* Open key */
+ #define KEY_OPTIONS 0x171 /* Options key */
+ #define KEY_PREVIOUS 0x172 /* Previous Object key */
+ #define KEY_REDO 0x173 /* redo key */
+ #define KEY_REFERENCE 0x174 /* Ref Key */
+ #define KEY_REFRESH 0x175 /* Refresh key */
+ #define KEY_REPLACE 0x176 /* Replace key */
+ #define KEY_RESTART 0x177 /* Restart key */
+ #define KEY_RESUME 0x178 /* Resume key */
+ #define KEY_SAVE 0x179 /* Save key */
+ #define KEY_SBEG 0x17A /* Shift begin key */
+ #define KEY_SCANCEL 0x17B /* Shift Cancel key */
+ #define KEY_SCOMMAND 0x17C /* Shift Command key */
+ #define KEY_SCOPY 0x17D /* Shift Copy key */
+ #define KEY_SCREATE 0x17E /* Shift Create key */
+ #define KEY_SDC 0x17F /* Shift Delete Character */
+ #define KEY_SDL 0x180 /* Shift Delete Line */
+ #define KEY_SELECT 0x181 /* Select key */
+ #define KEY_SEND 0x182 /* Send key */
+ #define KEY_SEOL 0x183 /* Shift Clear Line key */
+ #define KEY_SEXIT 0x184 /* Shift Exit key */
+ #define KEY_SFIND 0x185 /* Shift Find key */
+ #define KEY_SHELP 0x186 /* Shift Help key */
+ #define KEY_SHOME 0x187 /* Shift Home key */
+ #define KEY_SIC 0x188 /* Shift Input key */
+ #define KEY_SLEFT 0x189 /* Shift Left Arrow key */
+ #define KEY_SMESSAGE 0x18A /* Shift Message key */
+ #define KEY_SMOVE 0x18B /* Shift Move key */
+ #define KEY_SNEXT 0x18C /* Shift Next key */
+ #define KEY_SOPTIONS 0x18D /* Shift Options key */
+ #define KEY_SPREVIOUS 0x18E /* Shift Previous key */
+ #define KEY_SPRINT 0x18F /* Shift Print key */
+ #define KEY_SREDO 0x190 /* Shift Redo key */
+ #define KEY_SREPLACE 0x191 /* Shift Replace key */
+ #define KEY_SRIGHT 0x192 /* Shift Right Arrow key */
+ #define KEY_SRESUME 0x193 /* Shift Resume key */
+ #define KEY_SSAVE 0x194 /* Shift Save key */
+ #define KEY_SSUSPEND 0x195 /* Shift Suspend key */
+ #define KEY_SUNDO 0x196 /* Shift Undo key */
+ #define KEY_SUSPEND 0x197 /* Suspend key */
+ #define KEY_UNDO 0x198 /* Undo key */
+
/* 8-bit ASCII characters. */
#define unctrl(c) __unctrl[(c) & 0xff]
#define unctrllen(ch) __unctrllen[(ch) & 0xff]
***************
*** 149,154 ****
--- 255,263 ----
#define __CLEAROK 0x040 /* Clear on next refresh. */
#define __WSTANDOUT 0x080 /* Standout window */
#define __LEAVEOK 0x100 /* If curser left */
+ #define __KEYPAD 0x1000 /* If interpreting keypad codes */
+ #define __NODELAY 0x2000 /* Don't block in getch */
+ #define __NOTIMEOUT 0x4000 /* Wait indefinitely for func keys */
unsigned int flags;
} WINDOW;
***************
*** 255,260 ****
--- 364,370 ----
int gettmode __P((void));
void idlok __P((WINDOW *, int));
WINDOW *initscr __P((void));
+ void keypad __P((WINDOW *, int));
char *longname __P((char *, char *));
int mvcur __P((int, int, int, int));
int mvprintw __P((int, int, const char *, ...));
***************
*** 265,273 ****
--- 375,385 ----
WINDOW *newwin __P((int, int, int, int));
int nl __P((void));
int nocbreak __P((void));
+ void nodelay __P((WINDOW *, int));
int noecho __P((void));
int nonl __P((void));
int noraw __P((void));
+ void notimeout __P((WINDOW *, int));
int overlay __P((WINDOW *, WINDOW *));
int overwrite __P((WINDOW *, WINDOW *));
int printw __P((const char *, ...));
***************
*** 326,331 ****
--- 438,448 ----
int __touchwin __P((WINDOW *));
char *__tscroll __P((const char *, int, int));
int __waddch __P((WINDOW *, __LDATA *));
+ void __init_getch __P((char *));
+ int __nodelay __P((void));
+ int __delay __P((void));
+ int __notimeout __P((void));
+ int __timeout __P((void));
/* Private #defines. */
#define min(a,b) (a < b ? a : b)
Index: src/lib/libcurses/getch.c
diff -c src/lib/libcurses/getch.c:1.1.1.2 src/lib/libcurses/getch.c:1.7
*** src/lib/libcurses/getch.c:1.1.1.2 Tue Aug 5 19:34:20 1997
--- src/lib/libcurses/getch.c Tue Aug 12 11:11:48 1997
***************
*** 42,50 ****
--- 42,401 ----
#endif
#endif /* not lint */
+ #include <string.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <stdio.h>
#include "curses.h"
/*
+ * Keyboard input handler. Do this by snarfing
+ * all the info we can out of the termcap entry for TERM and putting it
+ * into a set of keymaps. A keymap is an array the size of all the possible
+ * single characters we can get, the contents of the array is a structure
+ * that contains the type of entry this character is (i.e. part/end of a
+ * multi-char sequence or a plain char) and either a pointer which will point
+ * to another keymap (in the case of a multi-char sequence) OR the data value
+ * that this key should return.
+ *
+ */
+
+ /* private data structures for holding the key definitions */
+ typedef struct keymap keymap_t;
+ typedef struct key_entry key_entry_t;
+
+ struct key_entry {
+ short type; /* type of key this is */
+ union {
+ keymap_t *next; /* next keymap is key is multi-key sequence */
+ int symbol; /* key symbol if key is a leaf entry */
+ } value;
+ };
+
+ /* Types of key structures we can have */
+ #define KEYMAP_MULTI 1 /* part of a multi char sequence */
+ #define KEYMAP_LEAF 2 /* key has a symbol associated with it, either it
+ is the end of a multi-char sequence or a single
+ char key that generates a symbol */
+
+ /* The max number of different chars we can receive */
+ #define MAX_CHAR 256
+
+ struct keymap {
+ int count; /* count of number of key structs allocated */
+ short mapping[MAX_CHAR]; /* mapping of key to allocated structs */
+ key_entry_t *key[0]; /* dynamic array of keys */
+ };
+
+
+ /* Key buffer */
+ #define INBUF_SZ 16 /* size of key buffer - must be larger than longest
+ multi-key sequence */
+ char inbuf[INBUF_SZ];
+ int start, end, working; /* pointers for manipulating inbuf data */
+
+ #define INC_POINTER(ptr) do { \
+ (ptr)++; \
+ ptr %= INBUF_SZ; \
+ } while(0)
+
+ short state; /* state of the inkey function */
+
+ #define INKEY_NORM 0 /* no key backlog to process */
+ #define INKEY_ASSEMBLING 1 /* assembling a multi-key sequence */
+ #define INKEY_BACKOUT 2 /* recovering from an unrecognised key */
+ #define INKEY_TIMEOUT 3 /* multi-key sequence timeout */
+
+ /* The termcap data we are interested in and the symbols they map to */
+ struct tcdata {
+ char *name; /* name of termcap entry */
+ int symbol; /* the symbol associated with it */
+ };
+
+ const struct tcdata tc[] = {
+ {"K1", KEY_A1},
+ {"K2", KEY_B2},
+ {"K3", KEY_A3},
+ {"K4", KEY_C1},
+ {"K5", KEY_C3},
+ {"k0", KEY_F0},
+ {"k1", KEY_F(1)},
+ {"k2", KEY_F(2)},
+ {"k3", KEY_F(3)},
+ {"k4", KEY_F(4)},
+ {"k5", KEY_F(5)},
+ {"k6", KEY_F(6)},
+ {"k7", KEY_F(7)},
+ {"k8", KEY_F(8)},
+ {"k9", KEY_F(9)},
+ {"kA", KEY_IL},
+ {"ka", KEY_CATAB},
+ {"kb", KEY_BACKSPACE},
+ {"kC", KEY_CLEAR},
+ {"kD", KEY_DC},
+ {"kd", KEY_DOWN},
+ {"kE", KEY_EOL},
+ {"kF", KEY_SF},
+ {"kH", KEY_LL},
+ {"kh", KEY_HOME},
+ {"kI", KEY_IC},
+ {"kL", KEY_DL},
+ {"kl", KEY_LEFT},
+ {"kN", KEY_NPAGE},
+ {"kP", KEY_PPAGE},
+ {"kR", KEY_SR},
+ {"kr", KEY_RIGHT},
+ {"kS", KEY_EOS},
+ {"kT", KEY_STAB},
+ {"kt", KEY_CTAB},
+ {"ku", KEY_UP}
+ };
+
+ /* Number of TC entries .... */
+ const int num_tcs = (sizeof(tc)/sizeof(struct tcdata));
+
+ /* The root keymap */
+
+ keymap_t *base_keymap;
+
+ /* prototypes for private functions */
+ keymap_t *
+ new_keymap(void); /* create a new keymap */
+
+ key_entry_t *
+ new_key(void); /* create a new key entry */
+
+ unsigned
+ inkey(int);
+
+ /*
+ * Init_inkey - initialise all the pointers & structures needed to make
+ * inkey work.
+ *
+ */
+ void
+ __init_getch(sp)
+ char *sp;
+ {
+ int i, j, length;
+ keymap_t *current;
+ char termcap[1024], entry[1024], termname[1024], *p;
+ key_entry_t *the_key;
+
+ /* init the inkey state variable */
+ state = INKEY_NORM;
+
+ /* init the base keymap */
+ base_keymap = new_keymap();
+
+ /* key input buffer pointers */
+ start = end = working = 0;
+
+ /* now do the termcap snarfing ... */
+ strncpy(termname, sp, 1022);
+ termname[1023] = 0;
+
+ if (tgetent(termcap, termname) > 0)
+ {
+ for (i = 0; i < num_tcs; i++)
+ {
+ p = entry;
+ if (tgetstr(tc[i].name, &p) != NULL)
+ {
+ current = base_keymap; /* always start with base keymap. */
+ length = strlen(entry);
+
+ for (j = 0; j < length - 1; j++)
+ {
+ if (current->mapping[(unsigned) entry[j]] < 0) /* first time for this char */
+ {
+ current->mapping[(unsigned) entry[j]] = current->count; /* map new entry */
+ the_key = new_key();
+ the_key->type = KEYMAP_MULTI; /* must be coz we are here */
+ the_key->value.next = new_keymap(); /* need for next key */
+
+ current->key[current->count++] = the_key; /* put into key array */
+
+ }
+
+ /* next key uses this map... */
+ current = current->key[current->mapping[(unsigned) entry[j]]]->value.next;
+ }
+
+ /* this is the last key in the sequence (it may have been the
+ only one but that does not matter) this means it is a leaf
+ key and should have a symbol associated with it */
+ current->mapping[(unsigned) entry[length - 1]] = current->count;
+ the_key = new_key();
+ the_key->type = KEYMAP_LEAF; /* leaf key */
+ the_key->value.symbol = tc[i].symbol; /* the associated symbol */
+ current->key[current->count++] = the_key;
+ }
+ }
+ }
+ }
+
+
+ /*
+ * new_keymap - allocates & initialises a new keymap structure. This
+ * function returns a pointer to the new keymap.
+ *
+ */
+ keymap_t *
+ new_keymap(void)
+ {
+ int i;
+ keymap_t *new_map;
+
+ if ((new_map = malloc(sizeof(keymap_t))) == NULL)
+ {
+ perror("Inkey: Cannot allocate new keymap");
+ exit(2);
+ }
+
+ /* initialise the new map */
+ new_map->count = 0;
+ for (i = 0; i < MAX_CHAR; i++)
+ {
+ new_map->mapping[i] = -1; /* no mapping for char */
+ }
+
+ return new_map;
+ }
+
+ /*
+ * new_key - allocates & initialises a new key entry. This function returns
+ * a pointer to the newly allocated key entry.
+ *
+ */
+ key_entry_t *
+ new_key(void)
+ {
+ key_entry_t *new_one;
+
+ if ((new_one = malloc(sizeof(key_entry_t))) == NULL)
+ {
+ perror("inkey: Cannot allocate new key entry");
+ exit(2);
+ }
+
+ new_one->type = 0;
+ new_one->value.next = NULL;
+
+ return new_one;
+ }
+
+ /*
+ * inkey - do the work to process keyboard input, check for multi-key
+ * sequences and return the appropriate symbol if we get a match.
+ *
+ */
+
+ unsigned
+ inkey(to)
+ int to;
+ {
+ int k, nchar;
+ char c;
+ keymap_t *current = base_keymap;
+
+ while (1) /* loop until we get a complete key sequence */
+ {
+ reread:
+ if (state == INKEY_NORM)
+ {
+ if ((nchar = read(STDIN_FILENO, &c, sizeof(char))) < 0) return ERR;
+ k = (unsigned int) c;
+ if (nchar == 0) return ERR; /* just in case we are nodelay mode */
+
+ working = start;
+ inbuf[working] = k;
+ INC_POINTER(working);
+ end = working;
+ state = INKEY_ASSEMBLING; /* go to the assembling state now */
+ }
+ else if (state == INKEY_BACKOUT)
+ {
+ k = inbuf[working];
+ INC_POINTER(working);
+ if (working == end) /* see if we have run out of keys in the backlog */
+ {
+ state = INKEY_ASSEMBLING; /* if we have then switch to assembling */
+ }
+ }
+ else if (state == INKEY_ASSEMBLING) /* assembling a key sequence */
+ {
+ if (to && (__timeout() == ERR)) return ERR;
+ if ((nchar = read(STDIN_FILENO, &c, sizeof(char))) < 0) return ERR;
+ if (to && (__notimeout() == ERR)) return ERR;
+
+ k = (unsigned int) c;
+ if (nchar == 0) /* inter-char timeout, start backing out */
+ {
+ if (start == end) goto reread; /* no chars in the buffer, restart */
+ k = inbuf[start];
+ state = INKEY_TIMEOUT;
+ }
+ else
+ {
+ inbuf[working] = k;
+ INC_POINTER(working);
+ end = working;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Inkey state screwed - exiting!!!");
+ exit(2);
+ }
+
+ /* Check key has no special meaning and we have not timed out */
+ if ((current->mapping[k] < 0) || (state == INKEY_TIMEOUT))
+ {
+ k = inbuf[start]; /* return the first key we know about */
+
+ INC_POINTER(start);
+ working = start;
+
+ if (start == end) /* only one char processed */
+ {
+ state = INKEY_NORM;
+ }
+ else /* otherwise we must have more than one char to backout */
+ {
+ state = INKEY_BACKOUT;
+ }
+ return k;
+ }
+ else /* must be part of a multikey sequence */
+ {
+ /* check for completed key sequence */
+ if (current->key[current->mapping[k]]->type == KEYMAP_LEAF)
+ {
+ start = working; /* eat the key sequence in inbuf */
+
+ if (start == end) /* check if inbuf empty now */
+ {
+ state = INKEY_NORM; /* if it is go back to normal */
+ }
+ else /* otherwise go to backout state */
+ {
+ state = INKEY_BACKOUT;
+ }
+
+ /* return the symbol */
+ return current->key[current->mapping[k]]->value.symbol;
+
+ }
+ else /* step on to next part of the multi-key sequence */
+ {
+ current = current->key[current->mapping[k]]->value.next;
+ }
+ }
+ }
+ }
+
+ /*
* wgetch --
* Read in a character from the window.
*/
***************
*** 52,58 ****
wgetch(win)
register WINDOW *win;
{
! register int inp, weset;
if (!(win->flags & __SCROLLOK) && (win->flags & __FULLWIN)
&& win->curx == win->maxx - 1 && win->cury == win->maxy - 1)
--- 403,411 ----
wgetch(win)
register WINDOW *win;
{
! register int weset;
! int inp;
! char c;
if (!(win->flags & __SCROLLOK) && (win->flags & __FULLWIN)
&& win->curx == win->maxx - 1 && win->cury == win->maxy - 1)
***************
*** 67,76 ****
} else
weset = 0;
! inp = getchar();
#ifdef DEBUG
__CTRACE("wgetch got '%s'\n", unctrl(inp));
#endif
if (__echoit) {
mvwaddch(curscr,
win->cury + win->begy, win->curx + win->begx, inp);
--- 420,453 ----
} else
weset = 0;
! if (win->flags & __NODELAY)
! {
! if (__nodelay() == ERR) return ERR;
! }
!
! if (win->flags & __KEYPAD)
! {
! inp = inkey(win->flags & __NOTIMEOUT);
! }
! else
! {
! if (read(STDIN_FILENO, &c, sizeof(char)) < 0)
! {
! inp = ERR;
! }
! else
! {
! inp = (unsigned int) c;
! }
! }
#ifdef DEBUG
__CTRACE("wgetch got '%s'\n", unctrl(inp));
#endif
+ if (win->flags & __NODELAY)
+ {
+ if (__delay() == ERR) return ERR;
+ }
+
if (__echoit) {
mvwaddch(curscr,
win->cury + win->begy, win->curx + win->begx, inp);
***************
*** 78,82 ****
}
if (weset)
nocbreak();
! return (inp);
}
--- 455,459 ----
}
if (weset)
nocbreak();
! return ((inp < 0) || (inp == ERR) ? ERR : inp);
}
Index: src/lib/libcurses/initscr.c
diff -c src/lib/libcurses/initscr.c:1.1.1.2 src/lib/libcurses/initscr.c:1.3
*** src/lib/libcurses/initscr.c:1.1.1.2 Tue Aug 5 19:34:25 1997
--- src/lib/libcurses/initscr.c Tue Aug 5 20:16:51 1997
***************
*** 91,96 ****
--- 91,98 ----
return (NULL);
}
+ __init_getch(sp);
+
__set_stophandler();
#ifdef DEBUG
Index: src/lib/libcurses/keypad.c
diff -c /dev/null src/lib/libcurses/keypad.c:1.2
*** /dev/null Tue Aug 12 11:12:46 1997
--- src/lib/libcurses/keypad.c Tue Aug 5 20:16:52 1997
***************
*** 0 ****
--- 1,59 ----
+ /*
+ * Copyright (c) 1981, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ #include <sys/cdefs.h>
+ #ifndef lint
+ #if 0
+ static char sccsid[] = "@(#)initscr.c 8.2 (Berkeley) 5/4/94";
+ #else
+ __RCSID("$NetBSD: initscr.c,v 1.7 1997/07/22 07:36:47 mikel Exp $");
+ #endif
+ #endif /* not lint */
+
+ #include "curses.h"
+
+ /*
+ * keypad --
+ * Turn on and off interpretation of function/keypad keys in the
+ * given window.
+ */
+ void
+ keypad(win, bf)
+ WINDOW *win;
+ int bf;
+ {
+ if (bf)
+ win->flags |= __KEYPAD;
+ else
+ win->flags &= ~__KEYPAD;
+ }
Index: src/lib/libcurses/nodelay.c
diff -c /dev/null src/lib/libcurses/nodelay.c:1.3
*** /dev/null Tue Aug 12 11:12:46 1997
--- src/lib/libcurses/nodelay.c Sun Aug 10 16:34:33 1997
***************
*** 0 ****
--- 1,59 ----
+ /*
+ * Copyright (c) 1981, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ #include <sys/cdefs.h>
+ #ifndef lint
+ #if 0
+ static char sccsid[] = "@(#)initscr.c 8.2 (Berkeley) 5/4/94";
+ #else
+ __RCSID("$NetBSD: initscr.c,v 1.7 1997/07/22 07:36:47 mikel Exp $");
+ #endif
+ #endif /* not lint */
+
+ #include "curses.h"
+
+ /*
+ * nodelay --
+ * Turn on and off blocking reads in getch for a
+ * given window.
+ */
+ void
+ nodelay(win, bf)
+ WINDOW *win;
+ int bf;
+ {
+ if (bf)
+ win->flags |= __NODELAY;
+ else
+ win->flags &= ~__NODELAY;
+ }
Index: src/lib/libcurses/notimeout.c
diff -c /dev/null src/lib/libcurses/notimeout.c:1.3
*** /dev/null Tue Aug 12 11:12:47 1997
--- src/lib/libcurses/notimeout.c Tue Aug 5 20:16:55 1997
***************
*** 0 ****
--- 1,59 ----
+ /*
+ * Copyright (c) 1981, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ #include <sys/cdefs.h>
+ #ifndef lint
+ #if 0
+ static char sccsid[] = "@(#)initscr.c 8.2 (Berkeley) 5/4/94";
+ #else
+ __RCSID("$NetBSD: initscr.c,v 1.7 1997/07/22 07:36:47 mikel Exp $");
+ #endif
+ #endif /* not lint */
+
+ #include "curses.h"
+
+ /*
+ * notimeout --
+ * Turn on and off inter-key timeout when assembling function keys for a
+ * given window.
+ */
+ void
+ notimeout(win, bf)
+ WINDOW *win;
+ int bf;
+ {
+ if (bf)
+ win->flags &= ~__NOTIMEOUT;
+ else
+ win->flags |= __NOTIMEOUT;
+ }
Index: src/lib/libcurses/tty.c
diff -c src/lib/libcurses/tty.c:1.1.1.2 src/lib/libcurses/tty.c:1.3
*** src/lib/libcurses/tty.c:1.1.1.2 Tue Aug 5 19:34:48 1997
--- src/lib/libcurses/tty.c Tue Aug 5 20:16:56 1997
***************
*** 64,69 ****
--- 64,71 ----
struct termios __orig_termios, __baset;
static struct termios cbreakt, rawt, *curt;
static int useraw;
+ static int ovmin = 1;
+ static int ovtime = 0;
#ifndef OXTABS
#ifdef XTABS /* SMI uses XTABS. */
***************
*** 166,171 ****
--- 168,215 ----
}
int
+ __delay()
+ {
+ cbreakt.c_cc[VMIN] = 1;
+ cbreakt.c_cc[VTIME] = 0;
+
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT : TCSANOW, curt) ? ERR : OK);
+ }
+
+ int
+ __nodelay()
+ {
+ cbreakt.c_cc[VMIN] = 0;
+ cbreakt.c_cc[VTIME] = 0;
+
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT : TCSANOW, curt) ? ERR : OK);
+ }
+
+ int
+ __timeout()
+ {
+ ovmin = cbreakt.c_cc[VMIN];
+ ovtime = cbreakt.c_cc[VTIME];
+ cbreakt.c_cc[VMIN] = 0;
+ cbreakt.c_cc[VTIME] = 2;
+
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSANOW : TCSANOW, curt) ? ERR : OK);
+ }
+
+ int
+ __notimeout()
+ {
+ cbreakt.c_cc[VMIN] = ovmin;
+ cbreakt.c_cc[VTIME] = ovtime;
+
+ return (tcsetattr(STDIN_FILENO, __tcaction ?
+ TCSASOFT | TCSANOW : TCSANOW, curt) ? ERR : OK);
+ }
+
+ int
echo()
{
rawt.c_lflag |= ECHO;
***************
*** 189,194 ****
--- 233,239 ----
TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK);
}
+
int
nl()
{
***************
*** 244,249 ****
--- 289,295 ----
tputs(TI, 0, __cputchar);
tputs(VS, 0, __cputchar);
+ tputs(KS, 0, __cputchar);
}
int
***************
*** 261,266 ****
--- 307,313 ----
(void)tputs(VE, 0, __cputchar);
(void)tputs(TE, 0, __cputchar);
+ (void)tputs(KE, 0, __cputchar);
(void)fflush(stdout);
(void)setvbuf(stdout, NULL, _IOLBF, 0);
Index: src/lib/libcurses/EXAMPLES/ex2.c
diff -c /dev/null src/lib/libcurses/EXAMPLES/ex2.c:1.1
*** /dev/null Tue Aug 12 11:12:47 1997
--- src/lib/libcurses/EXAMPLES/ex2.c Sun Aug 10 17:55:46 1997
***************
*** 0 ****
--- 1,110 ----
+ /*
+ * Test the function of the keypad, nodelay and notimeout functions.
+ * Follow the instructions printed out.
+ *
+ * $Log: ex2.c,v $
+ * Revision 1.1 1997/08/10 08:25:46 blymn
+ * New example file showing keypad, notimeout and nodelay functions.
+ *
+ *
+ */
+
+ #include <unistd.h>
+ #include <curses.h>
+
+ int
+ main(void)
+ {
+ WINDOW *term;
+ int i;
+ int key;
+ int padstate = FALSE;
+ int tostate = TRUE;
+ int delstate = FALSE;
+
+
+ term = initscr();
+ cbreak();
+ noecho();
+ mvprintw(1, 2, "Curses testing: press k to toggle keypad mode, q to quit");
+ mvprintw(2, 2, " press t to toggle timeout, d to toggle delay");
+ mvprintw(3, 2, " press other keys to see what happens");
+ refresh();
+
+ i = 6;
+ while ((key = getch()) != (int) 'q')
+ {
+ if (key < (int) ' ')
+ {
+ if (key == ERR)
+ {
+ mvprintw(i,2, "Got ERR back for key - sleeping for 1 second");
+ refresh();
+ sleep(1); /* don't go busy wait */
+ }
+ else
+ {
+ mvprintw(i,2, "Got non-printable key 0x%x", key);
+ }
+ }
+ else if (key < 256)
+ {
+ switch (key)
+ {
+ case 'd':
+ delstate = !delstate;
+ nodelay(stdscr, delstate);
+ mvprintw(i,2, "Nodelay is now %s\n", (delstate) ? "TRUE" : "FALSE");
+ break;
+
+ case 'k':
+ padstate = !padstate;
+ keypad(stdscr, padstate);
+ mvprintw(i,2, "Keypad is now %s\n", (padstate) ? "TRUE" : "FALSE");
+ break;
+
+ case 't':
+ tostate = !tostate;
+ notimeout(stdscr, tostate);
+ mvprintw(i,2, "Notimeout is now %s\n", (tostate) ? "TRUE" : "FALSE");
+ break;
+
+ default:
+ mvprintw(i,2, "Got key %c (0x%x)", (char) key, key);
+ break;
+ }
+ }
+ else
+ {
+ switch (key)
+ {
+ case KEY_UP:
+ mvprintw(i,2, "Got key_up");
+ break;
+
+ case KEY_DOWN:
+ mvprintw(i,2, "Got key_down");
+ break;
+
+ case KEY_LEFT:
+ mvprintw(i,2, "Got key_left");
+ break;
+
+ case KEY_RIGHT:
+ mvprintw(i,2, "Got key_right");
+ break;
+
+ default:
+ mvprintw(i,2, "Got keysym 0x%x", key);
+ break;
+ }
+ }
+
+ i++; i %= LINES; i = (i < 6) ? 6 : i;
+ move(i, 2); clrtoeol();
+ refresh();
+ }
+
+ endwin();
+ exit(0);
+ }
>Audit-Trail:
>Unformatted: