Annotation of 43BSDReno/contrib/emacs-18.55/etc/emacstool.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * 
                      3:  *    Copyright (C) 1986 Free Software Foundation, Inc.
                      4:  * 
                      5:  * This file is part of GNU Emacs.
                      6:  * 
                      7:  * GNU Emacs is distributed in the hope that it will be useful,
                      8:  * but without any warranty.  No author or distributor
                      9:  * accepts responsibility to anyone for the consequences of using it
                     10:  * or for whether it serves any particular purpose or works at all,
                     11:  * unless he says so in writing.
                     12:  * 
                     13:  * Everyone is granted permission to copy, modify and redistribute
                     14:  * GNU Emacs, but only under the conditions described in the
                     15:  * document "GNU Emacs copying permission notice".   An exact copy
                     16:  * of the document is supposed to have been given to you along with
                     17:  * GNU Emacs so that you can know how you may redistribute it all.
                     18:  * It should be in a file named COPYING.  Among other things, the
                     19:  * copyright notice and this notice must be preserved on all copies.
                     20:  * 
                     21:  *
                     22:  * For Emacs in SunView/Sun-Windows: (supported by Sun Unix v3.2)
                     23:  * Insert a notifier filter-function to convert all useful input 
                     24:  * to "key" sequences that emacs can understand.  See: Emacstool(1).
                     25:  *
                     26:  * Author: Jeff Peck, Sun Microsystems, Inc. <[email protected]>
                     27:  *
                     28:  * Original Idea: Ian Batten
                     29:  * Updated 15-Mar-88, Jeff Peck: set IN_EMACSTOOL, TERM, TERMCAP
                     30:  * 
                     31:  */
                     32: 
                     33: #include <suntool/sunview.h>
                     34: #include <suntool/tty.h>
                     35: #include <stdio.h>
                     36: #include <sys/file.h>
                     37: 
                     38: #define BUFFER_SIZE 128               /* Size of all the buffers */
                     39: 
                     40: /* define WANT_CAPS_LOCK to make f-key T1 (aka F1) behave as CapsLock */
                     41: #define WANT_CAPS_LOCK
                     42: #ifdef WANT_CAPS_LOCK
                     43: int caps_lock;         /* toggle indicater for f-key T1 caps lock */
                     44: static char *Caps = "[CAPS] ";         /* Caps Lock prefix string */
                     45: #define CAPS_LEN 7                     /* strlen (Caps) */
                     46: #endif
                     47: 
                     48: static char *mouse_prefix = "\030\000";        /* C-x C-@ */
                     49: static int   m_prefix_length = 2;       /* mouse_prefix length */
                     50: 
                     51: static char *key_prefix = "\030*";     /* C-x *   */
                     52: static int   k_prefix_length = 2;       /* key_prefix length */
                     53: 
                     54: static char *emacs_name = "emacs";     /* default run command */
                     55: static char buffer[BUFFER_SIZE];       /* send to ttysw_input */
                     56: static char *title = "Emacstool - ";   /* initial title */
                     57: 
                     58: Frame frame;                            /* Base frame for system */
                     59: Tty ttysw;                              /* Where emacs is */
                     60: int font_width, font_height;            /* For translating pixels to chars */
                     61: 
                     62: int console_fd = 0;            /* for debugging: setenv DEBUGEMACSTOOL */
                     63: FILE *console;                 /* for debugging: setenv DEBUGEMACSTOOL */
                     64: 
                     65: Icon frame_icon;
                     66: /* make an icon_image for the default frame_icon */
                     67: static short default_image[258] = 
                     68: {
                     69: #include <images/terminal.icon>
                     70: };
                     71: mpr_static(icon_image, 64, 64, 1, default_image);
                     72: 
                     73: 
                     74: /*
                     75:  * Assign a value to a set of keys
                     76:  */
                     77: int
                     78: button_value (event)
                     79:      Event *event;
                     80: {
                     81:   int retval = 0;
                     82:   /*
                     83:    * Code up the current situation:
                     84:    *
                     85:    * 1 = MS_LEFT;
                     86:    * 2 = MS_MIDDLE;
                     87:    * 4 = MS_RIGHT;
                     88:    * 8 = SHIFT;
                     89:    * 16 = CONTROL;
                     90:    * 32 = META;
                     91:    * 64 = DOUBLE;
                     92:    * 128 = UP;
                     93:    */
                     94: 
                     95:   if (MS_LEFT   == (event_id (event))) retval = 1;
                     96:   if (MS_MIDDLE == (event_id (event))) retval = 2;
                     97:   if (MS_RIGHT  == (event_id (event))) retval = 4;
                     98: 
                     99:   if (event_shift_is_down (event)) retval += 8;
                    100:   if (event_ctrl_is_down  (event)) retval += 16;
                    101:   if (event_meta_is_down  (event)) retval += 32;
                    102:   if (event_is_up         (event)) retval += 128;
                    103:   return retval;
                    104: }
                    105: 
                    106: /*
                    107:  *  Variables to store the time of the previous mouse event that was
                    108:  *  sent to emacs.
                    109:  *
                    110:  *  The theory is that to time double clicks while ignoreing UP buttons,
                    111:  *  we must keep track of the accumulated time.
                    112:  *
                    113:  *  If someone writes a SUN-SET-INPUT-MASK for emacstool,
                    114:  *  That could be used to selectively disable UP events, 
                    115:  *  and then this cruft wouldn't be necessary.
                    116:  */
                    117: static long prev_event_sec = 0;
                    118: static long prev_event_usec = 0;
                    119: 
                    120: /*
                    121:  *  Give the time difference in milliseconds, where one second
                    122:  *  is considered infinite.
                    123:  */
                    124: int
                    125: time_delta (now_sec, now_usec, prev_sec, prev_usec)
                    126:      long now_sec, now_usec, prev_sec, prev_usec;
                    127: {
                    128:   long sec_delta = now_sec - prev_sec;
                    129:   long usec_delta = now_usec - prev_usec;
                    130:   
                    131:   if (usec_delta < 0) {                /* "borrow" a second */
                    132:     usec_delta += 1000000;
                    133:     --sec_delta;
                    134:   }
                    135:   
                    136:   if (sec_delta >= 10) 
                    137:     return (9999);             /* Infinity */
                    138:   else
                    139:     return ((sec_delta * 1000) + (usec_delta / 1000));
                    140: }
                    141: 
                    142: 
                    143: /*
                    144:  * Filter function to translate selected input events for emacs
                    145:  * Mouse button events become ^X^@(button x-col y-line time-delta) .
                    146:  * Function keys: ESC-*{c}{lrt} l,r,t for Left, Right, Top; 
                    147:  * {c} encodes the keynumber as a character [a-o]
                    148:  */
                    149: static Notify_value
                    150: input_event_filter_function (window, event, arg, type)
                    151:      Window window;
                    152:      Event *event;
                    153:      Notify_arg arg;
                    154:      Notify_event_type type;
                    155: {
                    156:   struct timeval time_stamp;
                    157: 
                    158:   if (console_fd) fprintf(console, "Event: %d\n", event_id(event));
                    159: 
                    160:   /* UP L1 is the STOP key */
                    161:   if (event_id(event) == WIN_STOP) {
                    162:     ttysw_input(ttysw, "\007\007\007\007\007\007\007", 7);
                    163:     return NOTIFY_IGNORED;
                    164:   }
                    165: 
                    166:   /* UP L5 & L7 is Expose & Open, let them pass to sunview */
                    167:   if (event_id(event) == KEY_LEFT(5) || event_id(event) == KEY_LEFT(7))
                    168:     if(event_is_up (event)) 
                    169:       return notify_next_event_func (window, event, arg, type);
                    170:     else return NOTIFY_IGNORED;
                    171: 
                    172:   if (event_is_button (event)) {             /* do Mouse Button events */
                    173: /* Commented out so that we send mouse up events too.
                    174:    if (event_is_up (event)) 
                    175:       return notify_next_event_func (window, event, arg, type);
                    176: */
                    177:     time_stamp = event_time (event);
                    178:     ttysw_input (ttysw, mouse_prefix, m_prefix_length);
                    179:     sprintf (buffer, "(%d %d %d %d)\015", 
                    180:             button_value (event),
                    181:             event_x (event) / font_width,
                    182:             event_y (event) / font_height,
                    183:             time_delta (time_stamp.tv_sec, time_stamp.tv_usec,
                    184:                         prev_event_sec, prev_event_usec)
                    185:             );
                    186:     ttysw_input (ttysw, buffer, strlen(buffer));
                    187:     prev_event_sec = time_stamp.tv_sec;
                    188:     prev_event_usec = time_stamp.tv_usec;
                    189:     return NOTIFY_IGNORED;
                    190:   }
                    191:   
                    192:   { /* Do the function key events */
                    193:     int d;
                    194:     char c = (char) 0;
                    195:     if ((event_is_key_left  (event)) ?
                    196:        ((d = event_id(event) - KEY_LEFT(1)   + 'a'), c='l') : 
                    197:        ((event_is_key_right (event)) ?
                    198:         ((d = event_id(event) - KEY_RIGHT(1) + 'a'), c='r') : 
                    199:         ((event_is_key_top   (event)) ?
                    200:          ((d = event_id(event) - KEY_TOP(1)  + 'a'), c='t') : 0)))
                    201:       {
                    202:        if (event_is_up(event)) return NOTIFY_IGNORED;
                    203:        if (event_shift_is_down (event)) c = c -  32;
                    204:        /* this will give a non-{lrt} for unshifted keys */
                    205:        if (event_ctrl_is_down  (event)) c = c -  64;
                    206:        if (event_meta_is_down  (event)) c = c + 128;
                    207: #ifdef WANT_CAPS_LOCK
                    208: /* set a toggle and relabel window so T1 can act like caps-lock */
                    209:        if (event_id(event) == KEY_TOP(1)) 
                    210:          {
                    211:            /* make a frame label with and without CAPS */
                    212:            strcpy (buffer, Caps); 
                    213:            title = &buffer[CAPS_LEN];
                    214:            strncpy (title, (char *)window_get (frame, FRAME_LABEL),
                    215:                     BUFFER_SIZE - CAPS_LEN);
                    216:            buffer[BUFFER_SIZE] = (char) 0;     
                    217:            if (strncmp (title, Caps, CAPS_LEN) == 0)
                    218:              title += CAPS_LEN;                 /* already Caps */
                    219:            caps_lock =  (caps_lock ? 0 : CAPS_LEN);
                    220:            window_set(frame, FRAME_LABEL, (title -= caps_lock), 0);
                    221:            return NOTIFY_IGNORED;
                    222:          }
                    223: #endif
                    224:        ttysw_input (ttysw, key_prefix, k_prefix_length);
                    225:        sprintf (buffer, "%c%c", d, c);
                    226:        ttysw_input(ttysw, buffer, strlen(buffer));
                    227: 
                    228:        return NOTIFY_IGNORED;
                    229:       }
                    230:   }
                    231:   if ((event_is_ascii(event) || event_is_meta(event)) 
                    232:       && event_is_up(event)) return NOTIFY_IGNORED;
                    233: #ifdef WANT_CAPS_LOCK
                    234: /* shift alpha chars to upper case if toggle is set */
                    235:   if ((caps_lock) && event_is_ascii(event)
                    236:       && (event_id(event) >= 'a') && (event_id(event) <= 'z'))
                    237:     event_set_id(event, (event_id(event) - 32));
                    238: /* crufty, but it works for now. is there an UPCASE(event)? */
                    239: #endif
                    240:   return notify_next_event_func (window, event, arg, type);
                    241: }
                    242: 
                    243: main (argc, argv)
                    244:      int argc;
                    245:      char **argv;
                    246: {
                    247:   int error_code;      /* Error codes */
                    248:   
                    249:   if(getenv("DEBUGEMACSTOOL"))
                    250:     console = fdopen (console_fd = open("/dev/console",O_WRONLY), "w");
                    251: 
                    252:                        /* do this first, so arglist can override it */
                    253:   frame_icon = icon_create (ICON_LABEL, "Emacstool",
                    254:                            ICON_IMAGE, &icon_image,
                    255:                            0);
                    256: 
                    257:   putenv("IN_EMACSTOOL=t");    /* notify subprocess that it is in emacstool */
                    258: 
                    259:   if (putenv("TERM=sun") != 0) /* TTYSW will be a TERM=sun window */
                    260:     {fprintf (stderr, "%s: Could not set TERM=sun, using `%s'\n",
                    261:             argv[0], (char *)getenv("TERM")) ;};
                    262:   /*
                    263:    * If TERMCAP starts with a slash, it is the pathname of the
                    264:    * termcap file, not an entry extracted from it, so KEEP it!
                    265:    * Otherwise, it may not relate to the new TERM, so Nuke-It.
                    266:    * If there is no TERMCAP environment variable, don't make one.
                    267:    */
                    268:   {
                    269:     char *termcap ;    /* Current TERMCAP value */
                    270:     termcap = (char *)getenv("TERMCAP") ;
                    271:     if (termcap && (*termcap != '/'))
                    272:       {
                    273:        if (putenv("TERMCAP=") != 0)
                    274:          {fprintf (stderr, "%s: Could not clear TERMCAP\n", argv[0]) ;} ;
                    275:       } ;
                    276:   } ;
                    277:   
                    278:   /* find command to run as subprocess in window */
                    279:   if (!(argv[0] = (char *)getenv("EMACSTOOL")))        /* Set emacs command name */
                    280:       argv[0] = emacs_name;                    
                    281:   for (argc = 1; argv[argc]; argc++)           /* Use last one on line */
                    282:     if(!(strcmp ("-rc", argv[argc])))          /* Override if -rc given */
                    283:       {
                    284:        int i = argc;
                    285:        argv[argc--]=0;         /* kill the -rc argument */
                    286:        if (argv[i+1]) {        /* move to agrv[0] and squeeze the rest */
                    287:          argv[0]=argv[i+1];
                    288:          for (; argv[i+2]; (argv[i]=argv[i+2],argv[++i]=0));
                    289:        }
                    290:       }
                    291: 
                    292:   strcpy (buffer, title);
                    293:   strncat (buffer, argv[0],             /* append run command name */
                    294:           (BUFFER_SIZE - (strlen (buffer)) - (strlen (argv[0]))) - 1);
                    295: 
                    296:                        /* Build a frame to run in */
                    297:   frame = window_create ((Window)NULL, FRAME,
                    298:                         FRAME_LABEL, buffer,
                    299:                         FRAME_ICON, frame_icon,
                    300:                         FRAME_ARGC_PTR_ARGV, &argc, argv,
                    301:                         0);
                    302: 
                    303:   /* Create a tty with emacs in it */
                    304:   ttysw = window_create (frame, TTY, 
                    305:                         TTY_QUIT_ON_CHILD_DEATH, TRUE, 
                    306:                         TTY_BOLDSTYLE, 8, 
                    307:                         TTY_ARGV, argv, 
                    308:                         0);
                    309: 
                    310:   window_set(ttysw,
                    311:             WIN_CONSUME_PICK_EVENTS, 
                    312:             WIN_STOP,
                    313:             WIN_MOUSE_BUTTONS, WIN_UP_EVENTS,
                    314:             /* LOC_WINENTER, LOC_WINEXIT, LOC_MOVE, */
                    315:             0,
                    316: 
                    317:             WIN_CONSUME_KBD_EVENTS, 
                    318:             WIN_STOP,
                    319:             WIN_ASCII_EVENTS, 
                    320:             WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
                    321:             /* WIN_UP_ASCII_EVENTS, */
                    322:             0,
                    323:             
                    324:             0);
                    325: 
                    326:   font_height = (int)window_get (ttysw, WIN_ROW_HEIGHT);
                    327:   font_width  = (int)window_get (ttysw, WIN_COLUMN_WIDTH);
                    328: 
                    329:                                          /* Interpose my event function */
                    330:   error_code = (int)  notify_interpose_event_func 
                    331:     (ttysw, input_event_filter_function, NOTIFY_SAFE);
                    332: 
                    333:   if (error_code != 0)                       /* Barf */
                    334:     {
                    335:       fprintf (stderr, "notify_interpose_event_func got %d.\n", error_code);
                    336:       exit (1);
                    337:     }
                    338: 
                    339:   window_main_loop (frame);                  /* And away we go */
                    340: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.