1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*	Copyright (c) 1988 AT&T	*/
28/*	  All Rights Reserved	*/
29
30/*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40#pragma ident	"%Z%%M%	%I%	%E% SMI"
41
42/*LINTLIBRARY*/
43
44#include	<sys/types.h>
45#include	<stdlib.h>
46#include	<string.h>
47#include	"curses_inc.h"
48
49static	short	keycodes[] = {
50		    KEY_BACKSPACE,
51		    KEY_CATAB,
52		    KEY_CLEAR,
53		    KEY_CTAB,
54		    KEY_DC,
55		    KEY_DL,
56		    KEY_DOWN,
57		    KEY_EIC,
58		    KEY_EOL,
59		    KEY_EOS,
60		    KEY_F(0),
61		    KEY_F(1),
62		    KEY_F(10),
63		    KEY_F(2),
64		    KEY_F(3),
65		    KEY_F(4),
66		    KEY_F(5),
67		    KEY_F(6),
68		    KEY_F(7),
69		    KEY_F(8),
70		    KEY_F(9),
71		    KEY_HOME,
72		    KEY_IC,
73		    KEY_IL,
74		    KEY_LEFT,
75		    KEY_LL,
76		    KEY_NPAGE,
77		    KEY_PPAGE,
78		    KEY_RIGHT,
79		    KEY_SF,
80		    KEY_SR,
81		    KEY_STAB,
82		    KEY_UP,
83		    KEY_A1,
84		    KEY_A3,
85		    KEY_B2,
86		    KEY_C1,
87		    KEY_C3,
88		    KEY_BTAB,
89		    KEY_BEG,
90		    KEY_CANCEL,
91		    KEY_CLOSE,
92		    KEY_COMMAND,
93		    KEY_COPY,
94		    KEY_CREATE,
95		    KEY_END,
96		    KEY_ENTER,
97		    KEY_EXIT,
98		    KEY_FIND,
99		    KEY_HELP,
100		    KEY_MARK,
101		    KEY_MESSAGE,
102		    KEY_MOVE,
103		    KEY_NEXT,
104		    KEY_OPEN,
105		    KEY_OPTIONS,
106		    KEY_PREVIOUS,
107		    KEY_PRINT,
108		    KEY_REDO,
109		    KEY_REFERENCE,
110		    KEY_REFRESH,
111		    KEY_REPLACE,
112		    KEY_RESTART,
113		    KEY_RESUME,
114		    KEY_SAVE,
115		    KEY_SUSPEND,
116		    KEY_UNDO,
117		    KEY_SBEG,
118		    KEY_SCANCEL,
119		    KEY_SCOMMAND,
120		    KEY_SCOPY,
121		    KEY_SCREATE,
122		    KEY_SDC,
123		    KEY_SDL,
124		    KEY_SELECT,
125		    KEY_SEND,
126		    KEY_SEOL,
127		    KEY_SEXIT,
128		    KEY_SFIND,
129		    KEY_SHELP,
130		    KEY_SHOME,
131		    KEY_SIC,
132		    KEY_SLEFT,
133		    KEY_SMESSAGE,
134		    KEY_SMOVE,
135		    KEY_SNEXT,
136		    KEY_SOPTIONS,
137		    KEY_SPREVIOUS,
138		    KEY_SPRINT,
139		    KEY_SREDO,
140		    KEY_SREPLACE,
141		    KEY_SRIGHT,
142		    KEY_SRSUME,
143		    KEY_SSAVE,
144		    KEY_SSUSPEND,
145		    KEY_SUNDO,
146		    KEY_MOUSE
147		};
148
149static	_KEY_MAP	*p;
150static	bool		*funckey;
151static	short		*codeptr;
152
153static	void
154_laddone(char *txt)
155{
156	p->_sends = (txt);
157	p->_keyval = *codeptr;
158	funckey[(unsigned char)(txt)[0]] |= _KEY;
159	p++;
160}
161
162/* Map text into num, updating the map structure p. */
163
164static	void
165_keyfunc(char **keyptr, char **lastkey)
166{
167	for (; keyptr <= lastkey; keyptr++, codeptr++)
168		if (*keyptr) {
169			p->_sends = (*keyptr);
170			p->_keyval = *codeptr;
171			funckey[(unsigned char)(*keyptr)[0]] |= _KEY;
172			p++;
173		}
174}
175
176/* Map text into num, updating the map structure p. */
177
178static	void
179_keyfunc2(char **keyptr, char **lastkey)
180{
181	short code_value = KEY_F(11);
182
183	for (; *keyptr && keyptr <= lastkey; keyptr++, code_value++) {
184		p->_sends = *keyptr;
185		p->_keyval = (short) code_value;
186		funckey[(unsigned char)*keyptr[0]] |= _KEY;
187		p++;
188	}
189}
190
191int
192setkeymap(void)
193{
194	_KEY_MAP	keymap[((sizeof (keycodes) / sizeof (short)) +
195			    ((KEY_F(63) - KEY_F(11)) + 1))], **key_ptrs;
196	short		numkeys;
197	int		numbytes, key_size = cur_term->_ksz;
198
199	if (cur_term->internal_keys != NULL)
200		return (ERR);
201	p = keymap;
202	codeptr = keycodes;
203	funckey = cur_term->funckeystarter;
204
205	/* If backspace key sends \b, don't map it. */
206	if (key_backspace && strcmp(key_backspace, "\b"))
207		_laddone(key_backspace);
208	codeptr++;
209
210	_keyfunc(&key_catab, &key_dl);
211
212	/* If down arrow key sends \n, don't map it. */
213	if (key_down && strcmp(key_down, "\n"))
214		_laddone(key_down);
215	codeptr++;
216
217	_keyfunc(&key_eic, &key_il);
218
219	/* If left arrow key sends \b, don't map it. */
220	if (key_left && strcmp(key_left, "\b"))
221		_laddone(key_left);
222	codeptr++;
223
224	_keyfunc(&key_ll, &key_up);
225	_keyfunc(&key_a1, &key_c3);
226	_keyfunc(&key_btab, &key_btab);
227	_keyfunc(&key_beg, &key_sundo);
228	_keyfunc2(&key_f11, &key_f63);
229	_keyfunc(&key_mouse, &key_mouse);
230
231	/*
232	 * malloc returns the address of a list of pointers to
233	 * (_KEY_MAP *) structures
234	 */
235
236	if ((key_ptrs = (_KEY_MAP **)
237	    /* LINTED */
238	    malloc((key_size + (numkeys = (short)(p - keymap))) *
239	    sizeof (_KEY_MAP *))) == NULL) {
240		goto out;
241	}
242
243	/*
244	 * Number of bytes needed is the number of structures times their size
245	 * malloc room for our array of _KEY_MAP structures
246	 */
247
248	if ((p = (_KEY_MAP *) malloc((unsigned)
249	    /* LINTED */
250	    (numbytes = (int)(sizeof (_KEY_MAP) * numkeys)))) == NULL) {
251		/* Can't do it, free list of pointers, indicate */
252		/* error upon return. */
253		free((char *) key_ptrs);
254out:
255		term_errno = TERM_BAD_MALLOC;
256#ifdef	DEBUG
257		strcpy(term_parm_err, "setkeymap");
258		termerr();
259#endif	/* DEBUG */
260		return (ERR);
261	}
262
263	if (key_size != 0) {
264		(void) memcpy((char *) &(key_ptrs[numkeys]),
265		    (char *) cur_term->_keys, (key_size *
266		    sizeof (_KEY_MAP *)));
267		free(cur_term->_keys);
268	}
269	(void) memcpy((char *) (cur_term->internal_keys = p),
270	    (char *) keymap, numbytes);
271	cur_term->_keys = key_ptrs;
272	cur_term->_ksz += numkeys;
273	/*
274	 * Reset _lastkey_ordered to -1 since we put the keys read in
275	 * from terminfo at the beginning of the keys table.
276	 */
277	cur_term->_lastkey_ordered = -1;
278	cur_term->_lastmacro_ordered += numkeys;
279	cur_term->_first_macro += numkeys;
280
281	/* Initialize our pointers to the structures */
282	while (numkeys--)
283		*key_ptrs++ = p++;
284#ifdef	DEBUG
285	if (outf)
286		fprintf(outf, "return key structure %x, ending at %x\n",
287		    keymap, p);
288#endif	/* DEBUG */
289	return (OK);
290}
291