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 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 #pragma ident "%Z%%M% %I% %E% SMI"
32
33 /* common mouse interface functions */
34
35 #include <stdio.h> /* NULL */
36 #include <stdlib.h> /* NULL */
37 #include <string.h> /* NULL */
38 #include <ctype.h> /* isdigit */
39 #include "global.h"
40
41 #define ctrl(x) (x & 037)
42
43 MOUSETYPE mouse;
44
45 static MOUSEMENU *loadedmenu;
46 static BOOL changemenu = YES;
47
48 /* see if there is a mouse interface */
49
50 void
initmouse(void)51 initmouse(void)
52 {
53 char *s, *term;
54
55 if ((term = getenv("TERM")) == NULL) {
56 return;
57 }
58 if (strcmp(term, "emacsterm") == 0 || strcmp(term, "viterm") == 0) {
59 mouse = EMACSTERM;
60 } else if ((s = getenv("MOUSE")) != NULL && strcmp(s, "myx") == 0) {
61 /*
62 * the MOUSE enviroment variable is for 5620 terminal
63 * programs that have mouse support but the TERM environment
64 * variable is the same as a terminal without a mouse, such
65 * as myx
66 */
67 mouse = MYX;
68 }
69 if ((s = getenv("MOUSEMENU")) != NULL && strcmp(s, "none") == 0) {
70 changemenu = NO;
71 }
72 initmenu();
73 }
74
75 /* reinitialize the mouse in case curses changed the attributes */
76
77 void
reinitmouse(void)78 reinitmouse(void)
79 {
80 if (mouse == EMACSTERM) {
81
82 /*
83 * enable the mouse click and sweep coordinate control
84 * sequence
85 */
86 (void) printf("\033{2");
87 if (changemenu) {
88 (void) printf("\033#2"); /* switch to menu 2 */
89 }
90 (void) fflush(stdout);
91 }
92 }
93
94 /* restore any original mouse attributes not handled by terminfo */
95
96 void
cleanupmouse(void)97 cleanupmouse(void)
98 {
99 int i;
100
101 if (mouse == MYX && loadedmenu != NULL) {
102 /* remove the mouse menu */
103 (void) printf("\033[6;0X\033[9;0X");
104 for (i = 0; loadedmenu[i].text != NULL; ++i) {
105 (void) printf("\033[0;0x");
106 }
107 loadedmenu = NULL;
108 }
109 }
110
111 /* download a mouse menu */
112
113 void
downloadmenu(MOUSEMENU * menu)114 downloadmenu(MOUSEMENU *menu)
115 {
116 int i;
117 int len;
118
119 switch (mouse) {
120 case EMACSTERM:
121 reinitmouse();
122 (void) printf("\033V1"); /* display the scroll bar */
123 if (changemenu) {
124 (void) printf("\033M0@%s@%s@", menu[0].text,
125 menu[0].value);
126 for (i = 1; menu[i].text != NULL; ++i) {
127 (void) printf("\033M@%s@%s@", menu[i].text,
128 menu[i].value);
129 }
130 }
131 (void) fflush(stdout);
132 break;
133 case MYX:
134 if (changemenu) {
135 cleanupmouse();
136 (void) printf("\033[6;1X\033[9;1X");
137 for (i = 0; menu[i].text != NULL; ++i) {
138 len = strlen(menu[i].text);
139 (void) printf("\033[%d;%dx%s%s", len,
140 len + strlen(menu[i].value),
141 menu[i].text, menu[i].value);
142 }
143 (void) fflush(stdout);
144 loadedmenu = menu;
145 }
146 break;
147 case NONE:
148 case PC7300:
149 break;
150 }
151 }
152
153 /* draw the scroll bar */
154
155 void
drawscrollbar(int top,int bot,int total)156 drawscrollbar(int top, int bot, int total)
157 {
158 int p1, p2;
159
160 if (mouse == EMACSTERM) {
161 if (bot > top && total > 0) {
162 p1 = 16 + (top - 1) * 100 / total;
163 p2 = 16 + (bot - 1) * 100 / total;
164 if (p2 > 116) {
165 p2 = 116;
166 }
167 if (p1 < 16) {
168 p1 = 16;
169 }
170 /*
171 * don't send ^S or ^Q to avoid hanging a layer using
172 * cu(1)
173 */
174 if (p1 == ctrl('Q') || p1 == ctrl('S')) {
175 ++p1;
176 }
177 if (p2 == ctrl('Q') || p2 == ctrl('S')) {
178 ++p2;
179 }
180 } else {
181 p1 = p2 = 16;
182 }
183 (void) printf("\033W%c%c", p1, p2);
184 }
185 }
186
187 /* translate a mouse click or sweep to a selection */
188
189 int
mouseselection(MOUSEEVENT * p,int offset,int maxselection)190 mouseselection(MOUSEEVENT *p, int offset, int maxselection)
191 {
192 int i;
193
194 i = p->y1 - offset;
195 if (i < 0) {
196 i = 0;
197 } else if (i >= maxselection) {
198 i = maxselection - 1;
199 }
200 return (i);
201 }
202
203 /* get the mouse event */
204
205 MOUSEEVENT *
getmouseevent(void)206 getmouseevent(void)
207 {
208 static MOUSEEVENT m;
209
210 if (mouse == EMACSTERM) {
211 switch (mygetch()) {
212 case ctrl('_'): /* click */
213 if ((m.button = mygetch()) == '0') { /* if scroll bar */
214 m.percent = getpercent();
215 } else {
216 m.x1 = getcoordinate();
217 m.y1 = getcoordinate();
218 m.x2 = m.y2 = -1;
219 }
220 break;
221
222 case ctrl(']'): /* sweep */
223 m.button = mygetch();
224 m.x1 = getcoordinate();
225 m.y1 = getcoordinate();
226 m.x2 = getcoordinate();
227 m.y2 = getcoordinate();
228 break;
229 default:
230 return (NULL);
231 }
232 return (&m);
233 }
234 return (NULL);
235 }
236
237 /* get a row or column coordinate from a mouse button click or sweep */
238
239 int
getcoordinate(void)240 getcoordinate(void)
241 {
242 int c, next;
243
244 c = mygetch();
245 next = 0;
246 if (c == ctrl('A')) {
247 next = 95;
248 c = mygetch();
249 }
250 if (c < ' ') {
251 return (0);
252 }
253 return (next + c - ' ');
254 }
255
256 /* get a percentage */
257
258 int
getpercent(void)259 getpercent(void)
260 {
261 int c;
262
263 c = mygetch();
264 if (c < 16) {
265 return (0);
266 }
267 if (c > 120) {
268 return (100);
269 }
270 return (c - 16);
271 }
272
273 /* update the window label area */
274
275 int
labelarea(char * s)276 labelarea(char *s)
277 {
278 static BOOL labelon;
279
280 switch (mouse) {
281 case EMACSTERM:
282 if (labelon == NO) {
283 labelon = YES;
284 (void) printf("\033L1"); /* force it on */
285 }
286 (void) printf("\033L!%s!", s);
287 return (1);
288 case MYX:
289 (void) printf("\033[?%dv%s", strlen(s), s);
290 return (1);
291 case NONE:
292 case PC7300:
293 default:
294 return (0); /* no label area */
295 }
296 }
297