diff options
author | Damian Minkov <damencho@jitsi.org> | 2008-09-14 20:04:37 +0000 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2008-09-14 20:04:37 +0000 |
commit | 22a5a325e219f3567ccf6b07cd86b848bce23030 (patch) | |
tree | e68109dc83bbfe78ed54b762eb3f7f2f430d8a14 /src/native/macosx | |
parent | f3a580e154a893153ceecc7aa7c8d2c083175b0d (diff) | |
download | jitsi-22a5a325e219f3567ccf6b07cd86b848bce23030.zip jitsi-22a5a325e219f3567ccf6b07cd86b848bce23030.tar.gz jitsi-22a5a325e219f3567ccf6b07cd86b848bce23030.tar.bz2 |
Fix proper catching and dispatching apple events.
Diffstat (limited to 'src/native/macosx')
3 files changed, 225 insertions, 0 deletions
diff --git a/src/native/macosx/launcharghandler/AEGetURLEventHandler.h b/src/native/macosx/launcharghandler/AEGetURLEventHandler.h new file mode 100644 index 0000000..c17c1d8 --- /dev/null +++ b/src/native/macosx/launcharghandler/AEGetURLEventHandler.h @@ -0,0 +1,32 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class net_java_sip_communicator_util_launchutils_AEGetURLEventHandler */ + +#ifndef _Included_net_java_sip_communicator_util_launchutils_AEGetURLEventHandler +#define _Included_net_java_sip_communicator_util_launchutils_AEGetURLEventHandler +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: net_java_sip_communicator_util_launchutils_AEGetURLEventHandler + * Method: setAEGetURLListener + * Signature: (Lnet/java/sip/communicator/util/launchutils/AEGetURLEventHandler/IAEGetURLListener;)V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_util_launchutils_AEGetURLEventHandler_setAEGetURLListener + (JNIEnv *, jclass, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class net_java_sip_communicator_util_launchutils_AEGetURLEventHandler_IAEGetURLListener */ + +#ifndef _Included_net_java_sip_communicator_util_launchutils_AEGetURLEventHandler_IAEGetURLListener +#define _Included_net_java_sip_communicator_util_launchutils_AEGetURLEventHandler_IAEGetURLListener +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/native/macosx/launcharghandler/AEGetURLEventHandlerAgent.m b/src/native/macosx/launcharghandler/AEGetURLEventHandlerAgent.m new file mode 100644 index 0000000..029f489 --- /dev/null +++ b/src/native/macosx/launcharghandler/AEGetURLEventHandlerAgent.m @@ -0,0 +1,173 @@ +#include "AEGetURLEventHandler.h" + +#include <jvmti.h> +#include <stdlib.h> +#import <Foundation/Foundation.h> + +@interface AEGetURLEventHandler : NSObject +{ + jobject _listener; + char *_url; + JavaVM *_vm; +} + ++ (AEGetURLEventHandler *)sharedAEGetURLEventHandler; + +- (void)handleAEGetURLEvent:(NSAppleEventDescriptor *)event + withReplyEvent:(NSAppleEventDescriptor *)replyEvent; +- (void)setAEGetURLListener:(jobject)listener jniEnv:(JNIEnv *)jniEnv; +- (void)setURL:(char *)url; +- (void)setVM:(JavaVM *)vm; +- (void)tryFireAEGetURLEvent; +@end + +static AEGetURLEventHandler *g_sharedAEGetURLEventHandler = NULL; + +@implementation AEGetURLEventHandler ++ (AEGetURLEventHandler *)sharedAEGetURLEventHandler { + if (!g_sharedAEGetURLEventHandler) { + g_sharedAEGetURLEventHandler = [[AEGetURLEventHandler alloc] init]; + } + return g_sharedAEGetURLEventHandler; +} + +- (void)dealloc { + [self setURL:NULL]; + [self setAEGetURLListener:NULL jniEnv:NULL]; + + [super dealloc]; +} + +- (void)handleAEGetURLEvent:(NSAppleEventDescriptor *)event + withReplyEvent:(NSAppleEventDescriptor *)replyEvent { + NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init]; + NSString *str; + + str = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + if (str) { + const NSStringEncoding encoding = NSNonLossyASCIIStringEncoding; + NSUInteger length; + char *chars; + + length = [str lengthOfBytesUsingEncoding:encoding]; + if (length) { + length++; // Account for the NULL termination byte. + chars = (char *) malloc (length * sizeof (char)); + if (chars + && (YES == [str getCString:chars maxLength:length encoding:encoding])) { + [[AEGetURLEventHandler sharedAEGetURLEventHandler] + setURL:chars]; + } else { + free (chars); + } + } + } + + [autoreleasePool release]; +} + +- (AEGetURLEventHandler *)init { + self = [super init]; + if (self) { + _listener = NULL; + _url = NULL; + _vm = NULL; + } + return self; +} + +- (void)setAEGetURLListener:(jobject)listener jniEnv:(JNIEnv *)jniEnv { + if (!jniEnv + && (!_vm || (JNI_OK != (*_vm)->GetEnv (_vm, (void **) &jniEnv, JNI_VERSION_1_2)))) { + return; // TODO Don't swallow the failure. + } + + if (_listener) { + (*jniEnv)->DeleteGlobalRef (jniEnv, _listener); + _listener = NULL; + } + if (listener) { + _listener = (*jniEnv)->NewGlobalRef (jniEnv, listener); + + [self tryFireAEGetURLEvent]; + } +} + +- (void)setURL:(char *)url { + if (_url != url) { + if (_url) { + free (_url); + } + + _url = url; + + [self tryFireAEGetURLEvent]; + } +} + +- (void)setVM:(JavaVM *)vm { + _vm = vm; +} + +- (void)tryFireAEGetURLEvent { + JNIEnv *jniEnv; + + if (_vm + && _listener + && _url + && (JNI_OK == (*_vm)->GetEnv (_vm, (void **) &jniEnv, JNI_VERSION_1_2))) { + jclass clazz = (*jniEnv)->GetObjectClass (jniEnv, _listener); + jmethodID methodID = + (*jniEnv)->GetMethodID ( + jniEnv, clazz, "handleAEGetURLEvent", "(Ljava/lang/String;)V"); + + if (methodID) { + jstring url = (*jniEnv)->NewStringUTF (jniEnv, _url); + + if (url) { + (*jniEnv)->CallVoidMethod (jniEnv, _listener, methodID, url); + + /* + * The URL should not be reported again after it has been + * handled. + */ + [self setURL:NULL]; + } + } + } +} +@end + +JNIEXPORT jint JNICALL +Agent_OnLoad (JavaVM *vm, char *options, void *reserved) { + NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init]; + AEGetURLEventHandler *aeGetURLEventHandler + = [AEGetURLEventHandler sharedAEGetURLEventHandler]; + + [aeGetURLEventHandler setVM:vm]; + + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:aeGetURLEventHandler + andSelector:@selector(handleAEGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; + + [autoreleasePool release]; + + /* + * Non-zero will terminate the VM and we don't want that even if we fail to + * install the event handler. + */ + return 0; +} + +JNIEXPORT void JNICALL +Java_net_java_sip_communicator_util_launchutils_AEGetURLEventHandler_setAEGetURLListener + (JNIEnv *jniEnv, jclass clazz, jobject listener) { + NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init]; + + [[AEGetURLEventHandler sharedAEGetURLEventHandler] + setAEGetURLListener:listener jniEnv:jniEnv]; + + [autoreleasePool release]; +} diff --git a/src/native/macosx/launcharghandler/Makefile b/src/native/macosx/launcharghandler/Makefile new file mode 100644 index 0000000..86c1e8c --- /dev/null +++ b/src/native/macosx/launcharghandler/Makefile @@ -0,0 +1,20 @@ +# Author: Damian Minkov +# javah -classpath ../../../../classes/ -o AEGetURLEventHandler.h net.java.sip.communicator.util.launchutils.AEGetURLEventHandler + +CC=gcc +TARGET=libAEGetURLEventHandlerAgent.jnilib +JNI_INCLUDE_PATH=/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Headers/ +CFLAGS=-I$(JNI_INCLUDE_PATH) +LIBS=-framework Foundation +OBJS=AEGetURLEventHandlerAgent.o + +all:$(TARGET) + +clean: + rm -rf $(TARGET) $(OBJS) *~ + +install:$(TARGET) + cp $(TARGET) ../../../../lib/native/mac/ + +libAEGetURLEventHandlerAgent.jnilib:$(OBJS) + $(CC) -dynamiclib -o $(TARGET) $(LIBS) $(CFLAGS) $< |