2 * ========================================================================
3 * Copyright 2006-2007 University of Washington
4 * Copyright 2013-2022 Eduardo Chappa
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
18 #include "../estruct.h"
23 #include "../keydefs.h"
32 static int MapMSKEYtoPK(int c
);
36 /* internal declarations */
39 /* these next two are declared in pith/conf.h */
41 set_input_timeout(int t
)
50 get_input_timeout(void)
59 /* internal prototypes */
68 sleep(30); /* see if os receives SIGHUP */
69 kill(getpid(), SIGHUP
); /* eof or bad error */
75 * typahead - Check to see if any characters are already in the
81 int x
; /* holds # of pending chars */
83 return((ioctl(0,FIONREAD
,&x
) < 0) ? 0 : x
);
90 * ReadyForKey - return true if there's no timeout or we're told input
94 ReadyForKey(int timeout
)
96 switch(input_ready(timeout
)){
108 emlwwrite(_("Problem reading from keyboard!"), NULL
);
109 kill(getpid(), SIGHUP
); /* Bomb out (saving our work)! */
120 * GetKey - Read in a key.
121 * Do the standard keyboard preprocessing. Convert the keys to the internal
122 * character set. Resolves escape sequences and returns no-op if global
123 * timeout value exceeded.
130 if(!ReadyForKey(FUDGE
-5))
133 switch(status
= kbseq(simple_ttgetc
, NULL
, bail
, input_cs
, &ch
)){
134 case 0: /* regular character */
139 * Special hack to get around comm devices eating control characters.
142 return(BADESC
); /* user typed ESC ESC, then stopped */
144 switch(status
= kbseq(simple_ttgetc
, NULL
, bail
, input_cs
, &ch
)){
166 return(CTRL
| status
);
169 case 0: /* regular character */
172 default: /* punt the whole thing */
179 if(isdigit((unsigned char)ch
)){
180 int n
= 0, i
= ch
- '0';
183 return(BADESC
); /* bogus literal char value */
187 || (!isdigit((unsigned char) (ch
=
188 (*term
.t_getchar
)(NODATA
, NULL
, bail
)))
189 || (n
== 1 && i
== 2 && ch
> '5')
190 || (n
== 2 && i
== 25 && ch
> '5'))){
194 i
= (i
* 10) + (ch
- '0');
200 if(islower((unsigned char)ch
)) /* canonicalize if alpha */
201 ch
= toupper((unsigned char)ch
);
203 return((isalpha((unsigned char)ch
) || ch
== '@'
204 || (ch
>= '[' && ch
<= '_'))
205 ? (CTRL
| ch
) : ((ch
== ' ') ? (CTRL
| '@') : ch
));
211 case KEY_XTERM_MOUSE
:
214 * Special hack to get mouse events from an xterm.
215 * Get the details, then pass it past the keymenu event
216 * handler, and then to the installed handler if there
223 button
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) & 0x03;
225 x
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) - '!';
226 y
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) - '!';
230 if(checkmouse(&cmd
, 1, x
, y
))
233 else if(down
&& button
== 3){
235 if(checkmouse(&cmd
, 0, x
, y
))
269 return(CTRL
| KEY_UP
);
271 return(CTRL
| KEY_DOWN
);
272 case CTRL_KEY_RIGHT
:
273 return(CTRL
| KEY_RIGHT
);
275 return(CTRL
| KEY_LEFT
);
288 while(!strchr("~qz", (*term
.t_getchar
)(NODATA
, NULL
, bail
)));
290 return((status
== BADESC
)
292 : status
- (KEY_SWAL_UP
- KEY_UP
));
301 ch
= (*term
.t_getchar
)(NODATA
, NULL
, bail
) & 0x7f;
302 }while(cc
!= '\033' && ch
!= '\\');
311 default: /* punt the whole thing */
316 if (ch
>= 0x00 && ch
<= 0x1F) /* C0 control -> C- */
317 ch
= CTRL
| (ch
+'@');
324 * kbseq - looks at an escape sequence coming from the keyboard and
325 * compares it to a trie of known keyboard escape sequences, and
326 * returns the function bound to the escape sequence.
328 * Args: getcfunc -- Function to get a single character from stdin,
329 * called with the next two arguments to this
330 * function as its arguments.
331 * recorder -- If non-NULL, function used to record keystroke.
332 * bail_handler -- Function used to bail out on read error.
333 * c -- Pointer to returned character.
336 * The escaped function.
337 * 0 if a regular char with char stuffed in location c.
340 kbseq(int (*getcfunc
)(int (*recorder
)(int ), void (*bail_handler
)(void )),
341 int (*recorder
)(int),
342 void (*bail_handler
)(void),
351 if(current
== NULL
) /* bag it */
355 c
= (*getcfunc
)(recorder
, bail_handler
);
357 while(current
->value
!= c
){
358 if(current
->left
== NULL
){ /* NO MATCH */
360 unsigned long octets_so_far
, remaining_octets
;
361 unsigned char *inputp
;
363 unsigned char inputbuf
[20];
367 * Read enough bytes to make up a character and convert it to UCS-4.
369 memset(inputbuf
, 0, sizeof(inputbuf
));
373 remaining_octets
= octets_so_far
;
375 ucs
= mbtow(data
, &inputp
, &remaining_octets
);
379 * Not really a BADESC but that ought to
380 * be sufficient. We can add another type if
386 if(octets_so_far
>= sizeof(inputbuf
))
389 c
= (*getcfunc
)(recorder
, bail_handler
);
390 inputbuf
[octets_so_far
++] = c
;
394 /* got a good UCS-4 character */
406 current
= current
->left
;
409 if(current
->down
== NULL
) /* match!!!*/
410 return(current
->func
);
412 current
= current
->down
;
419 #define newnode() (KBESC_T *)malloc(sizeof(KBESC_T))
422 * kpinsert - insert a keystroke escape sequence into the global search
426 kpinsert(char *kstr
, int kval
, int termcap_wins
)
429 register KBESC_T
*temp
;
430 register KBESC_T
*trail
;
436 * Don't allow escape sequences that don't start with ESC unless
437 * termcap_wins. This is to protect against mistakes in termcap files.
439 if(!termcap_wins
&& *kstr
!= '\033')
442 temp
= trail
= kbesc
;
457 else{ /* first entry */
458 while((temp
!= NULL
) && (temp
->value
!= *buf
)){
463 if(temp
== NULL
){ /* add new val */
477 * Ignore attempt to overwrite shorter existing escape sequence.
478 * That means that sequences with higher priority should be
479 * set up first, so if we want termcap sequences to override
480 * hardwired sequences, put the kpinsert calls for the
481 * termcap sequences first. (That's what you get if you define
493 * Ignore attempt to overwrite longer sequences we are a prefix
494 * of (down != NULL) and exact same sequence (func != 0).
496 if(temp
!= NULL
&& temp
->down
== NULL
&& temp
->func
== 0)
503 * kbdestroy() - kills the key pad function key search tree
504 * and frees all lines associated with it
506 * Should be called with arg kbesc, the top of the tree.
509 kbdestroy(KBESC_T
*kb
)
523 * Do the standard keyboard preprocessing. Convert the keys to the internal
524 * character set. Resolves escape sequences and returns no-op if global
525 * timeout value exceeded.
538 * Main character processing loop.
540 while(!mswin_charavail()) {
543 /* Check Mouse. If we get a mouse event, convert to char
544 * event and return that. */
545 if (checkmouse (&ch
,0,0,0)) {
546 curwp
->w_flag
|= WFHARD
;
553 if(time(0L) >= timein
+(FUDGE
-10))
558 return (mswin_getc_fast());
561 #endif /* _WINDOWS */