xref: /illumos-gate/usr/src/tools/cscope-fast/mouse.c (revision dd72704bd9e794056c558153663c739e2012d721)
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
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
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
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
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
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
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 *
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
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
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
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