1 message in net.java.dev.jna.users[jna-users] Callback to Mac Carbon APIs.
FromSent OnAttachments
Alan SnyderSep 2, 2008 10:24 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[jna-users] Callback to Mac Carbon APIs.Actions...
From:Alan Snyder (ala@tidebreaksys.com)
Date:Sep 2, 2008 10:24:32 am
List:net.java.dev.jna.users

Thanks for the earlier e-mails, I'm making progress on this program. Currently it is running into a exception when it tries to call the Cabon API's NewEventHandlerUPP function.

The specific exception is :

java.lang.IllegalArgumentException: Unsupported argument type

com.tidebreak.proto.jna.pointright.core.KeyboardHookOSXRunnable$KeyListener at parameter 0 of function NewEventHandlerUPP at com.sun.jna.Function.convertArgument(Function.java:476) at com.sun.jna.Function.invoke(Function.java:203) at com.sun.jna.Library$Handler.invoke(Library.java:204) at $Proxy0.NewEventHandlerUPP(Unknown Source) ...

NewEventHandlerUPP is defined as:

* * /* EventHandlerUPP NewEventHandlerUPP( EventHandlerProcPtr userRoutine); */ EventHandlerUPP NewEventHandlerUPP( EventHandlerProcPtr userRoutine );

EventHandler is defined as: /* typedef OSStatus (*EventHandlerProcPtr) ( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData ); */ public interface EventHandlerProcPtr extends Callback { public OSStatus callback(Pointer inHandlerCallRef, Pointer inEvent, Pointer inUserData); //OSStatus callback(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, Pointer inUserData); //commented out, using EventHandlerCallRef as a pointer }

With the following implementation: public class KeyListener implements EventHandlerProcPtr{

public KeyListener(){}

public OSStatus callback(Pointer nextHandler, Pointer theEvent, Pointer userData) { System.out.print("key");

return lib.noErr; }

}//class KeyListener

and it is called on the line.

lib.InstallEventHandler(lib.GetEventMonitorTarget(), lib.NewEventHandlerUPP( new KeyListener() ), new ItemCount(NUM_EVENT_TYPES), eventTypes, null, null);

That is the summary above. The full details are below. My next step to understanding this is to run this in a debugger on the Mac. Any help here though is appreciated.

/** **/

static final TBCarbon lib = TBCarbon.INSTANCE; static final PRState state = PRState.getInstance();

public void run() {

try{

AtomicBoolean quitApp = state.getShutdownSignalor();

int NUM_EVENT_TYPES = 2; EventTypeSpec[] eventTypes = new EventTypeSpec[NUM_EVENT_TYPES];

eventTypes[0] = new EventTypeSpec(); eventTypes[0].eventClass = lib.kEventClassKeyboard; eventTypes[0].eventKind = lib.kEventRawKeyDown;

eventTypes[1] = new EventTypeSpec(); eventTypes[1].eventClass = lib.kEventClassKeyboard; eventTypes[1].eventKind = lib.kEventRawKeyUp;

lib.InstallEventHandler(lib.GetEventMonitorTarget(), lib.NewEventHandlerUPP( new KeyListener() ), new ItemCount(NUM_EVENT_TYPES), eventTypes, null, null);

//when do we remove the event handler?

}catch(Exception e){ System.err.println(e); e.printStackTrace(); }finally{ System.out.println("exit osx key hook thread."); }

}//run

public class KeyListener implements EventHandlerProcPtr{

public KeyListener(){}

public OSStatus callback(Pointer nextHandler, Pointer theEvent, Pointer userData) { System.out.print("key,");

PREvent event = new PREvent(); event.type = PREvent.PRType.KEY_PRESS; event.data = "key";

state.add(event);

return lib.noErr; }

}//class KeyListener

/** new file **/ public interface TBCarbon extends Library { TBCarbon INSTANCE = (TBCarbon)Native.loadLibrary("/System/Library/Frameworks/Carbon.framework/Carbon", TBCarbon.class);

//NOTE: C definitions from Carbon API are in /* */ comment blocks.

/* typedef struct OpaqueEventTargetRef* EventTargetRef; */ //just using a Pointer

/* InstallEventHandler */ /* OSStatus InstallEventHandler ( EventTargetRef inTarget, //using Pointer here. EventHandlerUPP inHandler, ItemCount inNumTypes, const EventTypeSpec *inList, void *inUserData, EventHandlerRef *outRef ); */ OSStatus InstallEventHandler( Pointer inTarget, EventHandlerUPP inHandler, ItemCount inNumTypes, final EventTypeSpec[] inList, Pointer inUserData, Pointer outRef);

/* EventHandlerUPP NewEventHandlerUPP( EventHandlerProcPtr userRoutine); */ EventHandlerUPP NewEventHandlerUPP( EventHandlerProcPtr userRoutine );

/* EventTargetRef GetEventMonitorTarget() */ Pointer GetEventMonitorTarget();

/* Remove the event handler. */ OSStatus RemoveEventHandler( Pointer inHandlerRef ); //OSStatus RemoveEventHandler( EventHandlerRef inHandlerRef ); //using just a Pointer

/* typedef SInt32 OSStatus */ public class OSStatus extends IntegerType{ public OSStatus() {this(0);} public OSStatus(int value) { super(4, value); } }

OSStatus noErr = new OSStatus(0); OSStatus eventAlreadyPostedErr = new OSStatus(-9860); OSStatus eventTargetBusyErr = new OSStatus(-9861); OSStatus eventClassInvalidErr = new OSStatus(-9862); //Note More on page 213 - Carbon_Event_Manager_Ref.pdf

/* Don't see defined anywhere, but used where integer is expected. */ public class ItemCount extends IntegerType{ public ItemCount() {this(0);} public ItemCount(int value) { super(4, value); } }

/* EventTypeSpec */ /* struct EventTypeSpec { UInt32 eventClass; UInt32 eventKind; }; typedef struct EventTypeSpec EventTypeSpec */ public class EventTypeSpec extends Structure{ public int eventClass; public int eventKind; }

/* typedef EventHandlerProcPtr EventHandlerUPP; */ interface EventHandlerUPP extends EventHandlerProcPtr {}

/* typedef OSStatus (*EventHandlerProcPtr) ( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData ); */ public interface EventHandlerProcPtr extends Callback { public OSStatus callback(Pointer inHandlerCallRef, Pointer inEvent, Pointer inUserData); //OSStatus callback(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, Pointer inUserData); }

/* If you name your function MyEventHandlerProc it would be declared as:

OSStatus MyEventHandlerProc ( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData ); */

int kEventMouseDown = 1; int kEventMouseUp = 2; int kEventMouseDragged = 6; int kEventMouseMoved = 10;

/* keyboard events */ int kEventRawKeyDown = 1; int kEventRawKeyRepeat = 2; int kEventRawKeyUp = 3; int kEventRawKeyModifiersChanged = 4; int kEventRawHotKeyPressed = 5; int kEventRawHotKeyReleased = 6;

/* typedef UInt32 EventClass; enum { kEventClassMouse = 'mous', kEventClassKeyboard = 'keyb'; ... }; */ int kEventClassMouse = (int)'m'<<24+(int)'o'<<16+(int)'u'<<8+(int)'s'; int kEventClassKeyboard = (int)'k'<<24+(int)'e'<<16+(int)'y'<<8+(int)'b';

}// end class TBCarbon