ain@j.cc.purdue.edu (Patrick White) (05/19/88)
Submitted by: rodger@hpmrtca (Rodger Anderson) Summary: A mouse accelerator and more. Poster Boy: Patrick White (ain@j.cc.purdue.edu) Archive Name: sources/amiga/volume4/mach.doc.sh.Z binaries/amiga/volume5/mach.doc.sh.Z Tested but uncompiled. NOTES: Rob or Brent tested this but didn't give me any notes about it, so I assume that it works just fine. I converted it from an arc to shars so I could separate docs, sources, and binaries. . -- Pat White (co-moderator comp.sources/binaries.amiga) ARPA/UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== >The author is Brian Moats of Polyglot software. I am merely posting >Mach to usenet, with Brian's permission. Brian doesn't have usenet >access, although he is on PeopleLink and Compuserve (see doc file). >I will forward anything I get. My uucp address is below. > >Hotkeys: > Defines the function keys (with qualifier) to be any string. >Mouse Accelerator: > Like the Gizmos one. >NewCLI: > Like PopCLI. >Screen Blanker: > Like PopCLI. >Sun Mouse: > Window under mouse always active. >Click To Front: > Should be obvious. >Screen Shuffler: > Cycles through each screen, instead of just Workbench. >Clock: > Machclk version has title bar clock. >Meter: > Mackclk has resettable $/hr meter for online time. > >Each feature can be enabled or disabled as needed, either at startup or while >running. Qualifier can be left-amiga or left-alt. # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Mach.doc # This archive created: Tue May 17 09:26:35 1988 # By: Patrick White (PUCC Land, USA) echo shar: extracting Mach.doc '(13285 characters)' cat << \SHAR_EOF > Mach.doc Mach - Mouse Accelerator with Hotkey. Version 1.6 02-01-88. MachClk - Mach + Title Bar Clock and Beeper. Version 1.2 02-01-88. NOTES: 1. Mach is identical to MachClk minus the clock. Features that apply only to MachClk are so noted. 2. References in this document to "Qualifier" means either the left or right Alternate or Amiga keys depending on whether or not you use "-a" on the command line. 3. When used on the command line, function keys are single digits. 1 is F1, 2 is F2, 9 is F9, and 0 is F10. 4. Main difference from 1.5 is the change of -d to -q which now accumulates qualifiers to be added to the next key. Unused hotkeys are passed on. Also, it should not lock up when holding an icon. USAGE: Run Mach [nscmqaeb] hotkeystring hotkeystring...hotkeystring or Run Mach [nscmqaeb] +1hotkeystring +2hotkeystring...+nhotkeystring or Run MachClk [nscmqaebktp] hotkeystring hotkeystring...hotkeystring or Run MachClk [nscmqaebktp] +1hotkeystring +2hotkeystring...+nhotkeystring Options: All are optional. Any order. They may be concatenated but an option with an argument should be the last one. e.g. Mach -scb10 (sun mouse, clicktofront and blanker) -n Acceleration factor where n >= 0 && n <=9. -s Removes sunmouse. -c Removes click to front. -m Removes the trapping of left-amiga-m. (allows normal use) -q Adds qualifier accumulator feature. -a Use the Amiga keys as qualifiers. -estr Use str as execute string. Default is "NewCLI >nil: <nil:". -bnn Time delay before blanking screen. 0-99 minutes. 0 = no blank. -knnn Put Clock left edge at nnn. (MachClk only) -tnn Beep every nn minutes. Default 15. (MachClk only) -pnnnn Set online rate. nnnn = pennies per hour. Default = 475. Hotkeys: The hotkeys are the keys F1 to F10 qualified with the left or right alternate keys. If you prefer to use left or right Amiga, put -a on the command line. This makes it more compatible with WordPerfect and other programs that make use of alternate-function keys. The escape character "\" may be used to introduce newline or a function key or to add qualifiers. \n newline \c control \a alternate \A Amiga \s shift \f function key where f is 1-0 = F1-F10 c, a, A, s modifiy the next letter. They can be combined. c, s, and n may be upper case. Examples: \C\a\3 is Control-Alternate-F3. \A\0 sends Amiga-F10. Hotkeys may call other hotkeys. The hotkeys are defined in the command line following the optional options. Definitions with embedded spaces should use "". They may be positional, that is, the first definition is matched with F1 and the second with F2. Or, you may specify a function key with +n. n = 1 - 0 with 0 equaling 10 and no spaces following the key number. e.g. Run Mach "+5diskcopy df0: to df1:\n" See more examples below. You may redefine hotkeys by running Mach again with new definitions. e.g. Mach +3dir\n "+0run df1:wp\n" Function keys not assigned to a hotkey string are passed through. Accelerator: The accelerator speeds up mouse movements. It accepts as an argument a number, 0-9, which sets its speed. -1 is the default, -0 = no acceleration. (I use -4). NewCLI: The qualifier and ESCape combination will create a NewCLI a la PopCLI from The Software Distillary. You need to have NewCLI and Run in the c: directory. The NewCLI will have the same size stack as Mach. You can change the command that is executed with -estring. A full window can be used with "-eNewCLI CON:0/0/640/200/MyCLI". Screen Blanker: After 5 minutes of no mouse or keyboard activity, the screen will go blank. You can change this default with -bnn where nn = 0 - 99 minutes. 0 disables blanking. Instant blanking: Control-Qualifier-F2. Sun Mouse: The window that the pointer is over becomes the active window after the first mouse movement. To be able to drag icons, the sun mouse is disabled while the left button is held down. If you don't want the sun mouse, use -s on the command line. On/off toggle: Control-Qualifier-F3. Click To Front: You can click in any part of a window and bring it to the front. If you don't want this, use -c on the command line. On/off toggle: Control-Qualifier-F4. Screen Shuffler: Left-Amiga-M will push the front screen to the back instead of pushing workbench to the back. Left-Amiga-N will still bring the workbench to the front. This is useful if you have more than two screens on at once, especially if they don't have screen depth gadgets. If you don't want this feature, use -m on your command line. On/off toggle: Control-Qualifier-F5. Clock: MachClk has a title bar clock that displays available memory and the time. You can change its left edge position with -knnn. For no clock use -k0 or -k. The clock is updated every second and brings itself to the front (if covered up) every 4 seconds except when the left button is held down. The current toggles are shown in the left corner. They are s: sun mouse, c: click to front, m: Amiga-M screen shuffler, d: double control, a: Alternate/Amiga qualifiers. On/off toggle: Control-Qualifier-F8. Beeper: MachClk (when the clock is activated) has a beeper (to keep you awake) which defaults to a 15 minute interval. Change this with -tnn. nn = 0 to 60 minutes. Meter: MachClk has an online cost meter. Use Control-Qualifier-F9 to toggle between the meter and the clock. Use Control-Qualifier-F10 to reset the meter. The rate that it uses may be set with "-pnnnn". nnnn is in pennies per hour. The meter runs continuously whether visible or not. The default rate is $4.75. On/off toggle: Control-Qualifier-F9. Uninstall: Use the combination Control-Qualifier-F1 to uninstall Mach or MachClk. Toggles: These key combinations can be used to toggle specific features. Ctl-Qualifier- F3 Sun mouse. F4 Click to front. F5 Screen shuffle. F6 Qualifier Accumulator. F7 Alternate/Amiga qualifiers. F8 Clock. (MachClk only) F9 Meter. (MachClk only) F10 Reset meter. (MachClk only) F3-F7 are displayed in the clock as [scmqa]. Instant blanker: Ctl-Qualifier-F2 Causes the screen to go blank immediately. EXAMPLES: Run Mach -2 -m -s df0: df1: "dir\n" "copy " "" "run sys:system/rollodex" This maps Alternate-F1 to df0: Alternate-F2 to df1: Alternate-F3 to dir + return Alternate-F4 to copy Alternate-F5 to nothing Alternate-F6 to run sys:system/rollodex The options set the acceleration factor to 2, allows the normal use of Left-Amiga-M, and disables the sun mouse feature. Run MachClk -0cab12 "run df1:wp\n" +5df0: \s\c\1 \c\A\0 dir\n\A\1 This maps Amiga-F1 to run df1:wp + return Amiga-F5 to df0: Amiga-F6 to Shift-Control-F1 Amiga-F7 to Control-Amiga-F10 Amiga-F8 to dir + return + Amiga-F1 This example shows how to concatenate options (-0cab12). The options set the acceleration factor to 0, the function key qualifiers to the Amiga keys, disables the click to front feature, and sets the waiting before blanking to 12 minutes. The clock is placed in its default position and the beeper interval is the default 15 minutes. Run MachClk -k200 -t30 -4 -a "diskcopy df0: to df1:\n" This maps Amiga-F1 to diskcopy df0: to df1: + return The options use 200 for the clock's left edge, sets the beeper interval to 30 minutes, the acceleration factor to 4, and the qualifiers to the Amiga keys. Run MachClk -p525 This set the online rate to $5.25. REDEFINING: Mach may be run again to redefine hotkeys or set the blanking time delay or the beep interval or to change the toggles. For example, after Mach is running, typing "Mach -6 +5df0:" will change the acceleration factor to 6 and redefine F5 to "df0:". Only the clock position may not be changed this way. Mach -b10 -p650 +3CCC +2BBB +5EEE FFF This redefines Qualifier-F2 to BBB Qualifier-F3 to CCC Qualifier-F5 to EEE Qualifier-F6 to FFF resets the blanking delay to 10 minutes, and set the online rate to $6.50. Mach -eWack This changes the Qualifier-ESCape command from NewCLI to Wack. Remember, the executed command will have the same size stack as Mach. MISCELLANEOUS: Note that anything after a semicolon is treated as a comment. If you are typing this in from the CLI, when you reach the end of the line, don't hit return and you can continue mapping up to 255 characters (including run mach [options]). If you are using an editor or word processor, use one that can handle long lines. You can use Ed but you need to use the command SR or EX. You can then put this in your startup-sequence. I have found that the hotkeys do not function properly with the program Sili(Con:). But they do work ok with ConMan. There seems to be some slight problems with SunMouse and the shareware disk utility DiskMan. Let me know if you find other incompatibilities. Mach may fail to run for any number of reasons (e.g. no free signals, insufficient memory). You will be informed of this if it is started with the Run command. If started from RunBack or RunBackGround (public domain program that will allow the CLI window to close and available on Fred Fish disk # 65) Mach won't run and you won't get any messages. If you want to use RunBack, it is best to test your script first with Run. The NewCLI brought up by Qualifier-ESC will have a stack the same size as Mach. Many programs that you may run from this CLI need a larger stack so either run Mach with a larger stack or, after you get a NewCLI, use the stack command to set your stack to a larger value. If programs mysteriously crash when run from the NewCLI, it may be caused by the stack size. Hidden Qualifier Feature: Many disabled people find it difficult if not impossible to type key combinations such as Control-Shift-F1. If you put -q on the command line, Mach will remember qualifiers that are pressed and add them to the first non-qualifier key pressed. So you could for example, type Control, Alternate, and then F1. The Control and Alternate would be added to the F1 just as if they were pressed at the same time. This is not for someone who doesn't need it as it sometimes may cause unexpected results like if you type Control and then change your mind, the Control will still be added to the next key pressed. Pressing Caps Lock will reset the qualifier accumulator. Note that because most people will not want this, it defaults to off unlike all the other features. On/off toggle: Control-Qualifier-F6. Copyright 1988 by Brian Moats Polyglot Software 10431 Ardyce Court Boise, Idaho 83704 PeopleLink - BrianM CI$ - 76167,2334 This program may be freely distributed but may not be used in any commercial product without prior written permission. Source available. Donations accepted. Other programs from Polyglot Software: M18Cheater - Lets you cheat in Mean 18 by causing your opponent to slice. Public domain. FunBut - Lets you use the F1 key instead of the left mouse button. It's useful when playing games like Defender of the Crown because it sends repeat mouse clicks. Public Domain. Dominoes - 3d graphics, instructions, tutorial. More entertaining and challenging than Shanghai. $24.95 The Crossword Creator - Make or solve crossword puzzles. 40,000+ word pattern matching dictionary, med-res or interlace, IFF compatible and many more features. $49.95 SHAR_EOF if test 13285 -ne "`wc -c Mach.doc`" then echo shar: error transmitting Mach.doc '(should have been 13285 characters)' fi # End of shell archive exit 0
ain@j.cc.purdue.edu (Patrick White) (05/20/88)
Submitted by: rodger@hpmrtca (Rodger Anderson) Summary: A mouse accelerator and more. Poster Boy: Patrick White (ain@j.cc.purdue.edu) Archive Name: sources/amiga/volume5/mach.src.sh.Z Tested but uncompiled. NOTES: Rob or Brent tested this but didn't give me any notes about it, so I assume that it works just fine. I converted it from an arc to shars so I could separate docs, sources, and binaries. . -- Pat White (co-moderator comp.sources/binaries.amiga) ARPA/UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== >The author is Brian Moats of Polyglot software. I am merely posting >Mach to usenet, with Brian's permission. Brian doesn't have usenet >access, although he is on PeopleLink and Compuserve (see doc file). >I will forward anything I get. My uucp address is below. > >Hotkeys: > Defines the function keys (with qualifier) to be any string. >Mouse Accelerator: > Like the Gizmos one. >NewCLI: > Like PopCLI. >Screen Blanker: > Like PopCLI. >Sun Mouse: > Window under mouse always active. >Click To Front: > Should be obvious. >Screen Shuffler: > Cycles through each screen, instead of just Workbench. >Clock: > Machclk version has title bar clock. >Meter: > Mackclk has resettable $/hr meter for online time. > >Each feature can be enabled or disabled as needed, either at startup or while >running. Qualifier can be left-amiga or left-alt. # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Mach.c # This archive created: Tue May 17 09:27:28 1988 # By: Patrick White (PUCC Land, USA) echo shar: extracting Mach.c '(36699 characters)' cat << \SHAR_EOF > Mach.c /* Mach1.6 - Mouse Accelerator with Hotkey **** 02-01-88 **** MachClk1.2 - and clock with beeper and meter. Copyright 1988 by Brian Moats @Polyglot Software. This program may be freely distributed providing that the copyright notice and document file are included. It may not be used in any commercial product without prior written permission. run mach [nambscqekp] hotkeystring hotkeystring...hotkeystring Arguments: All optional. Any order. -n Accelerator factor where n >= 0 && n <=9. -a Switchs hotkey qualifier from Alternate to Amiga. -m Removes the trapping of left-amiga-m. (allows normal use) -bnnn Time delay before blanking screen. 0-999 minutes. 0 = no blank. -s Removes sunmouse. -c Removes click to front. -q Adds qualifier accumulating feature. -estr Use str as execute command string. Default = NewCLI. -knnn nnn > 0 put clock left edge at nnn. If nnn = 0, don't use clock. -tnn Set beep time interval to every nn minutes. -pnnnn Set online rate. nnnn = pennies per hour. Default = 475. Usage eg. Run Mach -3 -m -a -b10 df0: df1: copy dir\n rename "blank space" Problem: The uninstall "Control-Qualifier-F1" and the Instant Screen Blanker don't work right if defined in a hotkey. e.g. \c\A\2 doesn't blank the screen and \c\A\1 doesn't uninstall correctly. How to build this: Simple (with Manx). I used version 3.4. cc machclk ln machclk.o -lc Changes from version 1.5: 1. Uses UpfrontLayer() instead of WindowToFront() for the clock to prevent lockups. Before, I was keeping track of the left mouse button and not doing a WindowToFront() if the button was down because you may be holding an icon. But...WindowToFront() doesn't actually happen until the next event and if it happened that that event was a left button down on an icon, bingo! it locks up. Sigh...live and learn. 2. Allocate 1 byte for null in hotkey and execute definitions. 3. Changed double control feature. Now you use -q. When you do, any shift, alternate, amiga or control key is added to the next non- qualifier key. This is intended primarily for disabled people who find it difficult, if not impossible, to hold down two or more keys at once. This accumulates qualifiers so you can hit for example, control, shift, alternate and then F1. This is the same as typing them at the same time. Hitting Caps Lock will reset the accumulator. 4. Return value (rv) changed to long. If there is an error and if short, it will crash when run from Runback but will set the returncode when run from Run. If long, it won't crash but won't set the returncode when run from Run. ??? Any ideas? */ #define USINGCLOCK /* take this out if you don't want the clock */ #include <devices/audio.h> #include <devices/input.h> #include <devices/inputevent.h> #include <devices/timer.h> #include <exec/types.h> #include <exec/interrupts.h> #include <exec/memory.h> #include <exec/ports.h> #include <graphics/gfxmacros.h> #include <intuition/intuitionbase.h> #include <libraries/dos.h> #include <functions.h> /* key codes that we need */ #define F1 0x50 #define F2 0x51 #define F3 0x52 #define F4 0x53 #define F5 0x54 #define F6 0x55 #define F7 0x56 #define F8 0x57 #define F9 0x58 #define F10 0x59 #define MCODE 0x37 /* "M" key code */ #define ESC 0x45 #define BACKSLASH 0x0d #define LSHIFT 0x60 #define RSHIFT 0x61 #define CTL 0x63 #define LALT 0x64 #define RALT 0x65 #define LAMIGA 0x66 #define RAMIGA 0x67 /* event signals */ #define QUIT 0x1 #define HOTKEY 0x2 #define ACCELERATE 0x4 #define BACKSCREEN 0x8 #define NEWCLI 0x10 #define UNBLANK 0x20 #define BLANK 0x40 #define SUN 0x80 #define CLICKTF 0x100 #define CLOCK 0x200 #define FIVE_MINUTES 300 /* 300 seconds */ #define WAIT_TIME 1000000L /* 1 second (in micro seconds) */ #define CAPSRPTMASK 0x05fb /* capslock & repeat masked */ #define CTLCAPSRPTMASK 0x05f3 /* control, capslock and repeat masked */ #ifdef USINGCLOCK char info[] = "MachClk 1.2 \xa9 1988 by Brian Moats @Polyglot Software.\n"; char usage[] = "\n\ Usage: Run MachClk [nscmqaebktp] hotkeystring hotkeystring...hotkeystring\n\ -n Acceleration factor. n >= 0 && n <=9.\n\ -s Removes sunmouse.\n\ -c Removes click to front.\n\ -m Allows normal use of Left-Amiga-M.\n\ -q Adds qualifier accumulating feature.\n\ -a Set qualifier from Alternate to Amiga.\n\ -estr Use str as execute command string. Default = NewCLI.\n\ -bnnn Time delay before blanking screen. 0 = no blank.\n\ -knnn nnn > 0 put clock left edge at nnn. If nnn = 0, don't use clock.\n\ -tnn Set beep time interval to every nn minutes.\n\ -pnnnn Set online rate. nnnn = pennies per hour. Default = 475.\n\n\ Control-Qualify-Function Key Toggles:\n\ F1 Remove, F2 Instant Blank, F3 Sun Mouse, F4 ClickToFront,\n\ F5 Screen Shuffler, F6 Qualifier Accumulator, F7 Alternate/Amiga,\n\ F8 Clock, F9 Meter, F10 Meter Reset.\n\n"; char reminfo[] = ">>> Use Control-Qualifier-F1 to remove MachClk. <<<\n"; char die[] = "MachClk 1.2 removed.\n"; char updated[] = "MachClk 1.2 updated.\n"; char failed[] = "MachClk 1.2 failed.\n"; #else /* Otherwise use this stuff */ char info[] = "Mach 1.6 \xa9 1988 by Brian Moats @Polyglot Software.\n"; char usage[] = "\n\ Usage: Run Mach [nscmqaeb] hotkeystring hotkeystring...hotkeystring\n\ -n Acceleration factor. n >= 0 && n <=9.\n\ -s Removes sunmouse.\n\ -c Removes click to front.\n\ -m Allows normal use of Left-Amiga-M.\n\ -q Adds qualifier accumulating feature.\n\ -a Set qualifier from Alternate to Amiga.\n\ -estr Use str as execute command string. Default = NewCLI.\n\ -bnnn Time delay before blanking screen. 0 = no blank.\n\n\ Control-Qualify-Function Key Toggles:\n\ F1 Remove, F2 Instant Blank, F3 Sun Mouse, F4 ClickToFront,\n\ F5 Screen Shuffler, F6 Qualifier Accumulator, F7 Alternate/Amiga.\n\n"; char reminfo[] = ">>> Use Control-Qualifier-F1 to remove Mach. <<<\n"; char die[] = "Mach 1.6 removed.\n"; char updated[] = "Mach 1.6 updated.\n"; char failed[] = "MachClk 1.6 failed.\n"; #endif char badarg[] = "\n>>> Bad arguments <<<\n"; char PortName[] = "Mach Port"; char DefECommand[] = "NewCLI >NIL: <NIL:"; short dx,dy; /* mouse acceleration delta x y */ short x,y; /* sunmouse and clicktofront position */ /* event info */ short keyCount = 0; /* # of function keys pressed in 1 event chain */ short kt[10]; /* 10 function keys max */ short event; /* signal all of the above defined events */ short lastcode = 0; /* last keypressed code that was removed from event chain */ long sec,micro; /* previous second and micro */ short noevent; /* # of seconds of no events */ short buttonisdown = 0; /* maintain left button state */ short canClock = 1; /* running the title bar clock */ short canMeter = 0; /* not showing online meter */ short lastMin = 61; /* init to impossible # of minutes */ short addQual = 0; /* qualifier to add */ short blanking = 0; /* not blanking now */ struct MsgPort *inputPort = NULL; struct IOStdReq *inputReq = NULL; struct MsgPort *TimerPort = NULL; struct Screen *s,*blankS = NULL; struct Window *mw = NULL; struct Layer *ml; struct IntuitionBase *IntuitionBase = NULL; struct LayersBase *LayersBase = NULL; struct GfxBase *GfxBase = NULL; struct FileHandle *msgfh, *nullfh = NULL; struct NewScreen newScreen = {0,0,320,30,1,0,0,NULL,CUSTOMSCREEN, NULL,NULL,NULL,NULL}; struct timerequest Timer_Req; long TimerSig,tdevice = 1; struct InputEvent phoney; struct HotInfo { struct Task *hotTask; long hotSig; } hotStuff; long signum = -1; struct Interrupt handlerStuff; /* This MsgPort holds all function key definitions and other variables that can be changed by running the program again. */ struct defPort { struct MsgPort mp; char * func[10]; /* pointers to 10 hotkey strings */ char * ECommand; /* pointer to command to execute with qualifier esc */ short acc; /* acceleration factor */ short ourLQual; /* the qualifiers being used */ short ourRQual; short canSun; /* sunning toggle */ short canFront; /* click to front toggle */ short canShuffle; /* amiga-m toggle */ short canAddQuals; /* qualifier adding toggle */ short alternate; /* alternate or amiga key toggle */ short blanktime; /* how long to wait before blanking */ #ifdef USINGCLOCK short rate; /* online rate */ short beepInterval; /* how long to wait between beeps */ #endif }; struct defPort *defPortPtr; char defPortName[] = "Definition Port"; short updating = 0; /* set to 1 if we updated (actually just found) defPort. */ /* Clock stuff */ #ifdef USINGCLOCK #define SCREENWIDTH 640 #define WINDOWWIDTH 346 #define LEFTEDGE SCREENWIDTH-54-WINDOWWIDTH struct NewWindow newWindow = { LEFTEDGE, 0, WINDOWWIDTH, 10, -1, -1, 0, /* No IDCMP messages */ WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; char TimeBuffer[49]; struct IntuiText TimeText = {1,0,JAM2,0,0, NULL, (UBYTE *)TimeBuffer, NULL }; struct Window *ClockWindow = NULL; short clockEdge = LEFTEDGE; /* default position */ short cost; /* online costs */ #endif /* end of clock stuff */ /* character translation table. Key codes in ascii order with bit 8 */ /* set for upper case. e.g. Shift 1 is exclamation mark and is */ /* key code 01, 2nd entry in table with bit 8 set. 0x101 */ USHORT keytran[96] = {0x140,0x101,0x12a,0x103,0x104,0x105,0x107,0x12a,0x109,0x10a, 0x108,0x10c,0x38,0x0b,0x39,0x3a,0x0a,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,0x08,0x09,0x129,0x29,0x138,0x0c, 0x139,0x13a,0x102,0x120,0x135,0x133,0x122, 0x112,0x123,0x124,0x125,0x117,0x126,0x127,0x128,0x137,0x136,0x118, 0x119,0x110,0x113,0x121,0x114,0x116,0x134,0x111,0x132,0x115,0x131,0x1a, 0x0d,0x1c,0x106,0x10b,0x00,0x20,0x35,0x33,0x22,0x12, 0x23,0x24,0x25,0x17,0x26,0x27,0x28,0x37,0x36,0x18, 0x19,0x10,0x13,0x21,0x14,0x16,0x34,0x11,0x32,0x15, 0x31,0x11a,0x10d,0x11b,0x100}; void HandlerInterface() { #asm movem.l a4,-(sp) ;Manx small code/small data needs to jsr _geta4# ;set up a4 to get at global data. movem.l A0/A1,-(sp) jsr _myhandler addq.l #8,A7 movem.l (sp)+,a4 ;Manx needs this to. ;No rts. Manx adds it. #endasm } /* The C handler routine. It's pretty long but each event is actually taken care of with just a few decisions. */ struct InputEvent *myhandler(ev1, hotStuff) struct InputEvent *ev1; struct HotInfo *hotStuff; { struct InputEvent *ev, *last; short removeit; short evcode,evqual; event = 0; Forbid(); for (ev=ev1,last = NULL; ev; ev=ev->ie_NextEvent) { evcode = ev->ie_Code; /* cause these are accessed so often... */ evqual = ev->ie_Qualifier; /* ...it saves bytes to get'em once */ removeit = 0; if ((ev->ie_Class != IECLASS_TIMER)) { noevent = 0; if (blanking) event |= UNBLANK; /* Not TIMER and screen is blank, need to un-blank */ if (ev->ie_Class == IECLASS_RAWKEY) if (evcode >= 0x80) { event &= !UNBLANK; /* BUT don't unblank on upkey */ if (evcode == (lastcode | 0x80)) /* remove if keypressed was removed */ { removeit = 1; lastcode = 0; } } else /* This is where we collect qualifiers to add */ { if (defPortPtr->canAddQuals) if ((evcode >= LSHIFT) && (evcode <= RAMIGA)) { lastcode = evcode; removeit = 1; switch (evcode) { case LSHIFT: addQual |= IEQUALIFIER_LSHIFT; break; case RSHIFT: addQual |= IEQUALIFIER_RSHIFT; break; case CTL: addQual |= IEQUALIFIER_CONTROL; break; case LALT: addQual |= IEQUALIFIER_LALT; break; case RALT: addQual |= IEQUALIFIER_RALT; break; case LAMIGA: addQual |= IEQUALIFIER_LCOMMAND; break; case RAMIGA: addQual |= IEQUALIFIER_RCOMMAND; break; default: lastcode = 0; removeit = 0; addQual = 0; /* Caps Lock gets here so lets nullify all */ break; /* qualifiers. */ } } else /* if code is not alt, amiga or shift */ { /* add any qualifiers that there may be. */ evqual |= addQual; ev->ie_Qualifier |= addQual; addQual = 0; } if (((evcode >= F1) && (evcode <= F10)) || (evcode == ESC)) { if (((evqual & CTLCAPSRPTMASK) == defPortPtr->ourLQual) || ((evqual & CTLCAPSRPTMASK) == defPortPtr->ourRQual)) { lastcode = evcode; if (evqual & IEQUALIFIER_CONTROL) /* qualifier+control+function */ { switch (evcode) { case F1: removeit = 1; event |= QUIT; break; case F2: removeit = 1; event |= BLANK; break; case F3: removeit = 1; defPortPtr->canSun = !defPortPtr->canSun; break; case F4: removeit = 1; defPortPtr->canFront = !defPortPtr->canFront; break; case F5: removeit = 1; defPortPtr->canShuffle = !defPortPtr->canShuffle; break; case F6: removeit = 1; defPortPtr->canAddQuals = !defPortPtr->canAddQuals; break; case F7: removeit = 1; defPortPtr->alternate = !defPortPtr->alternate; if (defPortPtr->alternate) { defPortPtr->ourLQual = IEQUALIFIER_LALT; defPortPtr->ourRQual = IEQUALIFIER_RALT; } else { defPortPtr->ourLQual = IEQUALIFIER_LCOMMAND; defPortPtr->ourRQual = IEQUALIFIER_RCOMMAND; } break; #ifdef USINGCLOCK case F8: removeit = 1; canClock = !canClock; event |= CLOCK; break; case F9: removeit = 1; canMeter = !canMeter; break; case F10: removeit = 1; cost = 0; break; #endif default: lastcode = 0; /* no down key we want to remove upkey of */ } } else /* qualifier + ESC or function */ { if (evcode == ESC) { removeit = 1; event |= NEWCLI; } else { if (defPortPtr->func[evcode - F1]) { removeit = 1; if (keyCount < 10) { kt[keyCount++] = evcode; /* save f key */ event |= HOTKEY; } } } } } } else if (defPortPtr->canShuffle && (evcode == MCODE)&&((evqual & IEQUALIFIER_LCOMMAND) == IEQUALIFIER_LCOMMAND)) { lastcode = evcode; removeit = 1; event |= BACKSCREEN; } } /* end of RAWKEY stuff */ if (ev->ie_Class == IECLASS_RAWMOUSE) { if (evcode == IECODE_LBUTTON) /* keep track of left button. Up or */ buttonisdown = 1; /* down. Don't sun mouse or send clock to front */ /* when down */ if (defPortPtr->canSun || defPortPtr->canFront) { s = IntuitionBase->FirstScreen; while (s && (s->MouseY < 0)) s = s->NextScreen; if (s == NULL) s = IntuitionBase->ActiveScreen; x = s->MouseX + ev->ie_X; y = s->MouseY + ev->ie_Y; if ((defPortPtr->canSun) && !buttonisdown) /* don't sun while button is down */ event |= SUN; if ((defPortPtr->canFront) && (ev->ie_Code == IECODE_LBUTTON)) event |= CLICKTF; } if (evcode == (IECODE_LBUTTON | 0x80)) /* Now set button up if it is */ buttonisdown = 0; if ((ev->ie_TimeStamp.tv_secs == sec) && ((ev->ie_TimeStamp.tv_micro / 50000) == micro)) { dx = ev->ie_X; /* only accel if 2 mouse moves in 1/20 second */ dy = ev->ie_Y; event |= ACCELERATE; } if (ev->ie_TimeStamp.tv_secs) /* writeevent sets sec=0 */ { micro = ev->ie_TimeStamp.tv_micro / 50000; sec = ev->ie_TimeStamp.tv_secs; } } } /* if not timer event */ /* all events get here */ if (removeit) if (last == NULL) /* remove from event chain */ ev1 = ev->ie_NextEvent; else last->ie_NextEvent = ev->ie_NextEvent; else last = ev; } /* for */ if (event) Signal(hotStuff->hotTask,hotStuff->hotSig); Permit(); return(ev1); } main(argc, argv) short argc; char *argv[]; { struct IntuiMessage *Msg; long class; long len; short i,j,f,c; msgfh = Output(); if (msgfh) { (void)Write(msgfh,info,(long)sizeof(info)); if ((argv[1][0] == '?') || (argc < 2)) { (void)Write(msgfh,usage,(long)sizeof(usage)); if (argc < 2) (void)Write(msgfh,reminfo,(long)sizeof(reminfo)); exit(0); } } IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L); GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L); LayersBase = (struct LayersBase *) OpenLibrary("layers.library",0L); defPortPtr = (struct defPort *) FindPort(defPortName); if (defPortPtr == NULL) { if ((defPortPtr = (struct defPort *) AllocMem((long)sizeof(struct defPort),MEMF_PUBLIC | MEMF_CLEAR)) == NULL) exit(10); defPortPtr->acc = 1; /* default acceleration rate */ defPortPtr->ourLQual = IEQUALIFIER_LALT; defPortPtr->ourRQual = IEQUALIFIER_RALT; /* Defaults to Alternate qualifiers */ defPortPtr->canSun = 1; defPortPtr->canFront = 1; defPortPtr->canShuffle = 1; defPortPtr->canAddQuals = 0; defPortPtr->alternate = 1; defPortPtr->blanktime = FIVE_MINUTES; #ifdef USINGCLOCK defPortPtr->beepInterval = 15; /* minutes */ defPortPtr->rate = 475; /* default peoplelink rate */ #endif if ((defPortPtr->ECommand = AllocMem((long)sizeof(DefECommand),MEMF_PUBLIC)) != NULL) strcpy(defPortPtr->ECommand,DefECommand); } else updating = 1; /* Port found so we must be updating it */ for (i = 1,f = 0; i < argc && f <= 9; i++) if (argv[i][0] == '-') { j = 1; while (argv[i][j]) /* parse multiple options with one leading "-" */ { if ((argv[i][j] >= '0') && (argv[i][j] <= '9')) /* Accelerating arg? */ defPortPtr->acc = (argv[i][j++] & 0x0f); else if ((argv[i][j] & 0x5f) == 'M') /* Don't want screen shuffler? */ { defPortPtr->canShuffle = 0; j++; } else if ((argv[i][j] & 0x5f) == 'A') /* Want Amiga qualifier? */ { defPortPtr->alternate = 0; defPortPtr->ourLQual = IEQUALIFIER_LCOMMAND; defPortPtr->ourRQual = IEQUALIFIER_RCOMMAND; j++; } else if ((argv[i][j] & 0x5f) == 'S') /* Don't want sunmouse? */ { defPortPtr->canSun = 0; j++; } else if ((argv[i][j] & 0x5f) == 'C') /* Don't want ClickToFront? */ { defPortPtr->canFront = 0; j++; } else if ((argv[i][j] & 0x5f) == 'B') /* Got blanking arg? */ { defPortPtr->blanktime = atoi(&argv[i][j+1]) * 60; while (argv[i][++j]) ; } else if ((argv[i][j] & 0x5f) == 'Q') /* Want to add up qualifiers? */ { defPortPtr->canAddQuals = 1; /* this one defaults to off. */ j++; } else if ((argv[i][j] & 0x5f) == 'E') /* Got execute command? */ { if (defPortPtr->ECommand) /* free old command */ FreeMem(defPortPtr->ECommand,(long)strlen(defPortPtr->ECommand)+1); if (defPortPtr->ECommand = AllocMem((long)strlen(&argv[i][j+1])+1,MEMF_PUBLIC)) strcpy(defPortPtr->ECommand,&argv[i][j+1]); while (argv[i][++j]) ; } #ifdef USINGCLOCK else if ((argv[i][j] & 0x5f) == 'K') /* Clock stuff? */ { clockEdge = atoi(&argv[i][j+1]); if (clockEdge == 0) /* 0 or no number means no clock */ canClock = 0; while (argv[i][++j]) ; } else if ((argv[i][j] & 0x5f) == 'T') /* Beep interval? */ { defPortPtr->beepInterval = atoi(&argv[i][j+1]); while (argv[i][++j]) ; } else if ((argv[i][j] & 0x5f) == 'P') /* Penny watcher? */ { defPortPtr->rate = atoi(&argv[i][j+1]); while (argv[i][++j]) ; } #endif else { if (msgfh) { Write(msgfh,badarg,(long)sizeof(badarg)); Write(msgfh,usage,(long)sizeof(usage)); } Uninstall(10L); } } } else /* Not "-", must be hotkey definition. */ /* Set len equal to length of argv[i] + 1 for null if not a */ /* specific key given with +n. If +n, set len equal to length */ /* of argv[i] - 1. */ { if (len = (long)strlen(argv[i])) { c = 0; if (argv[i][0] == '+') /* specific key? */ { if (argv[i][1] >= '0' && argv[i][1] <= '9') { f = argv[i][1] - '0' - 1; if (f < 0) f = 9; c = 2; /* 1st char of definition */ len--; /* less plus sign but keep 1 for null */ } } else len++; /* add for null */ if (defPortPtr->func[f]) /* free old definition */ FreeMem(defPortPtr->func[f],(long)strlen(defPortPtr->func[f])+1); if (defPortPtr->func[f] = AllocMem(len,MEMF_PUBLIC)) strcpy(defPortPtr->func[f],&argv[i][c]); } f++; } if (updating) /* if we just updating, get out now */ Uninstall(0L); defPortPtr->mp.mp_Node.ln_Pri = 0; defPortPtr->mp.mp_Node.ln_Type = NT_MSGPORT; NewList(&(defPortPtr->mp.mp_MsgList)); defPortPtr->mp.mp_Node.ln_Name = (char *) &(defPortName); AddPort(defPortPtr); /* add our hotkey and definition port structure */ /* Init HotStuff structure */ if((signum = AllocSignal((long)-1)) == -1) Uninstall(11L); hotStuff.hotSig = 1 << signum; hotStuff.hotTask = FindTask(NULL); /* and stuff to add the handler */ if(!(inputPort = CreatePort(PortName,0))) Uninstall(12L); if(!(inputReq = CreateStdIO(inputPort))) Uninstall(13L); handlerStuff.is_Data = (APTR)&hotStuff; /* shared data */ handlerStuff.is_Code = HandlerInterface; /* assem entry */ handlerStuff.is_Node.ln_Pri = 55; /* above Intuition */ handlerStuff.is_Node.ln_Name = "Mach Handler"; if(OpenDevice("input.device",0L,inputReq,0L) != 0) Uninstall(14L); inputReq->io_Command = IND_ADDHANDLER; inputReq->io_Data = (APTR)&handlerStuff; DoIO(inputReq); nullfh = Open("NIL:",MODE_NEWFILE); /* used by Execute() */ /* setup timer */ if ((TimerPort = CreatePort("Timer Port", 0L)) == NULL) Uninstall(15L); if ((tdevice = OpenDevice(TIMERNAME, UNIT_VBLANK, &Timer_Req, 0L)) != 0) Uninstall(16L); Timer_Req.tr_node.io_Message.mn_ReplyPort = TimerPort; Timer_Req.tr_node.io_Command = TR_ADDREQUEST; Timer_Req.tr_node.io_Flags = 0; Timer_Req.tr_node.io_Error = 0; TimerSig = (1L << TimerPort->mp_SigBit); /* end of timer stuff */ #ifdef USINGCLOCK if (canClock) SetupClock(); DisplayTime(); #endif (void)SetTaskPri(FindTask(NULL), 20L); QueTimer(); /************************************************************************* MAIN EVENT LOOP ***************************************************************************/ for (;;) { Wait(hotStuff.hotSig | TimerSig); #ifdef USINGCLOCK if (event & CLOCK) if (canClock) SetupClock(); else KillClock(); #endif if ((Msg = (struct IntuiMessage *)GetMsg(TimerPort)) || (event & BLANK)) { if (Msg) { QueTimer(); #ifdef USINGCLOCK DisplayTime(); #endif } if ((((++noevent >= defPortPtr->blanktime) && defPortPtr->blanktime) || (event & BLANK)) && !blanking) if ((blankS = OpenScreen(&newScreen)) != NULL) { SetRGB4(&(blankS->ViewPort),0L,0L,0L,0L); OFF_DISPLAY; blanking = 1; } } if (event & UNBLANK) if ((blanking) && (blankS)) { blanking = 0; (void)CloseScreen(blankS); ON_DISPLAY; } i = 0; if (event & HOTKEY) { while (i < keyCount) /*may be more than 1 function key pressed */ WriteHotString(i++); keyCount = 0; } if (defPortPtr->acc && (event & ACCELERATE)) Accelerate(); if (event & BACKSCREEN) { Forbid(); if (s = IntuitionBase->FirstScreen) (void)ScreenToBack(s); Permit(); } if (event & NEWCLI) { WBenchToFront(); Execute(defPortPtr->ECommand,nullfh,nullfh); } if (event & (SUN | CLICKTF)) { ml = WhichLayer(&(s->LayerInfo),(long)x,(long)y); if (ml && (mw = (struct Window *)ml->Window)) { if ( event & SUN) if (mw != IntuitionBase->ActiveWindow) (void)ActivateWindow(mw); if (event & CLICKTF) { if (!(mw->Flags & BACKDROP)) (void)WindowToFront(mw); } } } if (event & QUIT) Uninstall(0L); /* all done...never to return */ } /* for(;;) */ } /* main() */ /************************************************************************/ QueTimer() { Timer_Req.tr_time.tv_secs = 0; Timer_Req.tr_time.tv_micro = WAIT_TIME; SendIO(&Timer_Req.tr_node); } #ifdef USINGCLOCK SetupClock() { newWindow.LeftEdge = clockEdge; if (!(ClockWindow = OpenWindow(&newWindow))) canClock = 0; /* if can't then just disable clock */ } KillClock() { if (ClockWindow) CloseWindow(ClockWindow); ClockWindow = NULL; canClock = 0; } DisplayTime() { long hours, minutes, seconds; long chipfree, fastfree; struct DateStamp time; if (canClock) { DateStamp(&time); chipfree = AvailMem(MEMF_CHIP) >> 10; fastfree = AvailMem(MEMF_FAST) >> 10; hours = time.ds_Minute / 60 ; if (hours >= 13) hours = (hours % 13)+1; /* don't want 24 hr. */ minutes = time.ds_Minute % 60 ; seconds = time.ds_Tick / TICKS_PER_SECOND; if (!(seconds % 4)) /* don't do to often. */ { Forbid(); ml = WhichLayer(&(ClockWindow->WScreen->LayerInfo),(long)ClockWindow->LeftEdge,(long)ClockWindow->TopEdge+1); if ((ml->Window != ClockWindow) && !buttonisdown) UpfrontLayer(&(ClockWindow->WScreen->LayerInfo),ClockWindow->WLayer); Permit(); } /* Don't use windowtofront because it locks up if holding an icon */ if (canMeter) sprintf(TimeBuffer, "[ ] Chip: %3ld Fast:%4ld Cost: $%2d.%02d ", chipfree,fastfree,cost/100,cost % 100); else sprintf(TimeBuffer, "[ ] Chip: %3ld Fast:%4ld Time:%2ld:%02ld:%02ld", chipfree,fastfree,hours,minutes,seconds); if (lastMin != minutes) { lastMin = minutes; cost = cost + (((defPortPtr->rate / 6) + (defPortPtr->rate % 6)) / 10); } if (defPortPtr->canSun) TimeBuffer[1] = 's'; /* put in current toggles */ if (defPortPtr->canFront) TimeBuffer[2] = 'c'; if (defPortPtr->canShuffle) TimeBuffer[3] = 'm'; if (defPortPtr->canAddQuals) TimeBuffer[4] = 'q'; if (!(defPortPtr->alternate)) TimeBuffer[5] = 'a'; PrintIText(ClockWindow->RPort, &TimeText, 1L, 1L); if ((seconds == 0) && (defPortPtr->beepInterval) && ((minutes % defPortPtr->beepInterval)==0)) Beep(); } } Beep() { struct IOAudio sound; char * sData; short i; long soundUnit; if (sound.ioa_Request.io_Message.mn_ReplyPort = CreatePort("Beep Port",0L)) { soundUnit = 0x01020408; sound.ioa_Request.io_Message.mn_Node.ln_Pri = 10; sound.ioa_Data = (UBYTE *) &soundUnit; sound.ioa_Length = 4; if (OpenDevice(AUDIONAME,0L,&sound.ioa_Request,0L) == NULL) { if ((sData = AllocMem(64L,MEMF_CHIP | MEMF_CLEAR)) != NULL) { for (i = 1;i < 64;i++) sData[i] = i; sound.ioa_Request.io_Command = CMD_WRITE; sound.ioa_Request.io_Flags = ADIOF_PERVOL; sound.ioa_Data = (UBYTE *) sData; sound.ioa_Cycles = 50; sound.ioa_Length = 64; sound.ioa_Period = 128; /* use a higher number for a lower tone */ sound.ioa_Volume = 64; BeginIO(&sound.ioa_Request); WaitIO(&sound.ioa_Request); FreeMem(sData,64L); } CloseDevice(&sound.ioa_Request); } DeletePort(sound.ioa_Request.io_Message.mn_ReplyPort); } } #endif #define ASCIIBIAS 0x20 #define SHIFTBIT 0x100 #define RETURN 0x44 WriteHotString(e) short e; /* key table entry */ { short k,j,outkey,outqual; k = 0; j = kt[e]-F1; /* 1-10 from the function key code */ if (!(defPortPtr->func[j])) return; while (defPortPtr->func[j][k]) { outkey = 0; outqual = 0; while ((defPortPtr->func[j][k] == '\\') && (outkey == 0)) { switch (defPortPtr->func[j][++k]) { case 'N': case 'n': outkey = RETURN; ++k; break; case 'C': case 'c': outqual |= IEQUALIFIER_CONTROL; ++k; break; case 'a': outqual |= IEQUALIFIER_LALT; ++k; break; case 'A': outqual |= IEQUALIFIER_LCOMMAND; ++k; break; case 's': case 'S': outqual |= IEQUALIFIER_LSHIFT; ++k; break; case '\\': outkey = BACKSLASH; ++k; break; default: if ((defPortPtr->func[j][k] >= '0') && (defPortPtr->func[j][k] <= '9')) /* Function key? */ outkey = defPortPtr->func[j][k++] + 0x1f; /* translate '1' - '9' to F1 - F9 */ if (outkey == 0x4f) outkey = 0x59; /* translate '0' to F10 */ break; } } if (outkey == 0) /* then didn't get return or function key or "\" */ { /* translate letter into keycode and qualifier */ outkey = (keytran[(defPortPtr->func[j][k] - ASCIIBIAS)]); outqual |= (outkey & SHIFTBIT) >> 8; /* add shift qualifier if present */ outkey &= 0x7f; /* then strip shiftbit */ ++k; } WriteKey(outkey,outqual); /* send it pressed down */ WriteKey(outkey | 0x80,outqual); /* and up */ } } WriteKey(c,q) short c,q; { inputReq->io_Command = IND_WRITEEVENT; inputReq->io_Flags = 0; inputReq->io_Length = sizeof(struct InputEvent); inputReq->io_Data = (APTR)&phoney; phoney.ie_NextEvent = NULL; phoney.ie_Class = IECLASS_RAWKEY; phoney.ie_TimeStamp.tv_secs = 0; phoney.ie_TimeStamp.tv_micro = 0; phoney.ie_Code = c; phoney.ie_Qualifier = q; phoney.ie_X = 0; phoney.ie_Y = 0; DoIO(inputReq); } Accelerate() { inputReq->io_Command = IND_WRITEEVENT; inputReq->io_Flags = 0; inputReq->io_Length = sizeof(struct InputEvent); inputReq->io_Data = (APTR)&phoney; phoney.ie_NextEvent = NULL; phoney.ie_Class = IECLASS_RAWMOUSE; phoney.ie_TimeStamp.tv_secs = 0; phoney.ie_TimeStamp.tv_micro = 0; phoney.ie_Code = IECODE_NOBUTTON; phoney.ie_Qualifier = IEQUALIFIER_RELATIVEMOUSE; phoney.ie_X = (dx * defPortPtr->acc) / 2; phoney.ie_Y = (dy * defPortPtr->acc) / 3; DoIO(inputReq); } Uninstall(rv) long rv; { short i; if (msgfh) if (event & QUIT) (void)Write(msgfh,die,(long)sizeof(die)); else if (rv) (void)Write(msgfh,failed,(long)sizeof(failed)); else if (updating) (void)Write(msgfh,updated,(long)sizeof(updated)); if (!updating) { if (inputReq) /* remove the handler */ { inputReq->io_Command = IND_REMHANDLER; inputReq->io_Data = (APTR)&handlerStuff; DoIO(inputReq); CloseDevice(inputReq); DeleteStdIO(inputReq); } /* close, delete and free other stuff */ if (nullfh) Close(nullfh); if (inputPort) DeletePort(inputPort); if (signum > -1) FreeSignal(signum); if (tdevice == 0) { AbortIO(&Timer_Req.tr_node); CloseDevice(&Timer_Req); } if (TimerPort) DeletePort(TimerPort); #ifdef USINGCLOCK if (canClock) KillClock(); #endif if (defPortPtr) { /* Free hotkey definitions */ for (i=0;i<10;i++) if (defPortPtr->func[i]) FreeMem(defPortPtr->func[i],(long)strlen(defPortPtr->func[i])+1); /* Free Execute Command string */ if (defPortPtr->ECommand) FreeMem(defPortPtr->ECommand,(long)strlen(defPortPtr->ECommand)+1); if (defPortPtr->mp.mp_Node.ln_Name) RemPort(defPortPtr); FreeMem(defPortPtr,(long)sizeof(struct defPort)); } } if (IntuitionBase) CloseLibrary(IntuitionBase); if (GfxBase) CloseLibrary(GfxBase); if (LayersBase) CloseLibrary(LayersBase); exit(rv); } SHAR_EOF if test 36699 -ne "`wc -c Mach.c`" then echo shar: error transmitting Mach.c '(should have been 36699 characters)' fi # End of shell archive exit 0