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