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