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