xref: /titanic_44/usr/src/lib/libcurses/screen/tgetch.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
32*7c478bd9Sstevel@tonic-gate  * The Regents of the University of California
33*7c478bd9Sstevel@tonic-gate  * All Rights Reserved
34*7c478bd9Sstevel@tonic-gate  *
35*7c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
36*7c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
37*7c478bd9Sstevel@tonic-gate  * contributors.
38*7c478bd9Sstevel@tonic-gate  */
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include	"curses_inc.h"
45*7c478bd9Sstevel@tonic-gate #include	<signal.h>
46*7c478bd9Sstevel@tonic-gate #include	<unistd.h>
47*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
48*7c478bd9Sstevel@tonic-gate #include	<ctype.h>
49*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate  * Read a key typed from the terminal
53*7c478bd9Sstevel@tonic-gate  *
54*7c478bd9Sstevel@tonic-gate  * interpret:	= 0 for single-char key only
55*7c478bd9Sstevel@tonic-gate  * 		= 1 for matching function key and macro patterns.
56*7c478bd9Sstevel@tonic-gate  * 		= 2 same as 1 but no time-out for funckey matching.
57*7c478bd9Sstevel@tonic-gate  */
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate static	int _getkey(int, chtype *);
60*7c478bd9Sstevel@tonic-gate static	int _fpk(void);
61*7c478bd9Sstevel@tonic-gate static	int _pk(void);
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate chtype
64*7c478bd9Sstevel@tonic-gate tgetch(int interpret)
65*7c478bd9Sstevel@tonic-gate {
66*7c478bd9Sstevel@tonic-gate 	int		i = 0, j, collapse = 1;
67*7c478bd9Sstevel@tonic-gate #define	WAIT3		333
68*7c478bd9Sstevel@tonic-gate 	chtype		inp;
69*7c478bd9Sstevel@tonic-gate 	chtype		*inputQ = cur_term->_input_queue;
70*7c478bd9Sstevel@tonic-gate 	char		*chars_onQ = &(cur_term->_chars_on_queue);
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate #ifdef	SYSV
73*7c478bd9Sstevel@tonic-gate 	/*
74*7c478bd9Sstevel@tonic-gate 	 * Register the fact that getch is being used so
75*7c478bd9Sstevel@tonic-gate 	 * that typeahead checking can be done.
76*7c478bd9Sstevel@tonic-gate 	 * This code should GO AWAY when a poll() or FIONREAD can
77*7c478bd9Sstevel@tonic-gate 	 * be done on the file descriptor as then the check
78*7c478bd9Sstevel@tonic-gate 	 * will be non-destructive.
79*7c478bd9Sstevel@tonic-gate 	 */
80*7c478bd9Sstevel@tonic-gate 	cur_term->fl_typeahdok = TRUE;
81*7c478bd9Sstevel@tonic-gate #endif	/* SYSV */
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 	/* ask for input */
84*7c478bd9Sstevel@tonic-gate 	if (cur_term->_ungotten > 0) {
85*7c478bd9Sstevel@tonic-gate 		cur_term->_ungotten--;
86*7c478bd9Sstevel@tonic-gate 		/* decode an ungetch()'d character */
87*7c478bd9Sstevel@tonic-gate 		inp = -inputQ[0];
88*7c478bd9Sstevel@tonic-gate 	} else {
89*7c478bd9Sstevel@tonic-gate 		/* Only read a character if there is no typeahead/peekahead. */
90*7c478bd9Sstevel@tonic-gate 		if (*chars_onQ == 0) {
91*7c478bd9Sstevel@tonic-gate 			/* (*chars_onQ)++;  MR */
92*7c478bd9Sstevel@tonic-gate #ifdef	FIONREAD
93*7c478bd9Sstevel@tonic-gate 			inp = _readchar();
94*7c478bd9Sstevel@tonic-gate #else	/* FIONREAD */
95*7c478bd9Sstevel@tonic-gate 			inp = (chtype) _pk();
96*7c478bd9Sstevel@tonic-gate 			if ((int)inp == ERR) {
97*7c478bd9Sstevel@tonic-gate 		/*
98*7c478bd9Sstevel@tonic-gate 		 * interpret is set to 0 so that down below we don't
99*7c478bd9Sstevel@tonic-gate 		 * drop into getkey since we already know there can't be
100*7c478bd9Sstevel@tonic-gate 		 * a key that starts with -1.  Also, we don't want to
101*7c478bd9Sstevel@tonic-gate 		 * access funckeystarter[-1].
102*7c478bd9Sstevel@tonic-gate 		 */
103*7c478bd9Sstevel@tonic-gate 				interpret = FALSE;
104*7c478bd9Sstevel@tonic-gate 			}
105*7c478bd9Sstevel@tonic-gate #endif	/* FIONREAD */
106*7c478bd9Sstevel@tonic-gate 			(*chars_onQ)++;
107*7c478bd9Sstevel@tonic-gate 		} else
108*7c478bd9Sstevel@tonic-gate 			inp = inputQ[0];
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
111*7c478bd9Sstevel@tonic-gate 		if (outf)
112*7c478bd9Sstevel@tonic-gate 			fprintf(outf, "TGETCH read '%s'\n", unctrl(inp));
113*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 		/* Check for arrow and function keys */
116*7c478bd9Sstevel@tonic-gate 		if (interpret && cur_term->funckeystarter[inp])
117*7c478bd9Sstevel@tonic-gate 		    collapse = _getkey(interpret - 1, &inp);
118*7c478bd9Sstevel@tonic-gate 	}
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate 	/* Collapse the input queue to remove the escape */
121*7c478bd9Sstevel@tonic-gate 	/* sequence from the stack. */
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate 	j = *chars_onQ;
124*7c478bd9Sstevel@tonic-gate 	(*chars_onQ) -= collapse;
125*7c478bd9Sstevel@tonic-gate 	while (collapse < j)
126*7c478bd9Sstevel@tonic-gate 		inputQ[i++] = inputQ[collapse++];
127*7c478bd9Sstevel@tonic-gate 	return (inp);
128*7c478bd9Sstevel@tonic-gate }
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate #ifdef	FIONREAD
131*7c478bd9Sstevel@tonic-gate static	int
132*7c478bd9Sstevel@tonic-gate _readchar()
133*7c478bd9Sstevel@tonic-gate {
134*7c478bd9Sstevel@tonic-gate 	int		i;
135*7c478bd9Sstevel@tonic-gate 	unsigned	char	c;
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	if (cur_term->_delay == 0) {
138*7c478bd9Sstevel@tonic-gate 		int	arg;
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 		(void) ioctl(cur_term->_inputfd, FIONREAD, &arg);
141*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
142*7c478bd9Sstevel@tonic-gate 		if (outf)
143*7c478bd9Sstevel@tonic-gate 			fprintf(outf, "FIONREAD returns %d\n", arg);
144*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
145*7c478bd9Sstevel@tonic-gate 		if (arg < 1)
146*7c478bd9Sstevel@tonic-gate 			return (-1);
147*7c478bd9Sstevel@tonic-gate 	} else
148*7c478bd9Sstevel@tonic-gate 		if (cur_term->_delay > 0) {
149*7c478bd9Sstevel@tonic-gate 			char	c;
150*7c478bd9Sstevel@tonic-gate 			int	infd;
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 			infd = 1 << cur_term->_inputfd;
153*7c478bd9Sstevel@tonic-gate 			t.tv_sec = cur_term->_delay / 1000;
154*7c478bd9Sstevel@tonic-gate 			t.tv_usec = (cur_term->_delay % 1000) * 1000;
155*7c478bd9Sstevel@tonic-gate 			i = select(20, &infd, (int *)NULL, (int *)NULL, &t);
156*7c478bd9Sstevel@tonic-gate 			if (i < 0)
157*7c478bd9Sstevel@tonic-gate 				return (ERR);
158*7c478bd9Sstevel@tonic-gate 			i = read(cur_term->_inputfd, &c, 1);
159*7c478bd9Sstevel@tonic-gate 		} else
160*7c478bd9Sstevel@tonic-gate 			i = read(cur_term->_inputfd, &c, 1);
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
163*7c478bd9Sstevel@tonic-gate 	if (outf)
164*7c478bd9Sstevel@tonic-gate 		fprintf(outf, "read from %d returns %d chars, first %o\n",
165*7c478bd9Sstevel@tonic-gate 		    cur_term->_inputfd, i, c);
166*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	if (i > 0)
169*7c478bd9Sstevel@tonic-gate 		return (c);
170*7c478bd9Sstevel@tonic-gate 	else
171*7c478bd9Sstevel@tonic-gate 		return (ERR);
172*7c478bd9Sstevel@tonic-gate }
173*7c478bd9Sstevel@tonic-gate #endif	/* !FIONREAD */
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
176*7c478bd9Sstevel@tonic-gate extern	char	*_asciify();
177*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate /*
180*7c478bd9Sstevel@tonic-gate  * This algorithm is a "learning" algorithm. The premise is
181*7c478bd9Sstevel@tonic-gate  * that keys used once are like to be used again and again.
182*7c478bd9Sstevel@tonic-gate  * Since the time for a linear search of the table is so
183*7c478bd9Sstevel@tonic-gate  * expensive, we move keys that are found up to the top of
184*7c478bd9Sstevel@tonic-gate  * the list, making the access to a repeated key very fast and
185*7c478bd9Sstevel@tonic-gate  * keys that have been used before close to the top.
186*7c478bd9Sstevel@tonic-gate  */
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate static	int
189*7c478bd9Sstevel@tonic-gate _getkey(int blockpeek, chtype *inp)
190*7c478bd9Sstevel@tonic-gate {
191*7c478bd9Sstevel@tonic-gate 	_KEY_MAP	**kp = cur_term->_keys;
192*7c478bd9Sstevel@tonic-gate 	int		key, num_keys = cur_term->_ksz;
193*7c478bd9Sstevel@tonic-gate 	int		i;
194*7c478bd9Sstevel@tonic-gate 	chtype		*inputQ = cur_term->_input_queue;
195*7c478bd9Sstevel@tonic-gate 	char		*chars_onQ = &(cur_term->_chars_on_queue),
196*7c478bd9Sstevel@tonic-gate 			flag = cur_term->funckeystarter[*inp];
197*7c478bd9Sstevel@tonic-gate 	int		first, collapse = 1;
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
201*7c478bd9Sstevel@tonic-gate 	if (outf)
202*7c478bd9Sstevel@tonic-gate 		fprintf(outf, "getkey(): looking in linear table, "
203*7c478bd9Sstevel@tonic-gate 		    "inp=%d\n", *inp);
204*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 	if (flag & _KEY)
207*7c478bd9Sstevel@tonic-gate 		key = 0;
208*7c478bd9Sstevel@tonic-gate 	else {
209*7c478bd9Sstevel@tonic-gate 		key = cur_term->_first_macro;
210*7c478bd9Sstevel@tonic-gate 		blockpeek = TRUE;
211*7c478bd9Sstevel@tonic-gate 	}
212*7c478bd9Sstevel@tonic-gate 	first = key;
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 	for (; key < num_keys; key++) {
215*7c478bd9Sstevel@tonic-gate 		if (kp[key]->_sends[0] == *inp) {
216*7c478bd9Sstevel@tonic-gate 			for (i = 1; i < INP_QSIZE; i++) {
217*7c478bd9Sstevel@tonic-gate 				/* found it? */
218*7c478bd9Sstevel@tonic-gate 				if (kp[key]->_sends[i] == '\0')
219*7c478bd9Sstevel@tonic-gate 					break;
220*7c478bd9Sstevel@tonic-gate 				/* partial match? peek ahead. */
221*7c478bd9Sstevel@tonic-gate 				if (*chars_onQ == i) {
222*7c478bd9Sstevel@tonic-gate 					(*chars_onQ)++;
223*7c478bd9Sstevel@tonic-gate 					inputQ[i] = (blockpeek) ?
224*7c478bd9Sstevel@tonic-gate 						_pk() : _fpk();
225*7c478bd9Sstevel@tonic-gate 					switch ((int)inputQ[i]) {
226*7c478bd9Sstevel@tonic-gate 					case -2:
227*7c478bd9Sstevel@tonic-gate 			/*
228*7c478bd9Sstevel@tonic-gate 			 * Since -2 signifies a timeout we don't really
229*7c478bd9Sstevel@tonic-gate 			 * want to put it on the queue so we decrement
230*7c478bd9Sstevel@tonic-gate 			 * our counter.
231*7c478bd9Sstevel@tonic-gate 			 */
232*7c478bd9Sstevel@tonic-gate 						(*chars_onQ)--;
233*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
234*7c478bd9Sstevel@tonic-gate 					if (outf)
235*7c478bd9Sstevel@tonic-gate 						fprintf(outf, "Timed out\n");
236*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
237*7c478bd9Sstevel@tonic-gate 					if (flag & _MACRO) {
238*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
239*7c478bd9Sstevel@tonic-gate 						if (outf)
240*7c478bd9Sstevel@tonic-gate 							fprintf(outf,
241*7c478bd9Sstevel@tonic-gate 							    "Found macro\n");
242*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
243*7c478bd9Sstevel@tonic-gate 				/*
244*7c478bd9Sstevel@tonic-gate 				 * We have to decrement one because key will be
245*7c478bd9Sstevel@tonic-gate 				 * incremented at the bottom of the out loop.
246*7c478bd9Sstevel@tonic-gate 				 */
247*7c478bd9Sstevel@tonic-gate 						key = (first = blockpeek =
248*7c478bd9Sstevel@tonic-gate 						    cur_term->_first_macro) -
249*7c478bd9Sstevel@tonic-gate 						    1;
250*7c478bd9Sstevel@tonic-gate 						goto outerloop;
251*7c478bd9Sstevel@tonic-gate 					}
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 					/*FALLTHROUGH*/
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate 					case -1:
256*7c478bd9Sstevel@tonic-gate 						goto ret;
257*7c478bd9Sstevel@tonic-gate 					}
258*7c478bd9Sstevel@tonic-gate 				}
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate 				/* not this one? */
261*7c478bd9Sstevel@tonic-gate 				if (kp[key]->_sends[i] != inputQ[i])
262*7c478bd9Sstevel@tonic-gate 					goto outerloop;
263*7c478bd9Sstevel@tonic-gate 			}
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 			/* SS-mouse */
266*7c478bd9Sstevel@tonic-gate 			if (kp[key]->_keyval == KEY_MOUSE) {
267*7c478bd9Sstevel@tonic-gate 				MOUSE_STATUS old_mouse;
268*7c478bd9Sstevel@tonic-gate 				int rc;
269*7c478bd9Sstevel@tonic-gate 				static int get_xterm_mouse(int, int *);
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate 				old_mouse = Mouse_status;
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 				/* read the mouse status information	*/
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 				if (mouse_info)
276*7c478bd9Sstevel@tonic-gate 					rc = -3;	/* NOT IMPLEMENTED */
277*7c478bd9Sstevel@tonic-gate 				else
278*7c478bd9Sstevel@tonic-gate 					rc = get_xterm_mouse(blockpeek, &i);
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate 				if (rc == -1)		/* read error */
281*7c478bd9Sstevel@tonic-gate 					goto ret;
282*7c478bd9Sstevel@tonic-gate 				else if (rc == -2 || rc == -3) /* timeout */
283*7c478bd9Sstevel@tonic-gate 							/* or not mouse */
284*7c478bd9Sstevel@tonic-gate 					goto outerloop;
285*7c478bd9Sstevel@tonic-gate 				else if (rc == 0) /* report mouse pos */
286*7c478bd9Sstevel@tonic-gate 					Mouse_status.changes |= 020;
287*7c478bd9Sstevel@tonic-gate 				else if (rc >= 1 && rc <= 3)
288*7c478bd9Sstevel@tonic-gate 					/* mouse button event */
289*7c478bd9Sstevel@tonic-gate 					Mouse_status.changes =
290*7c478bd9Sstevel@tonic-gate 					    (((MOUSE_X_POS != old_mouse.x ||
291*7c478bd9Sstevel@tonic-gate 					    MOUSE_Y_POS != old_mouse.y) << 3) |
292*7c478bd9Sstevel@tonic-gate 					    ((Mouse_status.button[2] !=
293*7c478bd9Sstevel@tonic-gate 					    old_mouse.button[2]) << 2) |
294*7c478bd9Sstevel@tonic-gate 					    ((Mouse_status.button[1] !=
295*7c478bd9Sstevel@tonic-gate 					    old_mouse.button[1]) << 1) |
296*7c478bd9Sstevel@tonic-gate 					    (Mouse_status.button[0] !=
297*7c478bd9Sstevel@tonic-gate 					    old_mouse.button[0]));
298*7c478bd9Sstevel@tonic-gate 			}
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 			/* We found it! Read in any chars left in _sends */
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 			if ((collapse = i) == INP_QSIZE)
303*7c478bd9Sstevel@tonic-gate 				for (; kp[key]->_sends[i]; i++)
304*7c478bd9Sstevel@tonic-gate 					(void) _fpk();
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 			/* move key to top of ordered list */
307*7c478bd9Sstevel@tonic-gate 			if (key != first) {
308*7c478bd9Sstevel@tonic-gate 				_KEY_MAP	*savekey = kp[key];
309*7c478bd9Sstevel@tonic-gate 				short		*lorder;
310*7c478bd9Sstevel@tonic-gate 				int		j;
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate 				if (key > cur_term->_first_macro)
313*7c478bd9Sstevel@tonic-gate 				lorder = &(cur_term->_lastmacro_ordered);
314*7c478bd9Sstevel@tonic-gate 				else
315*7c478bd9Sstevel@tonic-gate 					lorder = &(cur_term->_lastkey_ordered);
316*7c478bd9Sstevel@tonic-gate 		/*
317*7c478bd9Sstevel@tonic-gate 		 * If we're below the last ordered key, swap next unordered
318*7c478bd9Sstevel@tonic-gate 		 * key with this one and ripple from there.
319*7c478bd9Sstevel@tonic-gate 		 */
320*7c478bd9Sstevel@tonic-gate 				if (key > *lorder)
321*7c478bd9Sstevel@tonic-gate 					kp[key] = kp[(i = ++(*lorder))];
322*7c478bd9Sstevel@tonic-gate 				else
323*7c478bd9Sstevel@tonic-gate 					i = key;
324*7c478bd9Sstevel@tonic-gate 				/* ripple the ordered keys down */
325*7c478bd9Sstevel@tonic-gate 				for (j = i--; j > first; )
326*7c478bd9Sstevel@tonic-gate 					kp[j--] = kp[i--];
327*7c478bd9Sstevel@tonic-gate 				kp[first] = savekey;
328*7c478bd9Sstevel@tonic-gate 			}
329*7c478bd9Sstevel@tonic-gate 			*inp = kp[first]->_keyval;
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 			/*
332*7c478bd9Sstevel@tonic-gate 			 * SS-mouse support: if mouse button event
333*7c478bd9Sstevel@tonic-gate 			 * occured on top of the soft label, we may
334*7c478bd9Sstevel@tonic-gate 			 * have to return the function key corresponding
335*7c478bd9Sstevel@tonic-gate 			 * to that soft label
336*7c478bd9Sstevel@tonic-gate 			 */
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 			if (*inp == KEY_MOUSE && A_BUTTON_CHANGED &&
339*7c478bd9Sstevel@tonic-gate 			    (MOUSE_Y_POS == LINES) &&
340*7c478bd9Sstevel@tonic-gate 			    (SP->slk != (SLK_MAP *) NULL) &&
341*7c478bd9Sstevel@tonic-gate 			    (SP->_map_mbe_to_key  != 0)) {
342*7c478bd9Sstevel@tonic-gate 				static void _map_button(chtype *);
343*7c478bd9Sstevel@tonic-gate 				_map_button(inp);
344*7c478bd9Sstevel@tonic-gate 			}
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 			goto ret;
347*7c478bd9Sstevel@tonic-gate 		}
348*7c478bd9Sstevel@tonic-gate outerloop:
349*7c478bd9Sstevel@tonic-gate 		;
350*7c478bd9Sstevel@tonic-gate 	}
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate ret:
353*7c478bd9Sstevel@tonic-gate 	/* key not found */
354*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
355*7c478bd9Sstevel@tonic-gate 	if (outf)
356*7c478bd9Sstevel@tonic-gate 		if (key == num_keys)
357*7c478bd9Sstevel@tonic-gate 			fprintf(outf, "Did not match anything.\n");
358*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
359*7c478bd9Sstevel@tonic-gate 	return (collapse);
360*7c478bd9Sstevel@tonic-gate }
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate /* SS-mouse */
364*7c478bd9Sstevel@tonic-gate /* this function tries to read in information that follows KEY_MOUSE: */
365*7c478bd9Sstevel@tonic-gate /* the first character identifies what button is involved (1,2,or 3)  */
366*7c478bd9Sstevel@tonic-gate /* if the first character is 0, we are dealing with report_mouse_pos  */
367*7c478bd9Sstevel@tonic-gate /*
368*7c478bd9Sstevel@tonic-gate  *	The routine returns the following:
369*7c478bd9Sstevel@tonic-gate  *		-3:	not a mouse button event
370*7c478bd9Sstevel@tonic-gate  *		-2:	read timed out
371*7c478bd9Sstevel@tonic-gate  *		-1:	the read failed
372*7c478bd9Sstevel@tonic-gate  *		[0, 1, 2, 3] - the first character in the mouse event
373*7c478bd9Sstevel@tonic-gate  */
374*7c478bd9Sstevel@tonic-gate static int
375*7c478bd9Sstevel@tonic-gate get_xterm_mouse(int blockpeek, int *i)
376*7c478bd9Sstevel@tonic-gate {
377*7c478bd9Sstevel@tonic-gate 	chtype	*inputQ = cur_term->_input_queue;		/* ??? */
378*7c478bd9Sstevel@tonic-gate 	/* LINTED */
379*7c478bd9Sstevel@tonic-gate 	chtype	*chars_onQ = (chtype *) &(cur_term->_chars_on_queue);
380*7c478bd9Sstevel@tonic-gate 	int	j, mx, my;
381*7c478bd9Sstevel@tonic-gate 	int	char1, char2, c1, c2;
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate 	/* the first character should be 0, 1, 2, or 4	*/
384*7c478bd9Sstevel@tonic-gate 
385*7c478bd9Sstevel@tonic-gate 	char1 = (inputQ[(*i)++] = (blockpeek) ? _pk() : _fpk());
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 	/* read error or timeout	*/
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate 	if (char1 < 0)
390*7c478bd9Sstevel@tonic-gate 		return (char1);
391*7c478bd9Sstevel@tonic-gate 	(*chars_onQ)++;
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate 	if (char1 < '0' || char1 > '3')
394*7c478bd9Sstevel@tonic-gate 		return (-3);
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 	/* if the character is 1, 2, or 3 it must be followed by 	*/
397*7c478bd9Sstevel@tonic-gate 	/* P, R, C, D, or T						*/
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 	if (char1 != '0') {
400*7c478bd9Sstevel@tonic-gate 		char2 = (inputQ[(*i)++] = (blockpeek) ? _pk() : _fpk());
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 		if (char2 < 0)
403*7c478bd9Sstevel@tonic-gate 			return (char2);
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate 		(*chars_onQ)++;
406*7c478bd9Sstevel@tonic-gate 		if (char2 != 'P' && char2 != 'R' && char2 != 'C' &&
407*7c478bd9Sstevel@tonic-gate 		    char2 != 'D' && char2 != 'T')
408*7c478bd9Sstevel@tonic-gate 			return (-3);
409*7c478bd9Sstevel@tonic-gate 	}
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate 	/* read X  and Y coordinates of the mouse	*/
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 	for (j = 0; j < 2; j++) {
414*7c478bd9Sstevel@tonic-gate 		c1 = (inputQ[(*i)++] = (blockpeek) ? _pk() : _fpk());
415*7c478bd9Sstevel@tonic-gate 		if (c1 < 0)
416*7c478bd9Sstevel@tonic-gate 			return (c1);
417*7c478bd9Sstevel@tonic-gate 		(*chars_onQ)++;
418*7c478bd9Sstevel@tonic-gate 		if (c1 >= ' ' && c1 <= '~') {	/* ascii char */
419*7c478bd9Sstevel@tonic-gate 			if (j == 0)
420*7c478bd9Sstevel@tonic-gate 				mx = c1 - ' ';
421*7c478bd9Sstevel@tonic-gate 			else
422*7c478bd9Sstevel@tonic-gate 				my = c1 - ' ';
423*7c478bd9Sstevel@tonic-gate 		} else if (char1 == 01 || char1 == 02) {   /* ^A || ^B */
424*7c478bd9Sstevel@tonic-gate 			c2 = (inputQ[(*i)++] = (blockpeek) ? _pk() : _fpk());
425*7c478bd9Sstevel@tonic-gate 			if (c2 < 0)
426*7c478bd9Sstevel@tonic-gate 				return (c2);
427*7c478bd9Sstevel@tonic-gate 			(*chars_onQ)++;
428*7c478bd9Sstevel@tonic-gate 			if (c2 >= ' ' && c2 <= '~') {
429*7c478bd9Sstevel@tonic-gate 				if (j == 0)
430*7c478bd9Sstevel@tonic-gate 					mx = c1 * (c2 - ' ');
431*7c478bd9Sstevel@tonic-gate 				else
432*7c478bd9Sstevel@tonic-gate 					my = c1 * (c2 - ' ');
433*7c478bd9Sstevel@tonic-gate 			} else
434*7c478bd9Sstevel@tonic-gate 				return (-3);
435*7c478bd9Sstevel@tonic-gate 		} else
436*7c478bd9Sstevel@tonic-gate 			return (-3);
437*7c478bd9Sstevel@tonic-gate 	}
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 	/* read complete mouse event: update the Mouse_status structure */
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 	MOUSE_X_POS = mx;
442*7c478bd9Sstevel@tonic-gate 	MOUSE_Y_POS = my;
443*7c478bd9Sstevel@tonic-gate 	j = char1 - '0';
444*7c478bd9Sstevel@tonic-gate 	if (j != 0) {
445*7c478bd9Sstevel@tonic-gate 		switch (char2) {
446*7c478bd9Sstevel@tonic-gate 			case 'P':
447*7c478bd9Sstevel@tonic-gate 				BUTTON_STATUS(j) = BUTTON_PRESSED;
448*7c478bd9Sstevel@tonic-gate 				break;
449*7c478bd9Sstevel@tonic-gate 			case 'R':
450*7c478bd9Sstevel@tonic-gate 				BUTTON_STATUS(j) = BUTTON_RELEASED;
451*7c478bd9Sstevel@tonic-gate 				break;
452*7c478bd9Sstevel@tonic-gate 			case 'C':
453*7c478bd9Sstevel@tonic-gate 				BUTTON_STATUS(j) = BUTTON_CLICKED;
454*7c478bd9Sstevel@tonic-gate 				break;
455*7c478bd9Sstevel@tonic-gate 			case 'D':
456*7c478bd9Sstevel@tonic-gate 				BUTTON_STATUS(j) = BUTTON_DOUBLE_CLICKED;
457*7c478bd9Sstevel@tonic-gate 				break;
458*7c478bd9Sstevel@tonic-gate 			case 'T':
459*7c478bd9Sstevel@tonic-gate 				BUTTON_STATUS(j) = BUTTON_TRIPLE_CLICKED;
460*7c478bd9Sstevel@tonic-gate 				break;
461*7c478bd9Sstevel@tonic-gate 		}
462*7c478bd9Sstevel@tonic-gate 	}
463*7c478bd9Sstevel@tonic-gate 	return (j);
464*7c478bd9Sstevel@tonic-gate }
465*7c478bd9Sstevel@tonic-gate /* SS-mouse-end */
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate /*
469*7c478bd9Sstevel@tonic-gate  * Fast peek key.  Like getchar but if the right flags are set, times out
470*7c478bd9Sstevel@tonic-gate  * quickly if there is nothing waiting, returning -1.
471*7c478bd9Sstevel@tonic-gate  * f is an output stdio descriptor, we read from the fileno.
472*7c478bd9Sstevel@tonic-gate  * We wait for long enough for a terminal to send another character
473*7c478bd9Sstevel@tonic-gate  * (at 15cps repeat rate, this is 67 ms, I'm using 100ms to allow
474*7c478bd9Sstevel@tonic-gate  * a bit of a fudge factor) and time out more quickly.
475*7c478bd9Sstevel@tonic-gate  * -2 is returned if we time out, -1 is returned if interrupted, and the
476*7c478bd9Sstevel@tonic-gate  * character is returned otherwise.
477*7c478bd9Sstevel@tonic-gate  */
478*7c478bd9Sstevel@tonic-gate 
479*7c478bd9Sstevel@tonic-gate #ifndef	FIONREAD
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate /*
482*7c478bd9Sstevel@tonic-gate  * Traditional implementation.  The best resolution we have is 1 second,
483*7c478bd9Sstevel@tonic-gate  * so we set a 1 second alarm and try to read.  If we fail for 1 second,
484*7c478bd9Sstevel@tonic-gate  * we assume there is no key waiting.  Problem here is that 1 second is
485*7c478bd9Sstevel@tonic-gate  * too long; people can type faster than this.
486*7c478bd9Sstevel@tonic-gate  *
487*7c478bd9Sstevel@tonic-gate  * Another possible implementation of changing VMIN/VTIME before and
488*7c478bd9Sstevel@tonic-gate  * after each read does not work because the tty driver's timeout
489*7c478bd9Sstevel@tonic-gate  * mechanism is too unreliable when the timeouts are changed too quickly.
490*7c478bd9Sstevel@tonic-gate  */
491*7c478bd9Sstevel@tonic-gate 
492*7c478bd9Sstevel@tonic-gate static	char	sig_caught;
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate static
495*7c478bd9Sstevel@tonic-gate #ifdef	SIGPOLL	/* Vr3 and beyond */
496*7c478bd9Sstevel@tonic-gate void
497*7c478bd9Sstevel@tonic-gate #endif  /* SIGPOLL */
498*7c478bd9Sstevel@tonic-gate /* The following line causes a lint warning for "dummy" which is not used. */
499*7c478bd9Sstevel@tonic-gate _catch_alarm(int dummy)
500*7c478bd9Sstevel@tonic-gate {
501*7c478bd9Sstevel@tonic-gate 	sig_caught = 1;
502*7c478bd9Sstevel@tonic-gate }
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate static int
505*7c478bd9Sstevel@tonic-gate _fpk(void)
506*7c478bd9Sstevel@tonic-gate {
507*7c478bd9Sstevel@tonic-gate 	unsigned	char	c;
508*7c478bd9Sstevel@tonic-gate 	int		infd = cur_term->_inputfd;
509*7c478bd9Sstevel@tonic-gate 	ssize_t		rc;
510*7c478bd9Sstevel@tonic-gate #ifdef	SIGPOLL	/* Vr3 and beyond */
511*7c478bd9Sstevel@tonic-gate 	void	(*oldsig)(int);
512*7c478bd9Sstevel@tonic-gate #else	/* SIGPOLL */
513*7c478bd9Sstevel@tonic-gate 	int		(*oldsig)(int);
514*7c478bd9Sstevel@tonic-gate #endif	/* SIGPOLL */
515*7c478bd9Sstevel@tonic-gate 	unsigned	int	oldalarm, alarm(unsigned);
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 	/* turn off any user alarms and set our own */
518*7c478bd9Sstevel@tonic-gate 	oldalarm = alarm(0);
519*7c478bd9Sstevel@tonic-gate 	sig_caught = 0;
520*7c478bd9Sstevel@tonic-gate 	oldsig = signal(SIGALRM, _catch_alarm);
521*7c478bd9Sstevel@tonic-gate 	(void) alarm(1);
522*7c478bd9Sstevel@tonic-gate 	rc = read(cur_term->_inputfd, (char *)&c, 1);
523*7c478bd9Sstevel@tonic-gate 	(void) alarm(0);
524*7c478bd9Sstevel@tonic-gate 
525*7c478bd9Sstevel@tonic-gate 	/*
526*7c478bd9Sstevel@tonic-gate 	 * This code is to take care of the possibility of
527*7c478bd9Sstevel@tonic-gate 	 * the process getting swapped out in the middle of
528*7c478bd9Sstevel@tonic-gate 	 * read() call above. The interrupt will cause the
529*7c478bd9Sstevel@tonic-gate 	 * read() call to retur, even if a character is really
530*7c478bd9Sstevel@tonic-gate 	 * on the clist. So we do a non-blocking read() to make
531*7c478bd9Sstevel@tonic-gate 	 * sure that there really isn't a character there.
532*7c478bd9Sstevel@tonic-gate 	 */
533*7c478bd9Sstevel@tonic-gate 
534*7c478bd9Sstevel@tonic-gate 	if (sig_caught && rc != 1)
535*7c478bd9Sstevel@tonic-gate 		if (cur_term->_check_fd != -1)
536*7c478bd9Sstevel@tonic-gate 			rc = read(cur_term->_check_fd, (char *)&c, 1);
537*7c478bd9Sstevel@tonic-gate 		else {
538*7c478bd9Sstevel@tonic-gate #include	<fcntl.h>
539*7c478bd9Sstevel@tonic-gate 			int	fcflags = fcntl(infd, F_GETFL, 0);
540*7c478bd9Sstevel@tonic-gate 
541*7c478bd9Sstevel@tonic-gate 			(void) fcntl(infd, F_SETFL, fcflags | O_NDELAY);
542*7c478bd9Sstevel@tonic-gate 			rc = read(infd, (char *)&c, 1);
543*7c478bd9Sstevel@tonic-gate 			(void) fcntl(infd, F_SETFL, fcflags);
544*7c478bd9Sstevel@tonic-gate 		}
545*7c478bd9Sstevel@tonic-gate 
546*7c478bd9Sstevel@tonic-gate 	/* restore the user alarms */
547*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGALRM, oldsig);
548*7c478bd9Sstevel@tonic-gate 	if (sig_caught && oldalarm > 1)
549*7c478bd9Sstevel@tonic-gate 	    oldalarm--;
550*7c478bd9Sstevel@tonic-gate 	(void) alarm(oldalarm);
551*7c478bd9Sstevel@tonic-gate 	if (rc == 1)			/* got a character */
552*7c478bd9Sstevel@tonic-gate 	    return (c);
553*7c478bd9Sstevel@tonic-gate 	else
554*7c478bd9Sstevel@tonic-gate 	    if (sig_caught)		/* timed out */
555*7c478bd9Sstevel@tonic-gate 		return (-2);
556*7c478bd9Sstevel@tonic-gate 	    else			/* EOF or got interrupted */
557*7c478bd9Sstevel@tonic-gate 		return (-1);
558*7c478bd9Sstevel@tonic-gate }
559*7c478bd9Sstevel@tonic-gate #else	/* FIONREAD */
560*7c478bd9Sstevel@tonic-gate /*
561*7c478bd9Sstevel@tonic-gate  * If we have the select system call, we can do much better than the
562*7c478bd9Sstevel@tonic-gate  * traditional method. Even if we don't have the real 4.2BSD select, we
563*7c478bd9Sstevel@tonic-gate  * can emulate it with napms and FIONREAD.  napms might be done with only
564*7c478bd9Sstevel@tonic-gate  * 1 second resolution, but this is no worse than what we have in the
565*7c478bd9Sstevel@tonic-gate  * traditional implementation.
566*7c478bd9Sstevel@tonic-gate  */
567*7c478bd9Sstevel@tonic-gate static
568*7c478bd9Sstevel@tonic-gate _fpk()
569*7c478bd9Sstevel@tonic-gate {
570*7c478bd9Sstevel@tonic-gate 	int		infd, rc;
571*7c478bd9Sstevel@tonic-gate 	int		*outfd, *exfd;
572*7c478bd9Sstevel@tonic-gate 	unsigned	char	c;
573*7c478bd9Sstevel@tonic-gate 	struct timeval	t;
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 	infd = 1 << cur_term->_inputfd;
576*7c478bd9Sstevel@tonic-gate 	outfd = exfd = (int *)NULL;
577*7c478bd9Sstevel@tonic-gate 	t.tv_sec = 0;
578*7c478bd9Sstevel@tonic-gate 	t.tv_usec = 100000;		/* 100 milliseconds */
579*7c478bd9Sstevel@tonic-gate 	rc = select(20, &infd, outfd, exfd, &t);
580*7c478bd9Sstevel@tonic-gate 	if (rc < 0)
581*7c478bd9Sstevel@tonic-gate 		return (-2);
582*7c478bd9Sstevel@tonic-gate 	rc = read(fileno(f), &c, 1);
583*7c478bd9Sstevel@tonic-gate 	return (rc == 1 ? c : -1);
584*7c478bd9Sstevel@tonic-gate }
585*7c478bd9Sstevel@tonic-gate #endif	/* FIONREAD */
586*7c478bd9Sstevel@tonic-gate 
587*7c478bd9Sstevel@tonic-gate /*
588*7c478bd9Sstevel@tonic-gate  * Plain peekchar function.  Nothing fancy.  This is just like _fpk
589*7c478bd9Sstevel@tonic-gate  * but will wait forever rather than time out.
590*7c478bd9Sstevel@tonic-gate  */
591*7c478bd9Sstevel@tonic-gate 
592*7c478bd9Sstevel@tonic-gate static int
593*7c478bd9Sstevel@tonic-gate _pk(void)
594*7c478bd9Sstevel@tonic-gate {
595*7c478bd9Sstevel@tonic-gate 	unsigned	char	c;
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 	return ((read(cur_term->_inputfd, (char *)&c, 1) == 1) ? c : ERR);
598*7c478bd9Sstevel@tonic-gate }
599*7c478bd9Sstevel@tonic-gate 
600*7c478bd9Sstevel@tonic-gate 
601*7c478bd9Sstevel@tonic-gate /*
602*7c478bd9Sstevel@tonic-gate  * SS-mouse: check if this mouse button event should map into
603*7c478bd9Sstevel@tonic-gate  * function key
604*7c478bd9Sstevel@tonic-gate  */
605*7c478bd9Sstevel@tonic-gate 
606*7c478bd9Sstevel@tonic-gate 
607*7c478bd9Sstevel@tonic-gate static void
608*7c478bd9Sstevel@tonic-gate _map_button(chtype *inp)
609*7c478bd9Sstevel@tonic-gate {
610*7c478bd9Sstevel@tonic-gate 	SLK_MAP *slk = SP->slk;
611*7c478bd9Sstevel@tonic-gate 	int num = slk->_num;
612*7c478bd9Sstevel@tonic-gate 	int len = slk->_len;
613*7c478bd9Sstevel@tonic-gate 	int i;
614*7c478bd9Sstevel@tonic-gate 
615*7c478bd9Sstevel@tonic-gate 	/* first determine if this mouse button event should be */
616*7c478bd9Sstevel@tonic-gate 	/* mapped into function key				*/
617*7c478bd9Sstevel@tonic-gate 
618*7c478bd9Sstevel@tonic-gate 	if (!(SP->_map_mbe_to_key &
619*7c478bd9Sstevel@tonic-gate 	    ((BUTTON_CHANGED(3) << (10 + BUTTON_STATUS(3))) |
620*7c478bd9Sstevel@tonic-gate 	    (BUTTON_CHANGED(2) << (5 + BUTTON_STATUS(2)))  |
621*7c478bd9Sstevel@tonic-gate 	    (BUTTON_CHANGED(1) << BUTTON_STATUS(1)))))
622*7c478bd9Sstevel@tonic-gate 		return;
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < num; i++) {
625*7c478bd9Sstevel@tonic-gate 		if (MOUSE_X_POS < slk->_labx[i])
626*7c478bd9Sstevel@tonic-gate 			break;
627*7c478bd9Sstevel@tonic-gate 		if (MOUSE_X_POS > slk->_labx[i] + len)
628*7c478bd9Sstevel@tonic-gate 			continue;
629*7c478bd9Sstevel@tonic-gate 		*inp = KEY_F(1) + i;
630*7c478bd9Sstevel@tonic-gate 		break;
631*7c478bd9Sstevel@tonic-gate 	}
632*7c478bd9Sstevel@tonic-gate }
633