Article 113 of comp.sources.apple2: Path: caen!nigel.msen.com!sdd.hp.com!cs.utexas.edu!rutgers!igor.rutgers.edu!yoko.rutgers.edu!jac From: jac@yoko.rutgers.edu (Jonathan A. Chandross) Newsgroups: comp.sources.apple2 Subject: v001SRC086: SwitchHitter -- NDA To Move Mouse (GS) Message-ID: Date: 2 May 93 02:49:34 GMT Organization: Rutgers Univ., New Brunswick, N.J. Lines: 507 Approved: jac@paul.rutgers.edu Submitted-by: Jason Simmons (jsimmons@sbcs.sunysb.edu) Posting-number: Volume 1, Source:86 Archive-name: nda/switch_hitter/switch_hitter1.00 Architecture: ONLY_2gs Version-number: 1.00 SwitchHitter is a New Desk Accessory for the Apple IIGS that lets you transport your mouse pointer to any spot on the screen instantaneously by pressing a key or combination of keys. Use the check boxes in the NDA window to choose your keys. When the selected keys are held down and the mouse is moved or clicked, SwitchHitter will place the arrow in the upper-right-hand corner of the screen. When the keys are released, the pointer will return to its original position. Enjoy. =Read.Me - -SwitchHitter - -SwitchHitter is a New Desk Accessory for the Apple IIGS that lets you -transport your mouse pointer to any spot on the screen instantaneously -by pressing a key or combination of keys. Use the check boxes in the -NDA window to choose your keys. When the selected keys are held down -and the mouse is moved or clicked, SwitchHitter will place the arrow -in the upper-right-hand corner of the screen. When the keys are released, -the pointer will return to its original position. - -Click on the Location button to select a different spot for the mouse to -move. While the pointer is a cross, click on the new spot. SwitchHitter -will keep track of two separate locations for 320 mode and 640 mode. - -SwitchHitter installs an item into the Desk Manager's run queue. This -code checks the keyboard modifier register for the appropriate combination -of keypresses. If it detects the combination, it moves the mouse pointer -via the PosMouse call to the user-set location and saves the original mouse -position. The original position is restored when the run queue item finds -that one of the keys has been released. - -SwitchHitter is composed of the following files: - JDDemoAux.asm Assembly routines to manage the Desk - Manager run queue - JDDemoAux.macs Macros for JDDemoAux.asm - SwitchHitter.cc C source to SwitchHitter - -SwitchHitter also relies on its resource fork, which can be obtained from -the compiled version available on FTP sites. - -To build it: (ORCA/C and ORCA/M required) - compile SwitchHitter.cc - compile JDDemoAux.asm - link SwitchHit JDDemoAux keep=SwitchHitter - -(c) 1993 by Jason Simmons (jsimmons@sbcs.sunysb.edu) -All Rights Reserved - -Jason Simmons -jsimmons@sbcs.sunysb.edu -Version 1.0 -April 1993 =Manifest -JDDemoAux.asm -JDDemoAux.macs -Manifest -Read.Me -SwitchHitter.cc =JDDemoAux.asm - case on - - mcopy JDDemoAux.macs - keep JDDemoAux - -addRQItem start - using itemHdr - - lda >rqPeriod - sta >iHperiod - pushlong #itemHdr - _AddToRunQ - rts - end - -removeRQItem start - pushlong #itemHdr - _RemoveFromRunQ - rts - end - -itemHdr data - ds 4 -iHperiod ds 2 - dc i2'$a55a' - ds 4 - end - -itemTask start - using itemHdr - - jsl rqAction - lda >rqPeriod - sta >iHperiod - rtl - end =JDDemoAux.macs - MACRO -&lab pushlong &addr,&offset -&lab ANOP - LCLC &C - LCLC &REST -&C AMID &addr,1,1 - AIF "&C"="#",.immediate - AIF "&C"="[",.zeropage - AIF C:&offset=0,.nooffset - AIF "&offset"="s",.stack - pushword &addr+2,&offset - pushword &addr,&offset - MEXIT -.nooffset - pushword &addr+2 - pushword &addr - MEXIT -.immediate -&REST AMID &addr,2,L:&addr-1 - dc I1'$F4',I2'(&REST)|-16' - dc I1'$F4',I2'&REST' - MEXIT -.stack - pushword &addr+2,s - pushword &addr+2,s - MEXIT -.zeropage - ldy #&offset+2 - pushword &addr,y - ldy #&offset - pushword &addr,y - MEND - MACRO -&lab pushword &SYSOPR -&lab ANOP - AIF C:&SYSOPR=0,.b - LCLC &C -&C AMID "&SYSOPR",1,1 - AIF ("&C"="#").AND.(S:LONGA),.immediate - lda &SYSOPR - pha - MEXIT -.b - pha - MEXIT -.immediate - LCLC &REST - LCLA &BL -&BL ASEARCH "&SYSOPR"," ",1 - AIF &BL>0,.a -&BL SETA L:&SYSOPR+1 -.a -&REST AMID "&SYSOPR",2,&BL-2 - dc I1'$F4',I2'&REST' - MEND - MACRO -&lab _AddToRunQ -&lab ldx #$1F05 - jsl $E10000 - MEND - MACRO -&lab _RemoveFromRunQ -&lab ldx #$2005 - jsl $E10000 - MEND =SwitchHitter.cc -#pragma keep "SwitchHit" -#pragma nda open close action init 0xffff 0xffff "--SwitchHitter\\H**" - -/* SwitchHitter - Version 1.0 - (c) 1993 by Jason Simmons (jsimmons@sbcs.sunysb.edu) - - This is composed of 2 files.To compile it: - compile SwitchHitter.cc - compile JDDemoAux.asm - link SwitchHit JDDemoAux keep=SwitchHitter */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void windDraw(void); -void handleCtrl(CtlRecHndl ctrlHandle,long ctrlID); -void getMod(void); -void doLocation(void); -void rqAction(void); -extern void addRQItem(void); -extern void removeRQItem(void); - -GrafPortPtr windPtr; -int active=0,NDAid,rqPeriod=0,resFileID,shMod,initDone=0,resStarted=0; -Handle shActive,shApple,shOption,shCtrl,shShift,shCaps; -int **shLocX,**shLocY,**shLocX320,**shLocY320; - -GrafPortPtr open(void) -{ -int oldAppID,error; -LevelRecGS oldLevelRec={1},newLevelRec={1,0}; -SysPrefsRecGS oldSysPrefs={1},newSysPrefs={1}; -char *alertSub[10]; -char alertStr[]="72/Unable to open window. (error $*0)/^Cancel"; - -if (!active) -{ - oldAppID=GetCurResourceApp(); /* identical to the Init routine */ - NDAid=MMStartUp(); - if (resStarted) - resStarted=0; - else ResourceStartUp(NDAid); - GetLevelGS(&oldLevelRec); - SetLevelGS(&newLevelRec); - GetSysPrefsGS(&oldSysPrefs); - newSysPrefs.preferences=(oldSysPrefs.preferences & 0x1fff) | 0x8000; - SetSysPrefsGS(&newSysPrefs); - resFileID=OpenResourceFile(3,NULL,LGetPathname2(NDAid,1)); - if (error=toolerror()) - { - alertSub[0]=malloc(5); - sprintf(alertSub[0],"%x",error); - AlertWindow(0,alertSub,alertStr); - SetSysPrefsGS(&oldSysPrefs); - SetLevelGS(&oldLevelRec); - SetCurResourceApp(oldAppID); - return NULL; - } - windPtr=NewWindow2(NULL,0L,windDraw,NULL,refIsResource,1L,rWindParam1); - SetSysWindow(windPtr); - shActive=LoadResource(1,1L); - shApple=LoadResource(1,2L); - shOption=LoadResource(1,3L); - shCtrl=LoadResource(1,4L); - shShift=LoadResource(1,5L); - shCaps=LoadResource(1,6L); - shLocX=(int **) LoadResource(1,7L); - shLocY=(int **) LoadResource(1,8L); - shLocX320=(int **) LoadResource(1,9L); - shLocY320=(int **) LoadResource(1,10L); - SetCtlValue(**shActive,GetCtlHandleFromID(windPtr,1L)); - SetCtlValue(**shApple,GetCtlHandleFromID(windPtr,2L)); - SetCtlValue(**shOption,GetCtlHandleFromID(windPtr,3L)); - SetCtlValue(**shCtrl,GetCtlHandleFromID(windPtr,4L)); - SetCtlValue(**shShift,GetCtlHandleFromID(windPtr,5L)); - SetCtlValue(**shCaps,GetCtlHandleFromID(windPtr,6L)); - getMod(); - SetSysPrefsGS(&oldSysPrefs); - SetLevelGS(&oldLevelRec); - SetCurResourceApp(oldAppID); - if (!initDone) - { - addRQItem(); - initDone=1; - } - active=1; - return windPtr; -} -} - -void close(void) -{ -long loop; - -if (active) -{ - CloseWindow(windPtr); - UpdateResourceFile(resFileID); /* Write the configuration changes to disk */ - for (loop=1;loop<11;loop++) /* Detach the configuration resource so */ - DetachResource(1,loop); /* the handles can still be used after */ - CloseResourceFile(resFileID); /* the resource file is closed and */ - ResourceShutDown(); /* the resource manager is shut down */ - active=0; -} -} - -void action(long param,int code) -{ -EventRecord tmdaRec={0,0,0,{0,0},0,0,0x1f0004,0,0,0,0,0,{0,0}}; - -if (code==eventAction) -{ /* Copy the event information into */ - memcpy(&tmdaRec,(void *) param,16); /* a blank task record and */ - switch (TaskMasterDA(0,&tmdaRec)) /* pass it to TaskMasterDA */ - { - case updateEvt:BeginUpdate(windPtr); /* redraw the window if necessary */ - windDraw(); - EndUpdate(windPtr); - break; - case wInControl:handleCtrl((CtlRecHndl) tmdaRec.wmTaskData2,tmdaRec.wmTaskData4); - break; /* control handle control ID */ - } -} -} - -void init(int code) -{ -int oldAppID; -LevelRecGS oldLevelRec={1},newLevelRec={1,0}; -SysPrefsRecGS oldSysPrefs={1},newSysPrefs={1}; -long loop; - -if (code) -{ - oldAppID=GetCurResourceApp(); /* save the ID of the app which last used the resource manager */ - NDAid=MMStartUp(); /* get a user ID */ - ResourceStartUp(NDAid); /* log in with the resource manager */ - resStarted=1; - GetLevelGS(&oldLevelRec); /* This information must be saved when */ - SetLevelGS(&newLevelRec); /* resource are used with NDAs */ - GetSysPrefsGS(&oldSysPrefs); - newSysPrefs.preferences=(oldSysPrefs.preferences & 0x1fff) | 0x8000; - SetSysPrefsGS(&newSysPrefs); - resFileID=OpenResourceFile(3,NULL,LGetPathname2(NDAid,1)); - shActive=LoadResource(1,1L); /* Load the configuration data */ - shApple=LoadResource(1,2L); /* e.g. which hotkeys are being used */ - shOption=LoadResource(1,3L); - shCtrl=LoadResource(1,4L); - shShift=LoadResource(1,5L); - shCaps=LoadResource(1,6L); - shLocX=(int **) LoadResource(1,7L); - shLocY=(int **) LoadResource(1,8L); - shLocX320=(int **) LoadResource(1,9L); - shLocY320=(int **) LoadResource(1,10L); - getMod(); /* calculate a mask which is used in rqAction */ - for (loop=1;loop<11;loop++) /* done so the configuration data can be */ - DetachResource(1,loop); /* accessed after the resource file is */ - CloseResourceFile(resFileID); /* closed */ - SetSysPrefsGS(&oldSysPrefs); /* restore the GS/OS information which was */ - SetLevelGS(&oldLevelRec); /* saved earlier */ - SetCurResourceApp(oldAppID); - addRQItem(); /* install the run queue item (see JDDemoAux.asm) */ - initDone=1; -} -else -{ - if (active) - { - UpdateResourceFile(resFileID); /* if the resource file is open, update */ - CloseResourceFile(resFileID); /* it and shut down the resource manager */ - ResourceShutDown(); - active=0; - } - else if (initDone) - { - DisposeHandle(shActive); /* if the resources were loaded and detached, */ - DisposeHandle(shApple); /* dispose of the handles */ - DisposeHandle(shOption); - DisposeHandle(shCtrl); - DisposeHandle(shShift); - DisposeHandle(shCaps); - DisposeHandle(shLocX); - DisposeHandle(shLocY); - DisposeHandle(shLocX320); - DisposeHandle(shLocY320); - } - if (resStarted) /* this flag would be set if the DA window had not been opened */ - { - ResourceShutDown(); - resStarted=0; - } - removeRQItem(); /* see JDDemoAux.asm */ - initDone=0; -} -} - -#pragma databank 1 - -void windDraw(void) -{ -DrawControls(GetPort()); -} - -#pragma databank 0 - -void handleCtrl(CtlRecHndl ctrlHandle,long ctrlID) -{ -Handle ctrlStatus; - -switch (ctrlID) -{ - case 1L:**shActive=GetCtlValue(ctrlHandle); - MarkResourceChange(1,1,1L); - return; - case 2L:ctrlStatus=shApple; - break; - case 3L:ctrlStatus=shOption; - break; - case 4L:ctrlStatus=shCtrl; - break; - case 5L:ctrlStatus=shShift; - break; - case 6L:ctrlStatus=shCaps; - break; - case 8L:doLocation(); - return; -} -**ctrlStatus=GetCtlValue(ctrlHandle); -getMod(); /* recalculate the mask used in rqAction */ -if (!shMod) /* if every key was unchecked, recheck the last deselected key */ -{ - SysBeep(); - SetCtlValue(1,ctrlHandle); - **ctrlStatus=1; -} -else MarkResourceChange(1,1,ctrlID); -} - -void getMod(void) -{ -shMod=0; -if (**shApple) - shMod|=0x80; -if (**shOption) - shMod|=0x40; -if (**shCtrl) - shMod|=2; -if (**shShift) - shMod|=1; -if (**shCaps) - shMod|=4; -} - -void doLocation(void) -{ -CursorPtr newCursor,oldCursor; -EventRecord evRec; -MouseRec pos; - -oldCursor=GetCursorAdr(); /* save the current cursor */ -if (GetMasterSCB() & 0x80) /* are you in 640 mode? */ - newCursor=(CursorPtr) *LoadResource(0x8027,1L); /* load in the cross cursor */ -else newCursor=(CursorPtr) *LoadResource(0x8027,2L); -SetCursor(newCursor); -while (!Button(0)); /* wait until the button is pressed */ -GetNextEvent(2,&evRec); /* remove the mouseDown event from the queue */ -pos=ReadMouse(); /* get the mouse position and save it */ -if (GetMasterSCB() & 0x80) -{ - **shLocX=pos.xPos; - **shLocY=pos.yPos; - MarkResourceChange(1,1,7L); - MarkResourceChange(1,1,8L); -} -else -{ - **shLocX320=pos.xPos; - **shLocY320=pos.yPos; - MarkResourceChange(1,1,9L); - MarkResourceChange(1,1,10L); -} -SetCursor(oldCursor); /* restore the old cursor */ -} - -#pragma databank 1 /* this routine will be called by the Desk Manager */ - -void rqAction(void) /* called every rqPeriod sixtieths of a second */ -{ -int keyMods; -static modsDown=0; -static MouseRec oldPos; - -if (!**shActive) - return; -/* read the keyboard modifier register (described in the Hardware Reference) */ -asm -{ - lda >0xe0c025 - sta keyMods -} -if ((keyMods & shMod) && !((keyMods & shMod) ^ shMod)) /* has every selected key been pressed? */ -{ - if (!modsDown) /* if the modifier keys are being held down, do not move the mouse */ - { - oldPos=ReadMouse(); - if (GetMasterSCB() & 0x80) - PosMouse(**shLocX,**shLocY); - else PosMouse(**shLocX320,**shLocY320); - modsDown=1; - } -} -else if (modsDown) /* if the keys have been released, move the mouse back to its oiginal position */ -{ - PosMouse(oldPos.xPos,oldPos.yPos); - modsDown=0; -} -} - + END OF ARCHIVE