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