Hotkey program for 7300/3B1
David H. Brierley
dave at galaxia.Newport.RI.US
Mon May 22 12:41:21 AEST 1989
Here is the hotkey program for the 7300/3B1 that I mentioned a couple of
months ago. Sorry it took so long but I decided I should write some
documentation for it before releasing it and I just never had the time.
A quick one line summary of the program might be "this program allows
you to bind programs to the shifted function keys". Read the README and
the man page for more details.
======= cut here ======
#! /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 at 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 at 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 at 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 at 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 at galaxia.Newport.RI.US {rayssd,xanth,lazlo,mirror}!galaxia!dave
Work: dhb at rayssd.ray.com {sun,decuac,gatech,necntc,ukma}!rayssd!dhb
More information about the Unix-pc.sources
mailing list