Implemented Matzon's mac os x init through reflection
This commit is contained in:
parent
963605989f
commit
36dbba4596
|
@ -32,24 +32,80 @@
|
|||
|
||||
package org.lwjgl.opengl;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import org.lwjgl.Sys;
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* Mac OS X specific hacks
|
||||
*
|
||||
* @author elias_naur <elias_naur@users.sourceforge.net>
|
||||
* @author Brian Matzon <brian@matzon.dk>
|
||||
* @version $Revision$
|
||||
*/
|
||||
class MacOSX {
|
||||
/**
|
||||
* Initializes the Mac OS X specific hack
|
||||
*/
|
||||
public static void initMacOSX() {
|
||||
|
||||
java.awt.Toolkit.getDefaultToolkit();
|
||||
new com.apple.eawt.Application().addApplicationListener(new com.apple.eawt.ApplicationAdapter() {
|
||||
public void handleQuit(com.apple.eawt.ApplicationEvent e) {
|
||||
e.setHandled(false);
|
||||
setQuitRequested();
|
||||
|
||||
// Add ourselves to quit requested, using reflection to allow
|
||||
// compiling on other platforms
|
||||
try {
|
||||
Class appClass = Class.forName("com.apple.eawt.Application");
|
||||
Class listenerClass = Class.forName("com.apple.eawt.ApplicationListener");
|
||||
Object appInstance = appClass.newInstance();
|
||||
// create proxy for adapter
|
||||
Object proxyInvoker = Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, new Invokee());
|
||||
Method addApplicationListener = appClass.getMethod("addApplicationListener", new Class[]{listenerClass});
|
||||
addApplicationListener.invoke(appInstance, new Object[]{proxyInvoker});
|
||||
} catch (Exception e) {
|
||||
// validate success
|
||||
if (Sys.DEBUG) {
|
||||
System.out.println("Unable to invoke 'addApplicationListener' method because of " + e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Even more hackish proxy class for allowing mac os x to be compiled on all platforms
|
||||
*
|
||||
* @author Brian Matzon <brian@matzon.dk>
|
||||
*/
|
||||
static private class Invokee implements InvocationHandler {
|
||||
/**
|
||||
* Called when the actual method of the proxied class is called
|
||||
*
|
||||
* @param proxy Object being proxied
|
||||
* @param method Method being invoked
|
||||
* @param args Arguments for that specific method
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
try {
|
||||
// Return if we were not called through handleQuit
|
||||
Class applicationEventClass = Class.forName("com.apple.eawt.ApplicationEvent");
|
||||
Class applicationListenerClass = Class.forName("com.apple.eawt.ApplicationListener");
|
||||
Method handleQuitMethod = applicationListenerClass.getMethod("handleQuit", new Class[]{applicationEventClass});
|
||||
if (!method.equals(handleQuitMethod))
|
||||
return null;
|
||||
// invoke setHandled(false);
|
||||
Method setHandled = args[0].getClass().getMethod("setHandled", new Class[] {boolean.class});
|
||||
setHandled.invoke(args[0], new Object[]{new Boolean(false)});
|
||||
// just call setQuitRequested
|
||||
setQuitRequested();
|
||||
} catch (Exception e) {
|
||||
if (Sys.DEBUG) {
|
||||
System.out.println("Unable to invoke 'setHandled' because of " + e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Notifies the native implementation that a quit event has been received */
|
||||
private static native void setQuitRequested();
|
||||
}
|
||||
|
|
|
@ -55,17 +55,7 @@ public final class Window {
|
|||
*
|
||||
*/
|
||||
if (Display.getPlatform() == Display.PLATFORM_AGL)
|
||||
initMacOSX();
|
||||
}
|
||||
|
||||
private static void initMacOSX() {
|
||||
try {
|
||||
Class mac_class = Class.forName("org.lwjgl.opengl.MacOSX");
|
||||
Method init_method = mac_class.getMethod("initMacOSX", null);
|
||||
init_method.invoke(null, null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
MacOSX.initMacOSX();
|
||||
}
|
||||
|
||||
/** Whether the window is currently created, ie. has a native peer */
|
||||
|
|
|
@ -47,5 +47,6 @@
|
|||
extern void setQuitRequested(void);
|
||||
extern bool registerKeyboardHandler(JNIEnv* env, WindowRef win_ref);
|
||||
extern bool registerMouseHandler(JNIEnv* env, WindowRef win_ref);
|
||||
extern bool isMouseCreatedAndNotNativeCursor(void);
|
||||
|
||||
#endif /* _LWJGL_WINDOW_H_INCLUDED_ */
|
||||
|
|
|
@ -42,53 +42,24 @@
|
|||
#include "Window.h"
|
||||
#include "tools.h"
|
||||
#include "org_lwjgl_input_Keyboard.h"
|
||||
#include "common_tools.h"
|
||||
|
||||
#define EVENT_BUFFER_SIZE 100
|
||||
#define KEYBOARD_SIZE 256
|
||||
#define UNICODE_BUFFER_SIZE 10
|
||||
|
||||
static unsigned char key_buf[KEYBOARD_SIZE];
|
||||
static unsigned char key_map[KEYBOARD_SIZE];
|
||||
static unsigned char input_event_buffer[EVENT_BUFFER_SIZE];
|
||||
static unsigned char output_event_buffer[EVENT_BUFFER_SIZE];
|
||||
|
||||
static int list_start = 0;
|
||||
static int list_end = 0;
|
||||
static bool buffer_enabled = false;
|
||||
static bool translation_enabled = false;
|
||||
|
||||
static void putEventElement(unsigned char byte) {
|
||||
int next_index = (list_end + 1)%EVENT_BUFFER_SIZE;
|
||||
if (next_index == list_start) {
|
||||
#ifdef _DEBUG
|
||||
printf("Keyboard buffer overflow!\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
input_event_buffer[list_end] = byte;
|
||||
list_end = next_index;
|
||||
}
|
||||
|
||||
static bool hasMoreEvents(void) {
|
||||
return list_start != list_end;
|
||||
}
|
||||
|
||||
static void copyEvent(int event_size, int event_index) {
|
||||
int output_index = event_index*event_size;
|
||||
for (int i = 0; i < event_size; i++) {
|
||||
output_event_buffer[output_index] = input_event_buffer[list_start];
|
||||
list_start = (list_start + 1)%EVENT_BUFFER_SIZE;
|
||||
output_index++;
|
||||
}
|
||||
}
|
||||
static event_queue_t event_queue;
|
||||
|
||||
static bool handleMappedKey(unsigned char mapped_code, unsigned char state) {
|
||||
unsigned char old_state = key_buf[mapped_code];
|
||||
if (old_state != state) {
|
||||
key_buf[mapped_code] = state;
|
||||
if (buffer_enabled) {
|
||||
putEventElement(mapped_code);
|
||||
putEventElement(state);
|
||||
putEventElement(&event_queue, mapped_code);
|
||||
putEventElement(&event_queue, state);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -125,15 +96,15 @@ static bool writeChars(int num_chars, UniChar *buffer) {
|
|||
return false;
|
||||
unsigned char b0 = getFirstByte(buffer[0]);
|
||||
unsigned char b1 = getSecondByte(buffer[0]);
|
||||
putEventElement(b0);
|
||||
putEventElement(b1);
|
||||
putEventElement(&event_queue, b0);
|
||||
putEventElement(&event_queue, b1);
|
||||
for (int i = 1; i < num_chars; i++) {
|
||||
putEventElement(0);
|
||||
putEventElement(0);
|
||||
putEventElement(&event_queue, 0);
|
||||
putEventElement(&event_queue, 0);
|
||||
b0 = getFirstByte(buffer[i]);
|
||||
b1 = getSecondByte(buffer[i]);
|
||||
putEventElement(b0);
|
||||
putEventElement(b1);
|
||||
putEventElement(&event_queue, b0);
|
||||
putEventElement(&event_queue, b1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -179,12 +150,12 @@ static pascal OSStatus doKeyDown(EventHandlerCallRef next_handler, EventRef even
|
|||
if (handleKey(key_code, 1)) {
|
||||
if (translation_enabled) {
|
||||
if (!handleUnicode(event)) {
|
||||
putEventElement(0);
|
||||
putEventElement(0);
|
||||
putEventElement(&event_queue, 0);
|
||||
putEventElement(&event_queue, 0);
|
||||
}
|
||||
} else {
|
||||
putEventElement(0);
|
||||
putEventElement(0);
|
||||
putEventElement(&event_queue, 0);
|
||||
putEventElement(&event_queue, 0);
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
|
@ -202,8 +173,8 @@ static pascal OSStatus doKeyUp(EventHandlerCallRef next_handler, EventRef event,
|
|||
}
|
||||
lock();
|
||||
if (handleKey(key_code, 0)) {
|
||||
putEventElement(0);
|
||||
putEventElement(0);
|
||||
putEventElement(&event_queue, 0);
|
||||
putEventElement(&event_queue, 0);
|
||||
}
|
||||
unlock();
|
||||
return noErr;
|
||||
|
@ -213,8 +184,8 @@ static void handleModifier(UInt32 modifier_bit_mask, UInt32 modifier_bit, unsign
|
|||
bool key_down = (modifier_bit_mask & modifier_bit) == modifier_bit;
|
||||
unsigned char key_state = key_down ? 1 : 0;
|
||||
if (handleMappedKey(key_code, key_state)) {
|
||||
putEventElement(0);
|
||||
putEventElement(0);
|
||||
putEventElement(&event_queue, 0);
|
||||
putEventElement(&event_queue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,8 +317,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate(JNIEnv * env, jclas
|
|||
lock();
|
||||
buffer_enabled = false;
|
||||
translation_enabled = false;
|
||||
list_end = 0;
|
||||
list_start = 0;
|
||||
initEventQueue(&event_queue);
|
||||
memset(key_buf, 0, KEYBOARD_SIZE*sizeof(unsigned char));
|
||||
setupMappings();
|
||||
unlock();
|
||||
|
@ -371,10 +341,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nRead(JNIEnv * env, jclass
|
|||
event_size = 4;
|
||||
else
|
||||
event_size = 2;
|
||||
while (hasMoreEvents()) {
|
||||
copyEvent(event_size, num_events);
|
||||
num_events++;
|
||||
}
|
||||
num_events = copyEvents(&event_queue, event_size);
|
||||
unlock();
|
||||
return num_events;
|
||||
}
|
||||
|
@ -383,12 +350,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation(JNIEnv *
|
|||
translation_enabled = true;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer(JNIEnv * env, jclass clazz) {
|
||||
jfieldID fid_readBuffer = env->GetStaticFieldID(clazz, "readBuffer", "Ljava/nio/ByteBuffer;");
|
||||
jobject new_buffer = env->NewDirectByteBuffer(&output_event_buffer, EVENT_BUFFER_SIZE);
|
||||
env->SetStaticObjectField(clazz, fid_readBuffer, new_buffer);
|
||||
JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer(JNIEnv * env, jclass clazz) {
|
||||
jobject new_buffer = env->NewDirectByteBuffer(getOutputList(&event_queue), getEventBufferSize(&event_queue));
|
||||
buffer_enabled = true;
|
||||
return EVENT_BUFFER_SIZE/2;
|
||||
return new_buffer;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nisStateKeySet(JNIEnv *env, jclass clazz, jint key) {
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
* @version $Revision$
|
||||
*/
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/hid/IOHIDKeys.h>
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <IOKit/hid/IOHIDUsageTables.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include "Window.h"
|
||||
#include "tools.h"
|
||||
#include "org_lwjgl_input_Mouse.h"
|
||||
|
@ -54,6 +59,18 @@ static unsigned char button_state[NUM_BUTTONS];
|
|||
static int last_x;
|
||||
static int last_y;
|
||||
static int wheel_dz;
|
||||
static bool native_cursor;
|
||||
static bool created;
|
||||
static IOHIDDeviceInterface **device_interface;
|
||||
|
||||
/*static pascal OSStatus doMouseMoved(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
|
||||
printf("Mouse moved\n");
|
||||
return eventNotHandledErr; // allow the event to propagate
|
||||
}
|
||||
*/
|
||||
bool isMouseCreatedAndNotNativeCursor(void) {
|
||||
return created && !native_cursor;
|
||||
}
|
||||
|
||||
static pascal OSStatus doMouseDown(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
|
||||
printf("Mouse down\n");
|
||||
|
@ -79,18 +96,132 @@ printf("Mouse wheel\n");
|
|||
bool registerMouseHandler(JNIEnv* env, WindowRef win_ref) {
|
||||
bool error = registerHandler(env, win_ref, doMouseDown, kEventClassMouse, kEventMouseDown);
|
||||
error = error || registerHandler(env, win_ref, doMouseUp, kEventClassMouse, kEventMouseUp);
|
||||
//error = error || registerHandler(env, win_ref, doMouseMoved, kEventClassMouse, kEventMouseMoved);
|
||||
error = error || registerHandler(env, win_ref, doMouseWheel, kEventClassMouse, kEventMouseWheelMoved);
|
||||
return !error;
|
||||
}
|
||||
|
||||
static void printCFString(CFStringRef str) {
|
||||
CFIndex buffer_size = CFStringGetLength(str) + 1;
|
||||
char * buffer = (char *)malloc(buffer_size);
|
||||
if (buffer != NULL) {
|
||||
if (CFStringGetCString(str, buffer, buffer_size, CFStringGetSystemEncoding()))
|
||||
printf("%s", buffer);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void printCFNumber(CFNumberRef num) {
|
||||
long number;
|
||||
|
||||
if (CFNumberGetValue(num, kCFNumberLongType, &number))
|
||||
printf("0x%lx (%ld)", number, number);
|
||||
}
|
||||
|
||||
static bool getIntProperty(CFDictionaryRef dict, CFStringRef key, int *key_value) {
|
||||
CFTypeRef val = CFDictionaryGetValue(dict, key);
|
||||
if (val != NULL) {
|
||||
CFTypeID type = CFGetTypeID(val);
|
||||
if (type == CFNumberGetTypeID())
|
||||
if (CFNumberGetValue((CFNumberRef)val, kCFNumberIntType, key_value))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void printProperty(CFDictionaryRef dict, CFStringRef key) {
|
||||
CFTypeRef val = CFDictionaryGetValue(dict, key);
|
||||
if (val != NULL) {
|
||||
CFTypeID type = CFGetTypeID(val);
|
||||
if (type == CFArrayGetTypeID()) printf("array\n");
|
||||
else if (type == CFBooleanGetTypeID()) printf("boolean\n");
|
||||
else if (type == CFDictionaryGetTypeID()) printf("dictionary\n");
|
||||
else if (type == CFNumberGetTypeID()) printCFNumber((CFNumberRef)val);
|
||||
else if (type == CFStringGetTypeID()) printCFString((CFStringRef)val);
|
||||
else printf("<unknown object type>\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void releaseDevice(void) {
|
||||
(*device_interface)->close(device_interface);
|
||||
}
|
||||
|
||||
static bool initDevice(io_object_t hid_device) {
|
||||
io_name_t class_name;
|
||||
IOCFPlugInInterface **plugin_interface;
|
||||
SInt32 score;
|
||||
IOReturn io_err = IOObjectGetClass(hid_device, class_name);
|
||||
if (io_err != kIOReturnSuccess)
|
||||
return false;
|
||||
printf("Found device type %s\n", class_name);
|
||||
io_err = IOCreatePlugInInterfaceForService(hid_device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin_interface, &score);
|
||||
if (io_err != kIOReturnSuccess)
|
||||
return false;
|
||||
HRESULT plugin_err = (*plugin_interface)->QueryInterface(plugin_interface,
|
||||
CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
|
||||
device_interface
|
||||
);
|
||||
(*plugin_interface)->Release(plugin_interface);
|
||||
if (plugin_err != S_OK)
|
||||
return false;
|
||||
io_err = (*device_interface)->open(device_interface, 0);
|
||||
if (io_err != kIOReturnSuccess) {
|
||||
releaseDevice();
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
static void findDevice(void) {
|
||||
io_iterator_t device_iterator;
|
||||
io_object_t hid_device;
|
||||
kern_return_t kern_err;
|
||||
bool success = false;
|
||||
CFMutableDictionaryRef dev_props;
|
||||
CFMutableDictionaryRef matching_dic = IOServiceMatching(kIOHIDDeviceKey);
|
||||
IOReturn err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dic, &device_iterator);
|
||||
if (err != kIOReturnSuccess) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not find matching devices\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
while (!success && (hid_device = IOIteratorNext(device_iterator)) != NULL) {
|
||||
kern_err = IORegistryEntryCreateCFProperties(hid_device, &dev_props, kCFAllocatorDefault, kNilOptions);
|
||||
if (kern_err == KERN_SUCCESS && dev_props != NULL) {
|
||||
/*printf(" usage ");
|
||||
printProperty(dev_props, CFSTR(kIOHIDPrimaryUsageKey));
|
||||
printf(" usage page ");
|
||||
printProperty(dev_props, CFSTR(kIOHIDPrimaryUsagePageKey));*/
|
||||
int usage;
|
||||
int usage_page;
|
||||
if (getIntProperty(dev_props, CFSTR(kIOHIDPrimaryUsageKey), &usage) &&
|
||||
getIntProperty(dev_props, CFSTR(kIOHIDPrimaryUsagePageKey), &usage_page) &&
|
||||
usage_page == kHIDPage_GenericDesktop && usage == kHIDUsage_GD_Mouse) {
|
||||
printProperty(dev_props, CFSTR(kIOHIDProductKey));
|
||||
printf("\n");
|
||||
success = initDevice(hid_device);
|
||||
if (success)
|
||||
printf("Device found: ");
|
||||
}
|
||||
CFRelease(dev_props);
|
||||
}
|
||||
IOObjectRelease(hid_device);
|
||||
}
|
||||
IOObjectRelease(device_iterator);
|
||||
}
|
||||
|
||||
static void pollDevice(void) {
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nHasWheel(JNIEnv *, jclass) {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetButtonCount(JNIEnv *, jclass) {
|
||||
return NUM_BUTTONS;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_initIDs(JNIEnv * env, jclass clazz) {
|
||||
fid_dx = env->GetStaticFieldID(clazz, "dx", "I");
|
||||
fid_dy = env->GetStaticFieldID(clazz, "dy", "I");
|
||||
|
@ -114,31 +245,39 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate(JNIEnv * env, jclass c
|
|||
last_x = 0;
|
||||
last_y = 0;
|
||||
wheel_dz = 0;
|
||||
CGAssociateMouseAndMouseCursorPosition(FALSE);
|
||||
native_cursor = false;
|
||||
findDevice();
|
||||
//CGAssociateMouseAndMouseCursorPosition(FALSE);
|
||||
created = true;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy(JNIEnv * env, jclass clazz) {
|
||||
CGAssociateMouseAndMouseCursorPosition(TRUE);
|
||||
if (!native_cursor)
|
||||
CGAssociateMouseAndMouseCursorPosition(TRUE);
|
||||
created = false;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll(JNIEnv * env, jclass clazz) {
|
||||
lock();
|
||||
/*Point cursor_pos;
|
||||
GetMouse(&cursor_pos);
|
||||
int dx = cursor_pos.v - last_x;
|
||||
int dy = cursor_pos.h - last_y;
|
||||
last_x += dx;
|
||||
last_y += dy;*/
|
||||
CGMouseDelta dx, dy;
|
||||
CGGetLastMouseDelta(&dx, &dy);
|
||||
int dx;
|
||||
int dy;
|
||||
if (!native_cursor) {
|
||||
pollDevice();
|
||||
} else {
|
||||
Point cursor_pos;
|
||||
GetMouse(&cursor_pos);
|
||||
dx = cursor_pos.v - last_x;
|
||||
dy = cursor_pos.h - last_y;
|
||||
last_x += dx;
|
||||
last_y += dy;
|
||||
}
|
||||
env->SetStaticIntField(clazz, fid_dx, (jint)dx);
|
||||
env->SetStaticIntField(clazz, fid_dy, (jint)dy);
|
||||
env->SetStaticIntField(clazz, fid_dwheel, (jint)wheel_dz);
|
||||
jbooleanArray buttons_array = (jbooleanArray)env->GetStaticObjectField(clazz, fid_buttons);
|
||||
env->SetBooleanArrayRegion(buttons_array, 0, NUM_BUTTONS, button_state);
|
||||
wheel_dz = 0;
|
||||
unlock();
|
||||
/*
|
||||
if (dx != 0 || dy != 0)
|
||||
/*if (dx != 0 || dy != 0)
|
||||
printf("dx %d dy %d, lx %d ly %d\n", dx, dy, last_x, last_y);*/
|
||||
unlock();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "org_lwjgl_opengl_Window.h"
|
||||
#include "extgl.h"
|
||||
#include "tools.h"
|
||||
#include "common_tools.h"
|
||||
|
||||
static WindowRef win_ref;
|
||||
static AGLContext context;
|
||||
|
@ -52,6 +53,8 @@ static Ptr fullscreen_ptr;
|
|||
static bool current_fullscreen;
|
||||
static bool miniaturized;
|
||||
static bool activated;
|
||||
static int center_x;
|
||||
static int center_y;
|
||||
|
||||
static void setWindowTitle(JNIEnv *env, jstring title_obj) {
|
||||
const char* title = env->GetStringUTFChars(title_obj, NULL);
|
||||
|
@ -87,10 +90,17 @@ static pascal OSStatus doMaximize(EventHandlerCallRef next_handler, EventRef eve
|
|||
return eventNotHandledErr;
|
||||
}
|
||||
|
||||
static void warpCursorToCenter(void) {
|
||||
CGPoint p = {center_x, center_y};
|
||||
CGWarpMouseCursorPosition(p);
|
||||
}
|
||||
|
||||
static pascal OSStatus doActivate(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
|
||||
lock();
|
||||
miniaturized = false;
|
||||
activated = true;
|
||||
if (isMouseCreatedAndNotNativeCursor())
|
||||
warpCursorToCenter();
|
||||
unlock();
|
||||
return eventNotHandledErr;
|
||||
}
|
||||
|
@ -107,6 +117,22 @@ static pascal OSStatus doQuit(EventHandlerCallRef next_handler, EventRef event,
|
|||
return noErr;
|
||||
}
|
||||
|
||||
static pascal OSStatus doBoundsChanged(EventHandlerCallRef next_handler, EventRef event, void *user_data) {
|
||||
Rect rect;
|
||||
OSStatus err = GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(rect), NULL, &rect);
|
||||
if (err != noErr) {
|
||||
#ifdef _DEBUG
|
||||
printf("Could not get bounds from bounds changed event\n");
|
||||
#endif
|
||||
return eventNotHandledErr;
|
||||
}
|
||||
lock();
|
||||
center_x = (rect.left + rect.right)/2;
|
||||
center_y = (rect.top + rect.bottom)/2;
|
||||
unlock();
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static bool registerEventHandlers(JNIEnv *env) {
|
||||
bool error;
|
||||
error = registerHandler(env, win_ref, doQuit, kEventClassWindow, kEventWindowClose);
|
||||
|
@ -114,6 +140,7 @@ static bool registerEventHandlers(JNIEnv *env) {
|
|||
error = error || registerHandler(env, win_ref, doDeactivate, kEventClassWindow, kEventWindowDeactivated);
|
||||
error = error || registerHandler(env, win_ref, doMiniaturized, kEventClassWindow, kEventWindowCollapsed);
|
||||
error = error || registerHandler(env, win_ref, doMaximize, kEventClassWindow, kEventWindowExpanded);
|
||||
error = error || registerHandler(env, win_ref, doBoundsChanged, kEventClassWindow, kEventWindowBoundsChanged);
|
||||
return !error && registerKeyboardHandler(env, win_ref) && registerMouseHandler(env, win_ref);
|
||||
}
|
||||
|
||||
|
@ -185,6 +212,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nCreate(JNIEnv *env, jclass
|
|||
kWindowCollapseBoxAttribute|
|
||||
kWindowStandardHandlerAttribute;
|
||||
SetRect(&rect, x, y, x + width, y + height);
|
||||
center_x = x + width/2;
|
||||
center_y = y + height/2;
|
||||
current_fullscreen = fullscreen == JNI_TRUE;
|
||||
miniaturized = false;
|
||||
activated = true;
|
||||
|
@ -232,8 +261,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_nCreate(JNIEnv *env, jclass
|
|||
}
|
||||
ShowWindow(win_ref);
|
||||
SelectWindow(win_ref);
|
||||
CGPoint p = {x, y};
|
||||
CGWarpMouseCursorPosition(p);
|
||||
warpCursorToCenter();
|
||||
CGPoint p = {center_x, center_y};
|
||||
CGPostMouseEvent(p, FALSE, 1, TRUE);
|
||||
CGPostMouseEvent(p, FALSE, 1, FALSE);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "tools.h"
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include "tools.h"
|
||||
#include "common_tools.h"
|
||||
|
||||
MPCriticalRegionID critical_region;
|
||||
|
||||
|
|
Loading…
Reference in New Issue