root/gtags-cscope/mouse.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mouseinit
  2. mousemenu
  3. loadmenu
  4. mousereinit
  5. mousecleanup
  6. drawscrollbar
  7. getmouseaction
  8. getcoordinate
  9. getpercent

   1 /*===========================================================================
   2  Copyright (c) 1998-2000, The Santa Cruz Operation 
   3  All rights reserved.
   4  
   5  Redistribution and use in source and binary forms, with or without
   6  modification, are permitted provided that the following conditions are met:
   7 
   8  *Redistributions of source code must retain the above copyright notice,
   9  this list of conditions and the following disclaimer.
  10 
  11  *Redistributions in binary form must reproduce the above copyright notice,
  12  this list of conditions and the following disclaimer in the documentation
  13  and/or other materials provided with the distribution.
  14 
  15  *Neither name of The Santa Cruz Operation nor the names of its contributors
  16  may be used to endorse or promote products derived from this software
  17  without specific prior written permission. 
  18 
  19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
  20  IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  23  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26  INTERRUPTION)
  27  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  30  DAMAGE. 
  31  =========================================================================*/
  32 
  33 /** @file
  34  *      mouse functions
  35  *
  36  *      cscope - interactive C symbol cross-reference
  37  */
  38 
  39 #include "global-cscope.h"
  40 
  41 BOOL    mouse = NO;                     /**< mouse interface */
  42 
  43 #ifdef UNIXPC   /* build command requires #ifdef instead of #if */
  44 #include <sys/window.h>
  45 BOOL    unixpcmouse = NO;       /**< running with a mouse on the @NAME{Unix} @NAME{PC}? */
  46 static int uw_hs, uw_vs;        /**< character height and width */
  47 #endif
  48 
  49 static char const rcsid[] = "$Id: mouse.c,v 1.2 2012/10/13 07:02:07 shigio Exp $";
  50 
  51 typedef struct {                        /* menu */
  52         char    *text;
  53         char    *value;
  54 } MENU;
  55 
  56 static  MENU    mainmenu[] = {          /**< main menu */
  57         {"Send",        "##\033s##\r"},
  58         {"Repeat",      "\031"},
  59         {"Edit All",    "\05"},
  60         {"Rebuild",     "\022"},
  61         {"Shell",       "!"},
  62         {"Redraw",      "\f"},
  63         {"Help",        "?"},
  64         {"Exit",        "\04"},
  65         {NULL,          NULL}
  66 };
  67 
  68 static  MENU    changemenu[] = {        /**< change mode menu */
  69         {"Mark Screen", "*"},
  70         {"Mark All",    "a"},
  71         {"Change",      "\04"},
  72         {"No Change",   "\033"},
  73         {"Shell",       "!"},
  74         {"Redraw",      "\f"},
  75         {"Help",        "?"},
  76         {NULL,          NULL}
  77 };
  78 
  79 static  MENU    *loaded;                /**< menu loaded */
  80 static  BOOL    emacsviterm = NO;       /**< terminal type */
  81 
  82 static  void    loadmenu(MENU *menu);
  83 static  int     getcoordinate(void);
  84 static  int     getpercent(void);
  85 
  86 /** see if there is a mouse interface */
  87 
  88 void
  89 mouseinit(void)
  90 {
  91         char    *term;
  92 
  93         /* see if this is emacsterm or viterm */
  94         term = mygetenv("TERM", "");
  95         if (strcmp(term, "emacsterm") == 0 || 
  96             strcmp(term, "viterm") == 0) {
  97                 emacsviterm = YES;
  98                 mouse = YES;
  99         }
 100         /* the MOUSE enviroment variable is for 5620 terminal programs that have
 101            mouse support but the TERM environment variable is the same as a
 102            terminal without a mouse, such as myx */
 103         else if (strcmp(mygetenv("MOUSE", ""), "myx") == 0) {
 104                 mouse = YES;
 105         }
 106 #if UNIXPC
 107         else if (strcmp(term,"s4") == 0 || 
 108                  strcmp(term,"s120") == 0 ||
 109                  strcmp(term,"s90") == 0) {
 110                 int retval;
 111                 struct uwdata uwd;      /* Window data structure */
 112                 struct umdata umd;      /* Mouse data structure */
 113 
 114                 /* Ask for character size info */
 115                         
 116                 retval = ioctl(1,WIOCGETD,&uwd);
 117                 if(retval || uwd.uw_hs <= 0 || uwd.uw_vs <= 0) {
 118                         /**************************************************
 119                          * something wrong with the kernel, so fake it... 
 120                          **************************************************/
 121                         if(!strcmp(term,"s4")) {
 122                                 uw_hs = 9;
 123                                 uw_vs = 12;
 124                         }
 125                         else {
 126                                 uw_hs = 6;
 127                                 uw_vs = 10;
 128                         }
 129                 }
 130                 else {
 131                         /* Kernel is working and knows about this font */
 132                         uw_hs = uwd.uw_hs;
 133                         uw_vs = uwd.uw_vs;
 134                 }
 135                 
 136                 /**************************************************
 137                  * Now turn on mouse reporting so we can actually
 138                  * make use of all this stuff.
 139                  **************************************************/
 140                 if((retval = ioctl(1,WIOCGETMOUSE,&umd)) != -1) {
 141                         umd.um_flags= MSDOWN+MSUP;
 142                         ioctl(1,WIOCSETMOUSE,&umd);
 143                 }
 144                 unixpcmouse = YES;
 145         }
 146 #endif
 147         if (mouse == YES) {
 148                 loadmenu(mainmenu);
 149         }
 150 }
 151 
 152 /** load the correct mouse menu */
 153 
 154 void
 155 mousemenu(void)
 156 {
 157         if (mouse == YES) {
 158                 if (changing == YES) {
 159                         loadmenu(changemenu);
 160                 }
 161                 else {
 162                         loadmenu(mainmenu);
 163                 }
 164         }
 165 }
 166 
 167 /** download a menu */
 168 
 169 static void
 170 loadmenu(MENU *menu)
 171 {
 172         int     i;
 173 
 174         if (emacsviterm == YES) {
 175                 mousereinit();
 176                 (void) printf("\033V1");        /* display the scrollbar */
 177                 (void) printf("\033M0@%s@%s@", menu[0].text, menu[0].value);
 178                 for (i = 1; menu[i].text != NULL; ++i) {
 179                         (void) printf("\033M@%s@%s@", menu[i].text, menu[i].value);
 180                 }
 181         }
 182         else {  /* myx */
 183                 int     len;
 184                 
 185                 mousecleanup();
 186                 (void) printf("\033[6;1X\033[9;1X");
 187                 for (i = 0; menu[i].text != NULL; ++i) {
 188                         len = strlen(menu[i].text);
 189                         (void) printf("\033[%d;%dx%s%s", len,
 190                                       (int) (len + strlen(menu[i].value)), 
 191                                       menu[i].text, menu[i].value);
 192                 }
 193                 loaded = menu;
 194         }
 195         (void) fflush(stdout);
 196 }
 197 
 198 /** reinitialize the mouse in case @NAME{curses} changed the attributes */
 199 
 200 void
 201 mousereinit(void)
 202 {
 203         if (emacsviterm == YES) {
 204 
 205                 /* enable the mouse click and sweep coordinate control sequence */
 206                 /* and switch to menu 2 */
 207                 (void) printf("\033{2\033#2");
 208                 (void) fflush(stdout);
 209         }
 210 }
 211 
 212 /** restore the mouse attributes */
 213 
 214 void
 215 mousecleanup(void)
 216 {
 217         int     i;
 218 
 219         if (loaded != NULL) {   /* only true for myx */
 220                 
 221                 /* remove the mouse menu */
 222                 (void) printf("\033[6;0X\033[9;0X");
 223                 for (i = 0; loaded[i].text != NULL; ++i) {
 224                         (void) printf("\033[0;0x");
 225                 }
 226                 loaded = NULL;
 227         }
 228 }
 229 
 230 /** draw the scrollbar */
 231 
 232 void
 233 drawscrollbar(int top, int bot)
 234 {
 235         int p1, p2;
 236 
 237         if (emacsviterm == YES) {
 238                 if (bot > top) {
 239                         p1 = 16 + (top - 1) * 100 / totallines;
 240                         p2 = 16 + (bot - 1) * 100 / totallines;
 241                         if (p2 > 116) {
 242                                 p2 = 116;
 243                         }
 244                         if (p1 < 16) {
 245                                 p1 = 16;
 246                         }
 247                         /* don't send ^S or ^Q because it will hang a layer using cu(1) */
 248                         if (p1 == ctrl('Q') || p1 == ctrl('S')) {
 249                                 ++p1;
 250                         }
 251                         if (p2 == ctrl('Q') || p2 == ctrl('S')) {
 252                                 ++p2;
 253                         }
 254                 }
 255                 else {
 256                         p1 = p2 = 16;
 257                 }
 258                 (void) printf("\033W%c%c", p1, p2);
 259         }
 260 }
 261 
 262 /** get the mouse information */
 263 
 264 MOUSE *
 265 getmouseaction(char leading_char)
 266 {
 267         static  MOUSE   m;
 268 
 269 #if UNIXPC
 270 
 271         if(unixpcmouse == YES && leading_char == ESC) {
 272 
 273                 /* Called if cscope received an ESC character.  See if it is
 274                  * a mouse report and if so, decipher it.  A mouse report
 275                  * looks like: "<ESC>[?xx;yy;b;rM"
 276                  */
 277                 int x = 0, y = 0, button = 0, reason = 0;
 278                 int i;
 279         
 280                 /* Get a mouse report.  The form is: XX;YY;B;RM where
 281                  * XX is 1,2, or 3 decimal digits with the X pixel position.
 282                  * Similarly for YY.  B is a single decimal digit with the
 283                  * button number (4 for one, 2 for two, and 1 for three).
 284                  * R is the reason for the mouse report.
 285                  *
 286                  * In general, the input is read until the mouse report has
 287                  * been completely read in or we have discovered that this
 288                  * escape sequence is NOT a mouse report.  In the latter case
 289                  * return the last character read to the input stream with
 290                  * myungetch().
 291                  */
 292                 
 293                 /* Check for "[?" being next 2 chars */
 294                 if(((i = mygetch()) != '[') || ((i = mygetch()) != '?')) {
 295                         myungetch(i);
 296                         return(NULL);
 297                 }
 298         
 299                 /* Grab the X position (in pixels) */
 300                 while(isdigit(i = mygetch())) {
 301                         x = (x*10) + (i - '0');
 302                 }
 303                 if(i != ';') {
 304                         myungetch(i);
 305                         return(NULL);   /* not a mouse report after all */
 306                 }
 307         
 308                 /* Grab the Y position (in pixels) */
 309                 while(isdigit(i = mygetch())) {
 310                         y = (y*10) + (i - '0');
 311                 }
 312                 if(i != ';') {
 313                         myungetch(i);
 314                         return(NULL);
 315                 }
 316         
 317                 /* Get which button */
 318                 if((button = mygetch()) > '4') {
 319                         myungetch(button);
 320                         return(NULL);
 321                 }
 322                 if((i = mygetch()) != ';') {
 323                         myungetch(i);
 324                         return(NULL);
 325                 }
 326                 
 327                 /* Get the reason for this mouse report */
 328                 if((reason = mygetch()) > '8') {
 329                         myungetch(reason);
 330                         return(NULL);
 331                 }
 332                 
 333                 /* sequence should terminate with an 'M' */
 334                 if((i = mygetch()) != 'M') {
 335                         myungetch(i);
 336                         return(NULL);
 337                 }
 338         
 339         
 340                 /* OK.  We get a mouse report whenever a button is depressed
 341                  * or released.  Let's ignore the report whenever the button
 342                  * is depressed until when I am ready to implement sweeping.
 343                  */
 344                 if(reason != '2') {
 345                         return(NULL);   /* '2' means button is released */
 346                 }
 347         
 348                 /************************************************************
 349                  * Always indicate button 1 irregardless of which button was
 350                  * really pushed.
 351                  ************************************************************/
 352                 m.button = 1;
 353         
 354                 /************************************************************
 355                  * Convert pixel coordinates to line and column coords.
 356                  * The height and width are obtained using an ioctl() call
 357                  * in mouseinit().  This assumes that variable width chars
 358                  * are not being used ('though it would probably work anyway).
 359                  ************************************************************/
 360                 
 361                 m.x1 = x/uw_hs; /* pixel/horizontal_spacing */
 362                 m.y1 = y/uw_vs; /* pixel/vertical_spacing   */
 363         
 364                 /* "null" out the other fields */
 365                 m.percent = m.x2 = m.y2 = -1;
 366         }
 367         else
 368 #endif  /* not UNIXPC */
 369 
 370         if (mouse == YES && leading_char == ctrl('X')) {
 371         
 372                 switch (mygetch()) {
 373                 case ctrl('_'):         /* click */
 374                         if ((m.button = mygetch()) == '0') {    /* if scrollbar */
 375                                 m.percent = getpercent();
 376                         }
 377                         else {
 378                                 m.x1 = getcoordinate();
 379                                 m.y1 = getcoordinate();
 380                                 m.x2 = m.y2 = -1;
 381                         }
 382                         break;
 383         
 384                 case ctrl(']'):         /* sweep */
 385                         m.button = mygetch();
 386                         m.x1 = getcoordinate();
 387                         m.y1 = getcoordinate();
 388                         m.x2 = getcoordinate();
 389                         m.y2 = getcoordinate();
 390                         break;
 391                 default:
 392                         return(NULL);
 393                 }
 394         }
 395         else return(NULL);
 396 
 397         return(&m);
 398 }
 399 
 400 /** get a row or column coordinate from a mouse button click or sweep */
 401 
 402 static int
 403 getcoordinate(void)
 404 {
 405         int  c, next;
 406 
 407         c = mygetch();
 408         next = 0;
 409         if (c == ctrl('A')) {
 410                 next = 95;
 411                 c = mygetch();
 412         }
 413         if (c < ' ') {
 414                 return (0);
 415         }
 416         return (next + c - ' ');
 417 }
 418 
 419 /** get a percentage */
 420 
 421 static int
 422 getpercent(void)
 423 {
 424         int c;
 425 
 426         c = mygetch();
 427         if (c < 16) {
 428                 return(0);
 429         }
 430         if (c > 120) {
 431                 return(100);
 432         }
 433         return(c - 16);
 434 }

/* [previous][next][first][last][top][bottom][index][help] */