1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: getkey.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2014 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
22 #include "../estruct.h"
27 #include "../keydefs.h"
36 static int MapMSKEYtoPK(int c
);
40 /* internal declarations */
43 /* these next two are declared in pith/conf.h */
45 set_input_timeout(int t
)
54 get_input_timeout(void)
63 /* internal prototypes */
72 sleep(30); /* see if os receives SIGHUP */
73 kill(getpid(), SIGHUP
); /* eof or bad error */
79 * typahead - Check to see if any characters are already in the
85 int x
; /* holds # of pending chars */
87 return((ioctl(0,FIONREAD
,&x
) < 0) ? 0 : x
);
94 * ReadyForKey - return true if there's no timeout or we're told input
98 ReadyForKey(int timeout
)
100 switch(input_ready(timeout
)){
112 emlwrite("\007Problem reading from keyboard!", NULL
);
113 kill(getpid(), SIGHUP
); /* Bomb out (saving our work)! */
124 * GetKey - Read in a key.
125 * Do the standard keyboard preprocessing. Convert the keys to the internal
126 * character set. Resolves escape sequences and returns no-op if global
127 * timeout value exceeded.
134 if(!ReadyForKey(FUDGE
-5))
137 switch(status
= kbseq(simple_ttgetc
, NULL
, bail
, input_cs
, &ch
)){
138 case 0: /* regular character */
143 * Special hack to get around comm devices eating control characters.
146 return(BADESC
); /* user typed ESC ESC, then stopped */
148 switch(status
= kbseq(simple_ttgetc
, NULL
, bail
, input_cs
, &ch
)){
170 return(CTRL
| status
);
173 case 0: /* regular character */
176 default: /* punt the whole thing */
183 if(isdigit((unsigned char)ch
)){
184 int n
= 0, i
= ch
- '0';
187 return(BADESC
); /* bogus literal char value */
191 || (!isdigit((unsigned char) (ch
=
192 (*term
.t_getchar
)(NODATA
, NULL
, bail
)))
193 || (n
== 1 && i
== 2 && ch
> '5')
194 || (n
== 2 && i
== 25 && ch
> '5'))){
198 i
= (i
* 10) + (ch
- '0');
204 if(islower((unsigned char)ch
)) /* canonicalize if alpha */
205 ch
= toupper((unsigned char)ch
);
207 return((isalpha((unsigned char)ch
) || ch
== '@'
208 || (ch
>= '[' && ch
<= '_'))
209 ? (CTRL
| ch
) : ((ch
== ' ') ? (CTRL
| '@') : ch
));
215 case KEY_XTERM_MOUSE
:
218 * Special hack to get mouse events from an xterm.
219 * Get the details, then pass it past the keymenu event
220 * handler, and then to the installed handler if there
227 button
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) & 0x03;
229 x
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) - '!';
230 y
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) - '!';
234 if(checkmouse(&cmd
, 1, x
, y
))
237 else if(down
&& button
== 3){
239 if(checkmouse(&cmd
, 0, x
, y
))
273 return(CTRL
| KEY_UP
);
275 return(CTRL
| KEY_DOWN
);
276 case CTRL_KEY_RIGHT
:
277 return(CTRL
| KEY_RIGHT
);
279 return(CTRL
| KEY_LEFT
);
292 while(!strchr("~qz", (*term
.t_getchar
)(NODATA
, NULL
, bail
)));
294 return((status
== BADESC
)
296 : status
- (KEY_SWAL_UP
- KEY_UP
));
305 ch
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) & 0x7f;
306 }while(cc
!= '\033' && ch
!= '\\');
315 default: /* punt the whole thing */
320 if (ch
>= 0x00 && ch
<= 0x1F) /* C0 control -> C- */
321 ch
= CTRL
| (ch
+'@');
328 * kbseq - looks at an escape sequence coming from the keyboard and
329 * compares it to a trie of known keyboard escape sequences, and
330 * returns the function bound to the escape sequence.
332 * Args: getcfunc -- Function to get a single character from stdin,
333 * called with the next two arguments to this
334 * function as its arguments.
335 * recorder -- If non-NULL, function used to record keystroke.
336 * bail_handler -- Function used to bail out on read error.
337 * c -- Pointer to returned character.
340 * The escaped function.
341 * 0 if a regular char with char stuffed in location c.
344 kbseq(int (*getcfunc
)(int (*recorder
)(int ), void (*bail_handler
)(void )),
345 int (*recorder
)(int),
346 void (*bail_handler
)(void),
355 if(current
== NULL
) /* bag it */
359 c
= (*getcfunc
)(recorder
, bail_handler
);
361 while(current
->value
!= c
){
362 if(current
->left
== NULL
){ /* NO MATCH */
364 unsigned long octets_so_far
, remaining_octets
;
365 unsigned char *inputp
;
367 unsigned char inputbuf
[20];
371 * Read enough bytes to make up a character and convert it to UCS-4.
373 memset(inputbuf
, 0, sizeof(inputbuf
));
377 remaining_octets
= octets_so_far
;
379 ucs
= mbtow(data
, &inputp
, &remaining_octets
);
383 * Not really a BADESC but that ought to
384 * be sufficient. We can add another type if
390 if(octets_so_far
>= sizeof(inputbuf
))
393 c
= (*getcfunc
)(recorder
, bail_handler
);
394 inputbuf
[octets_so_far
++] = c
;
398 /* got a good UCS-4 character */
410 current
= current
->left
;
413 if(current
->down
== NULL
) /* match!!!*/
414 return(current
->func
);
416 current
= current
->down
;
423 #define newnode() (KBESC_T *)malloc(sizeof(KBESC_T))
426 * kpinsert - insert a keystroke escape sequence into the global search
430 kpinsert(char *kstr
, int kval
, int termcap_wins
)
433 register KBESC_T
*temp
;
434 register KBESC_T
*trail
;
440 * Don't allow escape sequences that don't start with ESC unless
441 * termcap_wins. This is to protect against mistakes in termcap files.
443 if(!termcap_wins
&& *kstr
!= '\033')
446 temp
= trail
= kbesc
;
461 else{ /* first entry */
462 while((temp
!= NULL
) && (temp
->value
!= *buf
)){
467 if(temp
== NULL
){ /* add new val */
481 * Ignore attempt to overwrite shorter existing escape sequence.
482 * That means that sequences with higher priority should be
483 * set up first, so if we want termcap sequences to override
484 * hardwired sequences, put the kpinsert calls for the
485 * termcap sequences first. (That's what you get if you define
497 * Ignore attempt to overwrite longer sequences we are a prefix
498 * of (down != NULL) and exact same sequence (func != 0).
500 if(temp
!= NULL
&& temp
->down
== NULL
&& temp
->func
== 0)
507 * kbdestroy() - kills the key pad function key search tree
508 * and frees all lines associated with it
510 * Should be called with arg kbesc, the top of the tree.
513 kbdestroy(KBESC_T
*kb
)
527 * Do the standard keyboard preprocessing. Convert the keys to the internal
528 * character set. Resolves escape sequences and returns no-op if global
529 * timeout value exceeded.
542 * Main character processing loop.
544 while(!mswin_charavail()) {
547 /* Check Mouse. If we get a mouse event, convert to char
548 * event and return that. */
549 if (checkmouse (&ch
,0,0,0)) {
550 curwp
->w_flag
|= WFHARD
;
557 if(time(0L) >= timein
+(FUDGE
-10))
562 return (mswin_getc_fast());
565 #endif /* _WINDOWS */