dave@galaxia.Newport.RI.US (David H. Brierley) (06/07/89)
This is a repost of the hotkey program for the ATT 7300/3B1 that I posted a few weeks ago. I originally posted the source to unix-pc.sources and a short note to comp.sys.att saying that I posted the source. Since then I have been flooded with requests saying "we dont get unix-pc.*, sould you send me a copy?". The first few requests that I got I replied to via mail but eventually it got to the point where I decided it was worthwhile to just post the source to comp.sys.att. So here it is. Following is an excerpt from the README file and then the full shar file. One thing that I forgot to mention in the documentation is that if you move the mouse pointer into the window that hotkey creates on the status line the mouse pointer will disappear. This was done to give me a nice permanent place to hide the mouse pointer without going to a lot of fuss. ===== Begin extract from README file ===== This program provides a function similar to the IBM-PC TSR programs which use a "hot key" to activate the program. When the program is activated it is given a list of commands that are to be bound to the 8 shifted function keys. When a shifted function key is pressed a new window is created and the requested program is run from within the new window. ----- cut here and feed to sh ----- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: MANIFEST README hotkey.1 hotkey.c hotkey.sample makefile # Wrapped by dave@galaxia on Sun May 21 22:32:51 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(282 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 X README 1 X hotkey.1 1 X hotkey.c 1 X hotkey.sample 1 X makefile 1 END_OF_FILE if test 282 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1197 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThis program provides a function similar to the IBM-PC TSR programs which Xuse a "hot key" to activate the program. When the program is activated it Xis given a list of commands that are to be bound to the 8 shifted function Xkeys. When a shifted function key is pressed a new window is created and Xthe requested program is run from within the new window. Note that this Xprogram allocates a window for its own use which means that there is one Xless window available to the user. Since there are a total of 12 windows Xavailable on the system and there are only 8 function keys, this should not Xpresent any problems to the average user. X XFor more information about the program, read the man page. For even more Xinformation, read the source. X XNote that this program does not require any super user priveleges. X X---- Installation Instructions ---- X X1. Edit the makefile to correctly reflect the name of the directory you want X the program installed in. X2. Type "make". X3. Try it out before installing it, if you are paranoid. X4. Type "make install". X5. Let me know if you have any suggestions for improvements. X XDavid H. Brierley Xdave@galaxia.newport.ri.us X{mirror,rayssd,xanth,att} !galaxia!dave END_OF_FILE if test 1197 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'hotkey.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hotkey.1'\" else echo shar: Extracting \"'hotkey.1'\" \(5939 characters\) sed "s/^X//" >'hotkey.1' <<'END_OF_FILE' X.TH HOTKEY 1 LOCAL X.UC X.SH NAME Xhotkey \- set hotkey-like actions on function keys X.SH SYNOPSIS X.nf Xhotkey [-fFILE] [-r] [-k] [-u#] [-b#] [-n] [-h#] [-w#] [command] X.fi X.SH DESCRIPTION XThe X.I hotkey Xprogram takes over control of the shifted function keys which are normally Xused by the X.I "Phone Manager" Xand allows you to specify a program that is to be run when any of the Xfunction keys are pressed. Each time a function key is pressed a new Xwindow is created and the specified program is run inside the window. XThe user has control over the size of the created window, the smallest Xwindow allowed being four lines by twenty columns and the largest window Xallowed being full screen borderless. Each function key may be defined Xusing a separate invocation of the X.I hotkey Xprogram, but it is far easier to create a key definition file and simply Xrun X.I hotkey Xonce using the X.I -f Xoption. X.P XA list showing which function keys are currently mapped will be displayed Xon the top line of the screen, using the window normally used by the X.I "Phone Manager" Xto display the status of the phone lines. The format of the display is: X.sp X.ti +3 XFunction Keys Active: 12345678 X.sp XIf a particular function keys is not currently mapped, a period will be Xdisplayed in place of the key number. After you log off, or if you Xexplicitly kill the hotkey process using the X.I -k Xoption (see below), the display area will be blanked out. X.SH "INTERACTIONS WITH THE PHONE MANAGER" XSince this program uses the same display are on the screen as the X.I "Phone Manager," Xand since it usurps control of the shifted function keys, it is not Xrecomended that this program be used on systems which are actively using the X.I "Phone Manager." XThis is not to say that it cant be done, just that it is not recommended. XIf you do try to run this program and the X.I "Phone Manager" Xat the same time they will fight for control of the function keys and will Xfight over whose message gets displayed on the status line. The X.I "Phone Manager" Xwakes up every time something happens on one of the phone lines (i.e. Xincoming call, outgoing call, call termination) and reregisters for control Xof the function keys and updates the display. The X.I hotkey Xprogram wakes up at time intervals that are set at compile time and Xreregisters for control of the function keys. If the key definitions have Xchanged since the last time the display was changed the the display is Xupdated. The X.I hotkey Xprogram is also woken up by running the program again. X.SH "METHOD OF OPERATION" XThe first time this program is run it will fork itself into the background, Xallocate the window on the status line, and register for control of the Xshifted function keys. XThe key definitions are recorded in the X.I bind Xfile (see below) and the process id of the background process is recorded in Xthe X.I pid Xfile. The program determines that it should go into background mode by one Xof the following conditions being satisfied: a) there is no pid file; b) the Xprocess id listed in the pid file does not exist; c) the bind file is not Xowned by the current user. XEach time one of the shifted function keys are Xpressed the key definition file is read, a new window is created, and the Xrequested command is run within the new window. When the program receives a Xhangup signal, either because you logged off or because you ran the program Xagain specifying the -k option, it will blank out the window, change the Xownership of the bind file to -1, and then go to sleep. The next time Xsomeone runs the program the new copy of the program will see that the bind Xfile is owned by uid -1 and will automatically go into background mode and Xcreate a new bind file owned by the new user. The old copy of the program Xwill see that the bind file is no longer owned by uid -1 and will exit. XThe reason for all of this nonsense is that if the background process simply Xexits when it receives the hangup signal the display area on the status line Xwill revert to the ugly dots pattern. For this reason you should never kill Xthe X.I hotkey Xprocess using the X.I kill Xcommand but instead you should instruct the program to go into idle mode by Xusing the command X.I "hotkey -k." X.SH "OPTIONS" XThe following options are recognized on the command line: X.TP 8 X-b# XSpecifies the key number to be bound (1 thru 8). X.TP X-u# XSpecifies a key number to be unbound. X.TP X-k XKill the X.I hotkey Xprocess. X.TP X-r XRefresh the X.I hotkey Xwindow on the top line of the screen. X.TP X-h# XSpecifies the height (in rows) of the window to be created. X.TP X-w# XSpecifies the width (in columns) of the window to be created. X.TP X-n XSpecifies that the window to be created should be a full screen Xborderless window. X.TP X-fFILE XThe contents of the file are read in and used to define the function Xkeys (see below). X.P XAny remaining arguments on the command line are taken to be the command Xto be executed. X.SH "FORMAT OF KEY DEFINITION FILE" XThe key definition file, for use with the X.I -f Xoption, consists of one to eight lines in the following format: X.sp X.ti +3 Xkeynum,height,width command [arguments] X.sp XThe keynum values are the same as those defined above. The height and Xwidht values specify the size of the window in rows and columns. For a Xfull screen borderless window specify a size of 24,80. The key Xdefinitions may be in any order. X.SH "EXAMPLES" X.in +3 X.nf X# start a new shell process Xhotkey -b1 -h24 -w80 /bin/ksh X# read the news Xhotkey -b2 -h24 -w80 rn X# calculator Xhotkey -b3 -h12 -w20 calculatr X.in -3 X.fi X.SH "SAMPLE KEY DEFINITION FILE" X.nf X.in +3 X1,15,72 ksh X2,15,72 /u/dave/cmd/root.sh X3,15,72 /u/dave/cmd/uucp.sh X4,04,20 uusnap X5,04,20 scrtoggle X6,04,20 calculatr X7,24,80 pcomm.sh -f rayssdb X8,24,80 /u/dave/cmd/rn X.in -3 X.fi X.SH FILES X/usr/local/hotkey/pid - pid of active hotkey process X.br X/usr/local/hotkey/bind - current key bindings X.SH "SEE ALSO" Xwindow(7) X.SH "BUGS" XHopefully, none. X.SH "AUTHOR" XDavid H. Brierley END_OF_FILE if test 5939 -ne `wc -c <'hotkey.1'`; then echo shar: \"'hotkey.1'\" unpacked with wrong size! fi # end of 'hotkey.1' fi if test -f 'hotkey.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hotkey.c'\" else echo shar: Extracting \"'hotkey.c'\" \(14790 characters\) sed "s/^X//" >'hotkey.c' <<'END_OF_FILE' X#ifndef lint Xstatic char *SccsId = "@(#) hotkey.c: version 1.14 5/21/89 (dhb@galaxia)"; X#endif X X#include <stdio.h> X#include <sys/font.h> X#include <sys/window.h> X#include <termio.h> X#include <signal.h> X#include <malloc.h> X#include <string.h> X#include <setjmp.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/wd.h> X#include <track.h> X X#define ALARM_LIMIT 90 X X#define PID_FILE "/usr/local/hotkey/pid" X#define KEY_FILE "/usr/local/hotkey/bind" X Xstruct hotkey { X struct hotkey *h_next; X int h_key; X int h_height; X int h_width; X char h_cmd[256]; X}; X Xint getmaster (); Xvoid set_master (); Xint mk_window (); Xstruct hotkey *read_keyfile (); Xvoid write_keyfile (); Xvoid unbind (); Xint kcount (); Xvoid free_list (); Xstruct hotkey *insert (); Xstruct hotkey *bind (); Xint die (); Xvoid terminate (); Xvoid do_hotkey (); Xint atrap (); Xint refresh (); Xvoid zapmouse (); X Xvoid exit (); Xvoid _exit (); Xchar *getenv (); Xvoid longjmp (); Xunsigned alarm (); X Xjmp_buf abuff; Xint user_id; Xint need_wiocsys = 1; X Xmain (argc, argv) Xint argc; Xchar *argv[]; X{ X int keynum; X int mpid; X int wd; X int fd; X int signo; X int oldwd; X int wheight; X int wwidth; X time_t bind_time; X time_t new_bind; X char buffer[1]; X int bufpos; X char *home; X struct hotkey *head; X int optch; X extern char *optarg; X extern int optind; X X user_id = getuid (); X mpid = getmaster (); X keynum = -1; X wheight = 12; X wwidth = 60; X X if (mpid != 0) { X head = read_keyfile (KEY_FILE); X } X else { X head = NULL; X } X X while ((optch = getopt (argc, argv, "rknh:w:f:b:u:")) != EOF) { X switch (optch) { X case 'b': X keynum = atoi (optarg); X break; X case 'u': X unbind (optarg, head); X break; X case 'k': X free_list (head); X head = NULL; X break; X case 'h': X wheight = atoi (optarg); X break; X case 'w': X wwidth = atoi (optarg); X break; X case 'n': X wheight = 24; X wwidth = 80; X break; X case 'f': X free_list (head); X head = read_keyfile (optarg); X break; X case 'r': X if (mpid != 0) { X (void) kill (mpid, SIGUSR1); X } X exit (0); X } X } X X if (keynum >= 0) { X head = bind (keynum, wheight, wwidth, argc, argv, optind, head); X } X X if ((head == NULL) || (kcount (head) == 0)) { X if (mpid != 0) { X (void) kill (mpid, SIGHUP); X exit (0); X } X } X X write_keyfile (head); X X if (mpid != 0) { X (void) kill (mpid, SIGALRM); X exit (0); X } X X wd = mk_window (); X oldwd = ioctl (wd, WIOCGPREV, NULL); X if (oldwd == -1) { X oldwd = 0; X } X X if (fork () != 0) { X (void) ioctl (oldwd, WIOCSELECT, NULL); X exit (0); X } X X if ((home = getenv ("HOME")) != NULL) { X (void) chdir (home); X } X X for (fd = 0; fd < _NFILE; ++fd) { X if (fd != wd) { X (void) close (fd); X } X } X X for (signo = 1; signo < NSIG; ++signo) { X (void) signal (signo, SIG_IGN); X } X (void) signal (SIGALRM, atrap); X (void) signal (SIGHUP, die); X (void) signal (SIGTERM, die); X (void) signal (SIGUSR1, refresh); X free_list (head); X X bufpos = 0; X set_master (); X X while (1) { X (void) setjmp (abuff); X if (is_owner (KEY_FILE, &new_bind) == 0) { X terminate (); X } X if (need_wiocsys) { X (void) ioctl (wd, WIOCSYS, 1); X zapmouse (wd); X bind_time = 0; X need_wiocsys = 0; X } X if (new_bind != bind_time) { X display_keys (wd); X bind_time = new_bind; X } X (void) alarm (ALARM_LIMIT); X if (read (wd, buffer, 1) != 1) { X continue; X } X switch (bufpos) { X case 0: X if ((buffer[0] & 0x7f) == 0x1b) { X ++bufpos; X } break; X case 1: X if ((buffer[0] & 0x7f) == 0x4f) { X bufpos = 2; X } X else { X bufpos = 0; X } X break; X case 2: X keynum = (buffer[0] & 0x7f) - 'B'; X do_hotkey (keynum); X bufpos = 0; X break; X } X } X X} X Xint Xgetmaster () X{ X int fd; X int pid; X X if (is_owner (PID_FILE, NULL) == 0) { X return (0); X } X X if ((fd = open (PID_FILE, 0)) == -1) { X return (0); X } X X if (read (fd, (char *) &pid, sizeof (int)) != sizeof (int)) { X pid = 0; X } X (void) close (0); X X if (pid != 0) { X if (kill (pid, 0) == -1) { X pid = 0; X } X } X return (pid); X X} X Xvoid Xset_master () X{ X int fd; X int pid; X X (void) unlink (PID_FILE); X if ((fd = creat (PID_FILE, 0666)) == -1) { X exit (1); X } X X pid = getpid (); X if (write (fd, (char *) &pid, sizeof (int)) != sizeof (int)) { X exit (1); X } X X if (close (fd) == -1) { X exit (1); X } X X} X Xint Xmk_window () X{ X int wd; X int wnum; X int fd; X char *wname; X struct uwdata uwdata; X struct utdata utdata; X struct termio tty; X char *ttyname (); X X wnum = 0; X wd = -1; X while (wnum < 8) { X fd = open ("/dev/window", 2); X if (fd == -1) { X if (wd != -1) { X break; X } X exit (1); X } X wd = fd; X wname = ttyname (wd); X wnum = atoi (wname + 6); X } X X if (ioctl (wd, WIOCGETD, &uwdata) == -1) { X exit (1); X } X X uwdata.uw_x = 0; X uwdata.uw_y = 0; X uwdata.uw_width = 9 * 32; X uwdata.uw_height = 12; X uwdata.uw_uflags = NBORDER; X X if (ioctl (wd, WIOCSETD, &uwdata) == -1) { X exit (1); X } X X utdata.ut_num = WTXTUSER; X (void) strcpy (utdata.ut_text, "Status Manager"); X (void) ioctl (wd, WIOCSETTEXT, &utdata); X X if (ioctl (wd, WIOCPGRP, NULL) == -1) { X exit (1); X } X X if (ioctl (wd, WIOCSYS, 1) == -1) { X exit (1); X } X X if (ioctl (wd, TCGETA, &tty) == -1) { X exit (1); X } X X tty.c_lflag = 0; X tty.c_cc[VMIN] = 1; X tty.c_cc[VTIME] = 0; X X if (ioctl (wd, TCSETA, &tty) == -1) { X exit (1); X } X X return (wd); X X} X Xstruct hotkey * Xread_keyfile (filename) Xchar *filename; X{ X int keynum; X int height; X int width; X int n; X struct hotkey *head; X char line[BUFSIZ]; X FILE *fp; X char *cmd; X X head = NULL; X if ((fp = fopen (filename, "r")) == NULL) { X return (head); X } X X while (fgets (line, BUFSIZ - 1, fp) != NULL) { X cmd = line + strlen (line) - 1; X *cmd = '\0'; X if ((cmd = strchr (line, ' ')) == NULL) { X continue; X } X *cmd++ = '\0'; X while (*cmd == ' ') { X ++cmd; X } X n = sscanf (line, "%d,%d,%d", &keynum, &height, &width); X switch (n) { X case 3: X break; X case 1: X height = 12; X width = 60; X break; X default: X continue; X } X head = insert (head, keynum, height, width, cmd); X } X (void) fclose (fp); X return (head); X X} X Xvoid Xwrite_keyfile (head) Xstruct hotkey *head; X{ X struct hotkey *ptr; X FILE *fp; X X (void) unlink (KEY_FILE); X if ((fp = fopen (KEY_FILE, "w")) == NULL) { X exit (1); X } X X for (ptr = head; ptr != NULL; ptr = ptr -> h_next) { X if (ptr -> h_key != -1) { X (void) fprintf (fp, "%d,%d,%d %s\n", X ptr -> h_key, ptr -> h_height, ptr -> h_width, ptr -> h_cmd); X } X } X X if (fclose (fp) == -1) { X exit (1); X } X X} X Xvoid Xunbind (key, head) Xchar *key; Xstruct hotkey *head; X{ X struct hotkey *ptr; X int keynum; X X keynum = atoi (key); X for (ptr = head; ptr != NULL; ptr = ptr -> h_next) { X if (ptr -> h_key == keynum) { X ptr -> h_key = -1; X } X } X X} X Xint Xkcount (head) Xstruct hotkey *head; X{ X struct hotkey *ptr; X int knum; X X for (knum = 0, ptr = head; ptr != NULL; ptr = ptr -> h_next) { X if (ptr -> h_key != -1) { X ++knum; X } X } X X return (knum); X X} X Xvoid Xfree_list (head) Xstruct hotkey *head; X{ X struct hotkey *ptr; X struct hotkey *tmp; X X ptr = head; X while (ptr != NULL) { X tmp = ptr; X ptr = ptr -> h_next; X (void) free (tmp); X } X X} X Xstruct hotkey * Xinsert (head, key, height, width, cmd) Xstruct hotkey *head; Xint key; Xint height; Xint width; Xchar *cmd; X{ X struct hotkey *ptr; X X for (ptr = head; ptr != NULL; ptr = ptr -> h_next) { X if (ptr -> h_key == key) { X ptr -> h_key = -1; X } X } X X if (strlen (cmd) >= sizeof (ptr -> h_cmd)) { X (void) fprintf (stderr, X "Command string for key %d is too long, max = %d\n", X key, sizeof (ptr -> h_cmd)); X exit (1); X } X X ptr = (struct hotkey *) malloc (sizeof (struct hotkey)); X if (ptr == NULL) { X exit (1); X } X X if (height > 24) { X height = 24; X } X if (height < 6) { X height = 6; X } X if (width > 80) { X width = 80; X } X if (width < 20) { X width = 20; X } X X ptr -> h_key = key; X ptr -> h_height = height; X ptr -> h_width = width; X (void) strcpy (ptr -> h_cmd, cmd); X ptr -> h_next = head; X return (ptr); X X} X Xstruct hotkey * Xbind (key, height, width, ac, av, a0, head) Xint key; Xint height; Xint width; Xint ac; Xchar *av[]; Xint a0; Xstruct hotkey *head; X{ X struct hotkey *ptr; X char cmd[BUFSIZ]; X int n; X char *buf; X int maxlen; X int len0; X X (void) strcpy (cmd, av[a0]); X buf = cmd + strlen (cmd); X maxlen = BUFSIZ - strlen (cmd); X X for (n = a0 + 1; n < ac; ++n) { X len0 = strlen (av[n]) + 1; X if (len0 >= maxlen) { X (void) fprintf (stderr, X "Command string for key %d is too long\n", key); X exit (1); X } X (void) sprintf (buf, " %s", av[n]); X buf += len0; X maxlen -= len0; X } X X ptr = insert (head, key, height, width, cmd); X return (ptr); X X} X Xint Xdie (code) Xint code; X{ X X write_keyfile ((struct hotkey *) NULL); X (void) chown (KEY_FILE, 1, 1); X (void) chown (PID_FILE, 1, 1); X user_id = 1; X (void) signal (code, die); X X} X Xvoid Xterminate () X{ X int fd; X X for (fd = 0; fd < _NFILE; ++fd) { X (void) close (fd); X } X X exit (0); X X} X Xstatic int xloc = 0; Xstatic int yloc = 0; X Xvoid Xdo_hotkey (code) Xint code; X{ X int wd; X char *argv[BUFSIZ / 2]; X char *blank; X int argc; X int signo; X int temp; X char cmdbuf[BUFSIZ]; X struct uwdata uwdata; X struct utdata utdata; X struct hotkey *head; X struct hotkey *ptr; X X head = read_keyfile (KEY_FILE); X for (ptr = head; ptr != NULL; ptr = ptr -> h_next) { X if (ptr -> h_key == code) { X break; X } X } X X if (ptr == NULL) { X free_list (head); X return; X } X X wd = open ("/dev/window", 2); X if (wd == -1) { X free_list (head); X return; X } X X if (ioctl (wd, WIOCGETD, &uwdata) == -1) { X (void) close (wd); X free_list (head); X return; X } X X uwdata.uw_height = ptr -> h_height * uwdata.uw_vs; X uwdata.uw_width = ptr -> h_width * uwdata.uw_hs; X if (yloc == 0) { X yloc = uwdata.uw_vs; X } X uwdata.uw_x = xloc; X uwdata.uw_y = yloc; X xloc += (2 * uwdata.uw_hs); X yloc += (2 * uwdata.uw_vs); X if (xloc > (8 * uwdata.uw_hs)) { X xloc = 0; X yloc = 0; X } X if ((ptr -> h_height == 24) && (ptr -> h_width == 80)) { X uwdata.uw_uflags = NBORDER; X uwdata.uw_x = 0; X uwdata.uw_y = uwdata.uw_vs; X } X else { X uwdata.uw_uflags = BORDRESIZE; X if (uwdata.uw_x + uwdata.uw_width > WINWIDTH - (3 * uwdata.uw_hs)) { X temp = WINWIDTH - (3 * uwdata.uw_hs) - uwdata.uw_width; X if (temp < 0) { X temp = 0; X } X uwdata.uw_x = temp; X uwdata.uw_width = WINWIDTH - (3 * uwdata.uw_hs) - uwdata.uw_x; X } X if (uwdata.uw_y + uwdata.uw_height > WINHEIGHT - (4 * uwdata.uw_vs)) { X temp = WINHEIGHT - (4 * uwdata.uw_vs) - uwdata.uw_height; X if (temp < uwdata.uw_vs) { X temp = uwdata.uw_vs; X } X uwdata.uw_y = temp; X uwdata.uw_height = WINHEIGHT - (4 * uwdata.uw_vs) - uwdata.uw_y; X } X } X X if (ioctl (wd, WIOCSETD, &uwdata) == -1) { X (void) close (wd); X free_list (head); X return; X } X X utdata.ut_num = WTXTLABEL; X (void) strncpy (utdata.ut_text, ptr -> h_cmd, 40); X (void) ioctl (wd, WIOCSETTEXT, &utdata); X X (void) strcpy (cmdbuf, ptr -> h_cmd); X argc = 0; X blank = cmdbuf; X X while (blank != NULL) { X argv[argc++] = blank; X blank = strchr (blank, ' '); X if (blank != NULL) { X while (*blank == ' ') { X *blank++ = '\0'; X } X } X } X argv[argc] = NULL; X X if (fork () != 0) { X (void) close (wd); X free_list (head); X return; X } X X if (fork () != 0) { X _exit (0); X } X X (void) setpgrp (); X if (wd != 0) { X (void) close (0); X (void) dup (wd); X } X (void) close (1); X (void) dup (0); X (void) close (2); X (void) dup (0); X for (wd = 3; wd < _NFILE; ++wd) { X (void) close (wd); X } X (void) ioctl (0, WIOCPGRP, NULL); X for (signo = 1; signo < NSIG; ++signo) { X (void) signal (signo, SIG_DFL); X } X X (void) execvp (argv[0], argv); X (void) execl ("/bin/sh", "sh", "-c", ptr -> h_cmd, 0); X _exit (0); X X} X Xint Xatrap (code) Xint code; X{ X X (void) signal (code, atrap); X longjmp (abuff, 1); X X} X Xint Xrefresh (code) Xint code; X{ X X (void) signal (code, refresh); X need_wiocsys = 1; X longjmp (abuff, 1); X X} X X/* "12345678901234567890123456789012" */ X#define FKEY_MSG "Function Keys Active: ........ " X#define BLANKS " " X Xdisplay_keys (wd) Xint wd; X{ X struct hotkey *head; X struct hotkey *ptr; X char buf[33]; X int n; X int keys; X X head = read_keyfile (KEY_FILE); X X (void) strcpy (buf, FKEY_MSG); X keys = 0; X X for (ptr = head; ptr != NULL; ptr = ptr -> h_next) { X n = ptr -> h_key; X if ((n <= 0) || (n > 8)) { X continue; X } X buf[n + 21] = '0' + n; X ++keys; X } X if (keys == 0) { X (void) strcpy (buf, BLANKS); X } X (void) write (wd, "\r\n", 2); X (void) write (wd, buf, 31); X free_list (head); X X} X Xint Xis_owner (file, mod_time) Xchar *file; Xtime_t *mod_time; X{ X struct stat sbuf; X X if (stat (file, &sbuf) == -1) { X return (0); X } X X if (sbuf.st_uid != user_id) { X return (0); X } X X if (mod_time != NULL) { X *mod_time = sbuf.st_mtime; X } X X return (1); X X} X X/* mouse.c */ X X Xstruct umdata mouseinfo; Xstruct icon myicon; X Xvoid Xzapmouse (wd) Xint wd; X{ X X if (ioctl (wd, WIOCGETMOUSE, &mouseinfo) == -1) { X return; X } X X mouseinfo.um_icon = &myicon; X X (void) ioctl (wd, WIOCSETMOUSE, &mouseinfo); X} END_OF_FILE if test 14790 -ne `wc -c <'hotkey.c'`; then echo shar: \"'hotkey.c'\" unpacked with wrong size! fi # end of 'hotkey.c' fi if test -f 'hotkey.sample' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hotkey.sample'\" else echo shar: Extracting \"'hotkey.sample'\" \(170 characters\) sed "s/^X//" >'hotkey.sample' <<'END_OF_FILE' X1,15,72 ksh X2,15,72 /u/dave/cmd/root.sh X3,15,72 /u/dave/cmd/uucp.sh X4,04,20 uusnap X5,04,20 scrtoggle X6,04,20 calculatr X7,24,80 pcomm.sh -f rayssdb X8,24,80 /u/dave/cmd/rn END_OF_FILE if test 170 -ne `wc -c <'hotkey.sample'`; then echo shar: \"'hotkey.sample'\" unpacked with wrong size! fi # end of 'hotkey.sample' fi if test -f 'makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile'\" else echo shar: Extracting \"'makefile'\" \(479 characters\) sed "s/^X//" >'makefile' <<'END_OF_FILE' X# Makefile for hotkey program X# David H. Brierley - dave@galaxia.newport.ri.us X XINSDIR = /usr/local/bin XCFLAGS = -O X X# No attempt is made here to link with shared libraries. If you have ccc, X# ccs, shcc, etc then simply build the program by typing "make CC=ccc" and X# the shared libaries will automatically be used. X Xhotkey: hotkey.o X $(CC) hotkey.o X mv a.out hotkey X Xinstall: hotkey X rm -f $(INSDIR)/hotkey X strip hotkey X mv hotkey $(INSDIR)/hotkey X chmod 711 $(INSDIR)/hotkey END_OF_FILE if test 479 -ne `wc -c <'makefile'`; then echo shar: \"'makefile'\" unpacked with wrong size! fi # end of 'makefile' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- David H. Brierley Home: dave@galaxia.Newport.RI.US {rayssd,xanth,lazlo,mirror}!galaxia!dave Work: dhb@rayssd.ray.com {sun,decuac,gatech,necntc,ukma}!rayssd!dhb