Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
jGNE Helper.c
// |
// This is "jGNE Helper", formerly a monthly posting to |
// the Usenet newsgroup alt.sources.mac. |
// It provides an example for INIT programmers |
// interested in filtering events before they are handed to |
// applications calling GetNextEvent (which is called by |
// WaitNextEvent). |
// |
// The jGNE filter is the Apple-sanctioned method for |
// filtering events. It is possible to patch event traps. It |
// is sometimes even advisable. But since the jGNE filter is |
// the sanctioned method, one ought to attempt to use it |
// before patching traps. |
// |
// Prospective users of this code should know that the |
// plan of record for Copland does not include support |
// for jGNEFilter. However, it is likely that Copland |
// will include some form of global event filtering service. |
// Carefully isolate your use of this code and you may |
// be able to make the move to Copland without too much |
// pain. |
// |
// This code sample has a specific conflict with older |
// versions of PopChar. Newer versions of PopChar have a fix |
// which makes them compatible with this code. Users of older |
// versions of PopChar should probably upgrade to the current |
// version anyway -- this is a very old conflict. The conflict |
// manifests itself by rendering a good portion of the screen |
// "impervious" to clicks unless the option key is held down. |
// |
// This version of jGNE Helper was built with both Symantec |
// THINK C 7 and Metrowerks CodeWarrior CW7 for 68K machines. |
// It's entirely possible to write a native jGNEFilter. I've |
// even done it before. However, it hasn't occurred to me how |
// to fit a native filter into the context of this sample. |
// |
// For further info on the jGNE filter, consult your Technotes. |
// |
#ifndef THINK_C |
# ifndef __MWERKS__ |
# error unknown compiler |
# endif |
#endif |
#define OLDROUTINENAMES 0 |
#define OLDROUTINELOCATIONS 0 |
#ifndef __RESOURCES__ |
# include <Resources.h> |
#endif |
#ifndef __MEMORY__ |
# include <Memory.h> |
#endif |
#ifndef __EVENTS__ |
# include <Events.h> |
#endif |
#ifndef __SETUPA4__ |
# include <SetUpA4.h> |
#endif |
#ifndef __LOWMEM__ |
# include <LowMem.h> |
#endif |
// |
// This example filter simply watches for clicks |
// with the command, option, and control keys held |
// down. If it finds any, it beeps and returns a |
// value which indicates the event should not be |
// passed to the application which called GNE. |
// |
static Boolean myGNE (EventRecord *event, Boolean preResult) |
{ |
Boolean postResult = preResult; |
if (preResult) |
{ |
if (event->what == mouseDown) |
{ |
if (event->modifiers & cmdKey) |
{ |
if (event->modifiers & optionKey) |
{ |
if (event->modifiers & controlKey) |
{ |
SysBeep (10); |
postResult = false; |
} |
} |
} |
} |
} |
return postResult; |
} |
static void *gOldJGNE; |
static Boolean inJGNE; |
#if defined (THINK_C) |
static pascal void myJGNE (void) |
{ |
asm |
{ |
MOVE.L A1,A0 // save event record pointer from __GetA4 |
JSR __GetA4 // point A1 at our A4 |
MOVE.L A4,-(A7) // save old A4 |
MOVE.L (A1),A4 // get new A4 |
MOVE.L A0,A1 // restore old A1 |
#elif defined (__MWERKS__) |
static pascal asm void myJGNE (void) |
{ |
MOVE.L D0,A0 // save pre-result from SetUpA4 |
JSR SetUpA4 // fix A4, stomp D0 |
MOVE.L D0,-(A7) // save old A4 |
MOVE.L A0,D0 // restore pre-result |
#endif |
TST.B inJGNE // is myJGNE busy? |
BNE @1 // yes, so bail |
MOVE.B #true,inJGNE // mark myJGNE busy |
MOVE.W D0,-(A7) // push pre-result |
MOVE.L A1,-(A7) // push event record pointer |
JSR myGNE // do the real work |
MOVE.L (A7)+,A1 // restore event record pointer |
ADDQ.L #2,A7 // pop pre-result; post-result in D0 |
ASL.W #8,D0 // bump C boolean to Lisa |
MOVE.W D0,8(A7) // stash result where caller expects it |
MOVE.B #false,inJGNE // mark myJGNE not busy |
@1: |
MOVE.L gOldJGNE,A0 // get previous jGNE |
MOVE.L (A7)+,A4 // restore A4 |
MOVE.L A0,-(A7) // return to previous jGNE |
#if defined (THINK_C) |
} |
#elif defined (__MWERKS__) |
RTS |
#endif |
} |
#if defined (__MWERKS__) |
# include <A4Stuff.h> |
#elif defined (THINK_C) |
pascal void * GetA0 (void) = { 0x2E88 }; |
#endif |
void main (void) |
{ |
#if defined (__MWERKS__) |
void __Startup__ (void); |
long oldA4 = SetCurrentA4 ( ); |
RememberA4 ( ); |
DetachResource (RecoverHandle ((Ptr) __Startup__)); |
#elif defined (THINK_C) |
void *me = GetA0 ( ); |
RememberA0 ( ); |
DetachResource (RecoverHandle (me)); |
SetUpA4 ( ); |
#endif |
gOldJGNE = LMGetGNEFilter ( ); |
#if defined (__MWERKS__) |
LMSetGNEFilter (myJGNE); |
#elif defined (THINK_C) |
LMSetGNEFilter ((ProcPtr) myJGNE); |
#endif |
#if defined (__MWERKS__) |
SetA4 (oldA4); |
#elif defined (THINK_C) |
RestoreA4 ( ); |
#endif |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14