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 (c) 1995-1998 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 /* LINTLIBRARY */
28 
29 /*
30  * keypad.c
31  *
32  * XCurses Library
33  *
34  * Copyright 1990, 1995 by Mortice Kern Systems Inc.  All rights reserved.
35  *
36  */
37 
38 #ifdef M_RCSID
39 #ifndef lint
40 static char rcsID[] =
41 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/"
42 "libxcurses/src/libc/xcurses/rcs/keypad.c 1.6 1998/06/03 12:56:59 "
43 "cbates Exp $";
44 #endif
45 #endif
46 
47 #include <private.h>
48 #include <stdlib.h>
49 
50 /*
51  * Add a function key string to the decode tree.
52  * Return -1 on error, else the length of the key sequence.
53  */
54 static int
decode_add(t_decode ** root,const char * str,short code)55 decode_add(t_decode **root, const char *str, short code)
56 {
57 	const char	*start;
58 	t_decode	*node, *saved;
59 
60 	if (root == NULL)
61 		return (-1);
62 
63 	if (str == NULL)
64 		return (0);
65 
66 	start = str;
67 	saved = NULL;
68 
69 	if (*root == NULL) {
70 		/* First node of tree. */
71 		node = (t_decode *) malloc(sizeof (*node));
72 		if (node == NULL)
73 			return (-1);
74 
75 		*root = saved = node;
76 
77 		node->child = node->sibling = NULL;
78 		node->ch = *str++;
79 		node->key = 0;
80 	} else {
81 		/* Find node to insert function key sequence into the tree. */
82 		for (node = *root; *str != '\0'; ++str, node = node->child) {
83 			while (node->ch != *str &&
84 				node->sibling != NULL)
85 				node = node->sibling;
86 
87 			if (node->ch != *str) {
88 				node->sibling = (t_decode *)
89 					malloc(sizeof (*node));
90 				if (node->sibling == NULL)
91 					return (-1);
92 
93 				saved = node = node->sibling;
94 				node->child = node->sibling = NULL;
95 				node->ch = *str++;
96 				node->key = 0;
97 				break;
98 			}
99 
100 			if (node->child == NULL)
101 				break;
102 		}
103 	}
104 
105 	/* Insert string into the tree; node->child == null. */
106 	while (*str != '\0') {
107 		node->child = (t_decode *) malloc(sizeof (*node));
108 		if (node->child == NULL) {
109 			__m_decode_free(&saved);
110 			return (-1);
111 		}
112 
113 		node = node->child;
114 		node->child = node->sibling = NULL;
115 		node->ch = *str++;
116 		node->key = 0;
117 	}
118 
119 	node->key = code;
120 
121 	/* (str - start) should be enough small to fit in "int" */
122 	return ((int)(str - start));
123 }
124 
125 
126 void
__m_decode_free(t_decode ** tree)127 __m_decode_free(t_decode **tree)
128 {
129 	if (*tree != NULL) {
130 		__m_decode_free(&(*tree)->sibling);
131 		__m_decode_free(&(*tree)->child);
132 		free(*tree);
133 		*tree = NULL;
134 	}
135 }
136 
137 /*
138  * Initialise the function key decode tree.
139  */
140 int
__m_decode_init(t_decode ** tree)141 __m_decode_init(t_decode **tree)
142 {
143 	int	max, len;
144 	const short	(*p)[2];
145 
146 	*tree = NULL;
147 
148 	for (max = -1, p = __m_keyindex; **p != -1; ++p) {
149 		len = decode_add(tree, cur_term->_str[**p], (*p)[1]);
150 		if (len < 0)
151 			return (-1);
152 		if (max < len)
153 			max = len;
154 	}
155 
156 	return (max);
157 }
158 
159 /*
160  * When true for a given window, then multibyte function key processing
161  * is done for all input throough that window, see wgetch().
162  */
163 int
keypad(WINDOW * w,bool bf)164 keypad(WINDOW *w, bool bf)
165 {
166 	if (bf) {
167 		if (keypad_xmit)
168 			(void) TPUTS(keypad_xmit, 1, __m_outc);
169 		w->_flags |= W_USE_KEYPAD;
170 	} else {
171 		if (keypad_local)
172 			(void) TPUTS(keypad_local, 1, __m_outc);
173 		w->_flags &= ~W_USE_KEYPAD;
174 	}
175 	return (OK);
176 }
177