/* Mach1.6a - Mouse Accelerator with Hotkey **** 02-10-88 **** MachClk1.2a - 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 [nambscqwekp] 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. -w Disables auto clock to front. Adds depth gadget. -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" How to build this: Simple (with Manx). I used version 3.4. cc machclk ln machclk.o -lc Changes from version 1.6 1. New toggle -w will disabled the auto clock to front and add an (mostly) invisible depth gadget to the clock window. 2. Fixed orphaned clock window resulting from rapid F8 toggling. 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? 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. */ #define USINGCLOCK /* take this out if you don't want the clock */ #include #include #include #include #include #include #include #include #include #include #include #include /* 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.2a \xa9 1988 by Brian Moats @Polyglot Software.\n"; char usage[] = "\n\ Usage: Run MachClk [nscmqawebktp] 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\ -w Disables auto clock to front. Adds depth gadget.\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.2a removed.\n"; char updated[] = "MachClk 1.2a updated.\n"; char failed[] = "MachClk 1.2a failed.\n"; #else /* Otherwise use this stuff */ char info[] = "Mach 1.6a \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.6a removed.\n"; char updated[] = "Mach 1.6a updated.\n"; char failed[] = "MachClk 1.6a failed.\n"; #endif char badarg[] = "\n>>> Bad arguments <<<\n"; char PortName[] = "Mach Port"; char DefECommand[] = "NewCLI >NIL: 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; 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->canCFront = 1; /* can automatically bring clock to front */ 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]) ; } else if ((argv[i][j] & 0x5f) == 'W') /* Clock window autofront? */ { defPortPtr->canCFront = 0; 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) { canClock = !canClock; /* Toggling it here prevents orphaned windows */ 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 (defPortPtr->canCFront) newWindow.Flags &= ~WINDOWDEPTH; else newWindow.Flags |= WINDOWDEPTH; 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) && defPortPtr->canCFront) /* 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); /* Don't use windowtofront because it locks up if holding an icon because it waits for an event which might be a button down on an icon! */ Permit(); } 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); }