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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /* LINTLIBRARY */
30 
31 /*
32  * unctrl.c
33  *
34  * XCurses Library
35  *
36  * Copyright 1990, 1995 by Mortice Kern Systems Inc.  All rights reserved.
37  *
38  */
39 
40 #if M_RCSID
41 #ifndef lint
42 static char rcsID[] =
43 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/"
44 "libxcurses/src/libc/xcurses/rcs/unctrl.c 1.3 1998/05/29 15:58:55 "
45 "cbates Exp $";
46 #endif
47 #endif
48 
49 #include <private.h>
50 #include <limits.h>
51 #include <ctype.h>
52 
53 static const char *carat[] = {
54 	"^?",
55 	"^@",
56 	"^A",
57 	"^B",
58 	"^C",
59 	"^D",
60 	"^E",
61 	"^F",
62 	"^G",
63 	"^H",
64 	"^I",
65 	"^J",
66 	"^K",
67 	"^L",
68 	"^M",
69 	"^N",
70 	"^O",
71 	"^P",
72 	"^Q",
73 	"^R",
74 	"^S",
75 	"^T",
76 	"^U",
77 	"^V",
78 	"^W",
79 	"^X",
80 	"^Y",
81 	"^Z",
82 	"^[",
83 	"^\\",
84 	"^]",
85 	"^^",
86 	"^_"
87 };
88 
89 char *
90 unctrl(chtype ch)
91 {
92 	char	*str;
93 	int	c, msb;
94 	static char	chr[5];
95 
96 
97 	/* Map wide character to a wide string. */
98 	c = (int)(ch & A_CHARTEXT);
99 	msb = 1 << (CHAR_BIT-1);
100 
101 	if (c & ~((1 << CHAR_BIT) - 1)) {
102 		/* Only know about single-byte characters I guess ... */
103 		return (NULL);
104 	}
105 	if (iscntrl(c)) {
106 		/* ASCII DEL */
107 		if (c == 127)
108 			return ((char *)carat[0]);
109 
110 		/* ASCII control codes. */
111 		if (0 <= c && c < 32)
112 			return ((char *)carat[c+1]);
113 
114 		/* Something we don't know what to do with. */
115 		return (NULL);
116 	} else if (c & msb) {
117 		/* Meta key notation if high bit is set on character. */
118 		c &= ~msb;
119 
120 		chr[0] = 'M';
121 		chr[1] = '-';
122 
123 		if (iscntrl(c)) {
124 			str = (char *) unctrl(c);
125 			chr[2] = *str++;
126 			chr[3] = *str;
127 			chr[4] = '\0';
128 		} else {
129 			chr[2] = (char)c;
130 			chr[3] = '\0';
131 		}
132 	} else {
133 		/* Return byte as is. */
134 		chr[0] = (char)c;
135 		chr[1] = '\0';
136 	}
137 
138 	return (chr);
139 }
140