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