From cbe41294a5fc5f4c8d5e3aaabfd810dc35262f14 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 3 Jul 2006 18:07:44 +0000 Subject: [PATCH] Linux: Moved most input related stuff from native to java --- build.xml | 1 + src/java/org/lwjgl/opengl/LinuxDisplay.java | 411 ++++++++-- src/java/org/lwjgl/opengl/LinuxKeyboard.java | 305 +++++++ src/java/org/lwjgl/opengl/LinuxKeycodes.java | 760 ++++++++++++++++++ src/java/org/lwjgl/opengl/LinuxMouse.java | 264 ++++++ src/native/common/common_tools.c | 74 +- src/native/common/common_tools.h | 12 +- src/native/linux/Window.h | 23 - src/native/linux/display.c | 13 +- src/native/linux/org_lwjgl_input_Keyboard.c | 692 ---------------- src/native/linux/org_lwjgl_input_Mouse.c | 367 --------- src/native/linux/org_lwjgl_opengl_Display.c | 222 ++--- .../linux/org_lwjgl_opengl_LinuxKeyboard.c | 145 ++++ .../linux/org_lwjgl_opengl_LinuxMouse.c | 105 +++ src/native/win32/dinputhelper.c | 14 - src/native/win32/dinputhelper.h | 1 - 16 files changed, 2056 insertions(+), 1353 deletions(-) create mode 100644 src/java/org/lwjgl/opengl/LinuxKeyboard.java create mode 100644 src/java/org/lwjgl/opengl/LinuxKeycodes.java create mode 100644 src/java/org/lwjgl/opengl/LinuxMouse.java delete mode 100644 src/native/linux/org_lwjgl_input_Keyboard.c delete mode 100644 src/native/linux/org_lwjgl_input_Mouse.c create mode 100644 src/native/linux/org_lwjgl_opengl_LinuxKeyboard.c create mode 100644 src/native/linux/org_lwjgl_opengl_LinuxMouse.c diff --git a/build.xml b/build.xml index 40b3cdaa..1cc58496 100644 --- a/build.xml +++ b/build.xml @@ -450,6 +450,7 @@ + diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index c5864901..3ae46658 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -47,6 +47,13 @@ import org.lwjgl.LWJGLUtil; import org.lwjgl.input.Keyboard; final class LinuxDisplay implements DisplayImplementation { + /* X11 constants */ + private final static int GrabSuccess = 0; + private final static int AutoRepeatModeOff = 0; + private final static int AutoRepeatModeOn = 1; + private final static int AutoRepeatModeDefault = 2; + + /** Window mode enum */ private static final int FULLSCREEN_LEGACY = 1; private static final int FULLSCREEN_NETWM = 2; @@ -63,8 +70,6 @@ final class LinuxDisplay implements DisplayImplementation { /** Current mode swithcing API */ private static int current_displaymode_extension = NONE; - private static final int NUM_BUTTONS = 3; - /** Keep track on the current awt lock owner to avoid * depending on JAWT locking to be re-entrant (This is a * problem with GCJ). JAWT locking is not that well specified @@ -86,6 +91,17 @@ final class LinuxDisplay implements DisplayImplementation { private static DisplayMode saved_mode; private static DisplayMode current_mode; + private static boolean keyboard_grabbed; + private static boolean pointer_grabbed; + private static boolean input_released; + private static boolean grab; + private static boolean focused; + private static ByteBuffer current_cursor; + private static ByteBuffer blank_cursor; + + private static LinuxKeyboard keyboard; + private static LinuxMouse mouse; + private static ByteBuffer getCurrentGammaRamp() throws LWJGLException { lockAWT(); try { @@ -257,15 +273,113 @@ final class LinuxDisplay implements DisplayImplementation { return WINDOWED; } + private static native long getDisplay(); + private static native int getScreen(); + private static native long getWindow(); + + private static void ungrabKeyboard() { + if (keyboard_grabbed) { + nUngrabKeyboard(getDisplay()); + keyboard_grabbed = false; + } + } + private static native int nUngrabKeyboard(long display); + + private static void grabKeyboard() { + if (!keyboard_grabbed) { + int res = nGrabKeyboard(getDisplay(), getWindow()); + if (res == GrabSuccess) + keyboard_grabbed = true; + } + } + private static native int nGrabKeyboard(long display, long window); + + private static void grabPointer() { + if (!pointer_grabbed) { + int result = nGrabPointer(getDisplay(), getWindow()); + if (result == GrabSuccess) { + pointer_grabbed = true; + // make sure we have a centered window + if (isLegacyFullscreen()) { + nSetViewPort(getDisplay(), getWindow(), getScreen()); + } + } + } + } + private static native int nGrabPointer(long display, long window); + private static native void nSetViewPort(long display, long window, int screen); + + private static void ungrabPointer() { + if (pointer_grabbed) { + pointer_grabbed = false; + nUngrabPointer(getDisplay()); + } + } + private static native int nUngrabPointer(long display); + + private static boolean isFullscreen() { + return current_window_mode == FULLSCREEN_LEGACY || current_window_mode == FULLSCREEN_NETWM; + } + + private static boolean shouldGrab() { + return !input_released && grab; + } + + private static void updatePointerGrab() { + if (isFullscreen() || shouldGrab()) { + grabPointer(); + } else { + ungrabPointer(); + } + updateCursor(); + } + + private static void updateCursor() { + ByteBuffer cursor; + if (shouldGrab()) { + cursor = blank_cursor; + } else { + cursor = current_cursor; + } + nDefineCursor(getDisplay(), getWindow(), cursor); + } + private static native void nDefineCursor(long display, long window, ByteBuffer cursor_handle); + + private static boolean isLegacyFullscreen() { + return current_window_mode == FULLSCREEN_LEGACY; + } + + private static void updateKeyboardGrab() { + if (isLegacyFullscreen()) + grabKeyboard(); + else + ungrabKeyboard(); + } + public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException { lockAWT(); try { - ByteBuffer handle = peer_info.lockAndGetHandle(); + incDisplay(); try { - current_window_mode = getWindowMode(fullscreen); - nCreateWindow(handle, mode, current_window_mode, x, y); - } finally { - peer_info.unlock(); + ByteBuffer handle = peer_info.lockAndGetHandle(); + try { + current_window_mode = getWindowMode(fullscreen); + nCreateWindow(handle, mode, current_window_mode, x, y); + blank_cursor = createBlankCursor(); + current_cursor = null; + focused = true; + input_released = false; + pointer_grabbed = false; + keyboard_grabbed = false; + grab = false; + updateInputGrab(); + nSetRepeatMode(getDisplay(), AutoRepeatModeOff); + } finally { + peer_info.unlock(); + } + } catch (LWJGLException e) { + decDisplay(); + throw e; } } finally { unlockAWT(); @@ -273,23 +387,41 @@ final class LinuxDisplay implements DisplayImplementation { } private static native void nCreateWindow(ByteBuffer peer_info_handle, DisplayMode mode, int window_mode, int x, int y) throws LWJGLException; + private static void updateInputGrab() { + updatePointerGrab(); + updateKeyboardGrab(); + } + public void destroyWindow() { lockAWT(); - nDestroyWindow(); - unlockAWT(); + try { + try { + setNativeCursor(null); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to reset cursor: " + e.getMessage()); + } + nDestroyCursor(blank_cursor); + blank_cursor = null; + ungrabKeyboard(); + nDestroyWindow(); + nSetRepeatMode(getDisplay(), AutoRepeatModeDefault); + decDisplay(); + } finally { + unlockAWT(); + } } private static native void nDestroyWindow(); public void switchDisplayMode(DisplayMode mode) throws LWJGLException { lockAWT(); try { - nSwitchDisplayMode(current_displaymode_extension, mode); + nSwitchDisplayMode(getScreen(), current_displaymode_extension, mode); current_mode = mode; } finally { unlockAWT(); } } - private static native void nSwitchDisplayMode(int extension, DisplayMode mode) throws LWJGLException; + private static native void nSwitchDisplayMode(int screen, int extension, DisplayMode mode) throws LWJGLException; public void resetDisplayMode() { lockAWT(); @@ -312,7 +444,7 @@ final class LinuxDisplay implements DisplayImplementation { try { incDisplay(); try { - return nGetGammaRampLength(); + return nGetGammaRampLength(getDisplay(), getScreen()); } catch (LWJGLException e) { LWJGLUtil.log("Got exception while querying gamma length: " + e); return 0; @@ -327,7 +459,7 @@ final class LinuxDisplay implements DisplayImplementation { unlockAWT(); } } - private static native int nGetGammaRampLength() throws LWJGLException; + private static native int nGetGammaRampLength(long display, int screen) throws LWJGLException; public void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException { if (!isXF86VidModeSupported()) @@ -338,13 +470,13 @@ final class LinuxDisplay implements DisplayImplementation { private static void doSetGamma(ByteBuffer native_gamma) throws LWJGLException { lockAWT(); try { - nSetGammaRamp(native_gamma); + nSetGammaRamp(getScreen(), native_gamma); current_gamma = native_gamma; } finally { unlockAWT(); } } - private static native void nSetGammaRamp(ByteBuffer gammaRamp) throws LWJGLException; + private static native void nSetGammaRamp(int screen, ByteBuffer gammaRamp) throws LWJGLException; private static ByteBuffer convertToNativeRamp(FloatBuffer ramp) throws LWJGLException { return nConvertToNativeRamp(ramp, ramp.position(), ramp.remaining()); @@ -406,34 +538,42 @@ final class LinuxDisplay implements DisplayImplementation { public void setTitle(String title) { lockAWT(); - nSetTitle(title); - unlockAWT(); + try { + nSetTitle(title); + } finally { + unlockAWT(); + } } private static native void nSetTitle(String title); public boolean isCloseRequested() { lockAWT(); - boolean result = nIsCloseRequested(); - unlockAWT(); - return result; + try { + return nIsCloseRequested(); + } finally { + unlockAWT(); + } } private static native boolean nIsCloseRequested(); public boolean isVisible() { lockAWT(); - boolean result = nIsVisible(); - unlockAWT(); - return result; + try { + return nIsVisible(); + } finally { + unlockAWT(); + } } private static native boolean nIsVisible(); public boolean isActive() { lockAWT(); - boolean result = nIsActive(current_window_mode); - unlockAWT(); - return result; + try { + return focused || isLegacyFullscreen(); + } finally { + unlockAWT(); + } } - private static native boolean nIsActive(int window_mode); public boolean isDirty() { lockAWT(); @@ -452,17 +592,22 @@ final class LinuxDisplay implements DisplayImplementation { lockAWT(); try { nUpdate(current_displaymode_extension, current_window_mode, saved_gamma, current_gamma, saved_mode, current_mode); + checkInput(); } catch (LWJGLException e) { LWJGLUtil.log("Caught exception while processing messages: " + e); + } finally { + unlockAWT(); } - unlockAWT(); } private static native void nUpdate(int extension, int current_window_mode, ByteBuffer saved_gamma, ByteBuffer current_gamma, DisplayMode saved_mode, DisplayMode current_mode) throws LWJGLException; public void reshape(int x, int y, int width, int height) { lockAWT(); - nReshape(x, y, width, height); - unlockAWT(); + try { + nReshape(x, y, width, height); + } finally { + unlockAWT(); + } } private static native void nReshape(int x, int y, int width, int height); @@ -488,61 +633,118 @@ final class LinuxDisplay implements DisplayImplementation { } public int getButtonCount() { - return NUM_BUTTONS; + return mouse.getButtonCount(); } public void createMouse() { lockAWT(); - nCreateMouse(current_window_mode); - unlockAWT(); + try { + mouse = new LinuxMouse(getDisplay(), getWindow()); + } finally { + unlockAWT(); + } } - private static native void nCreateMouse(int window_mode); public void destroyMouse() { - lockAWT(); - nDestroyMouse(); - unlockAWT(); + mouse = null; } - private static native void nDestroyMouse(); public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) { update(); lockAWT(); - nPollMouse(coord_buffer, buttons); - unlockAWT(); + try { + mouse.poll(grab, coord_buffer, buttons); + } finally { + unlockAWT(); + } } - private static native void nPollMouse(IntBuffer coord_buffer, ByteBuffer buttons); public int readMouse(IntBuffer buffer) { update(); lockAWT(); - int count = nReadMouse(buffer, buffer.position()); - unlockAWT(); - return count; + try { + return mouse.read(buffer); + } finally { + unlockAWT(); + } } - private static native int nReadMouse(IntBuffer buffer, int buffer_position); public void setCursorPosition(int x, int y) { lockAWT(); - nSetCursorPosition(x, y); - unlockAWT(); + try { + mouse.setCursorPosition(x, y); + } finally { + unlockAWT(); + } } - private native void nSetCursorPosition(int x, int y); - public void grabMouse(boolean grab) { - lockAWT(); - nGrabMouse(current_window_mode, grab); - unlockAWT(); + private static void checkInput() { + focused = nGetInputFocus(getDisplay()) == getWindow(); + if (focused) { + acquireInput(); + } else { + releaseInput(); + } + } + private static native long nGetInputFocus(long display); + + private static void releaseInput() { + if (isLegacyFullscreen() || input_released) + return; + input_released = true; + nSetRepeatMode(getDisplay(), AutoRepeatModeDefault); + updateInputGrab(); + if (current_window_mode == FULLSCREEN_NETWM) { + nIconifyWindow(getDisplay(), getWindow(), getScreen()); + try { + nSwitchDisplayMode(getScreen(), current_displaymode_extension, saved_mode); + nSetGammaRamp(getScreen(), saved_gamma); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to restore saved mode: " + e.getMessage()); + } + } + } + private static native void nIconifyWindow(long display, long window, int screen); + + private static void acquireInput() { + if (isLegacyFullscreen() || !input_released) + return; + input_released = false; + nSetRepeatMode(getDisplay(), AutoRepeatModeOff); + updateInputGrab(); + if (current_window_mode == FULLSCREEN_NETWM) { + try { + nSwitchDisplayMode(getScreen(), current_displaymode_extension, current_mode); + nSetGammaRamp(getScreen(), current_gamma); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to restore mode: " + e.getMessage()); + } + } + } + private static native void nSetRepeatMode(long display, int mode); + + public void grabMouse(boolean new_grab) { + lockAWT(); + try { + if (new_grab != grab) { + grab = new_grab; + updateInputGrab(); + mouse.changeGrabbed(grab, pointer_grabbed, shouldGrab()); + } + } finally { + unlockAWT(); + } } - private static native void nGrabMouse(int window_mode, boolean grab); public int getNativeCursorCapabilities() { lockAWT(); try { incDisplay(); - int caps = nGetNativeCursorCapabilities(); - decDisplay(); - return caps; + try { + return nGetNativeCursorCapabilities(); + } finally { + decDisplay(); + } } catch (LWJGLException e) { throw new RuntimeException(e); } finally { @@ -552,19 +754,24 @@ final class LinuxDisplay implements DisplayImplementation { private static native int nGetNativeCursorCapabilities() throws LWJGLException; public void setNativeCursor(Object handle) throws LWJGLException { + current_cursor = (ByteBuffer)handle; lockAWT(); - nSetNativeCursor(handle); - unlockAWT(); + try { + updateCursor(); + } finally { + unlockAWT(); + } } - private static native void nSetNativeCursor(Object handle) throws LWJGLException; public int getMinCursorSize() { lockAWT(); try { incDisplay(); - int min_size = nGetMinCursorSize(); - decDisplay(); - return min_size; + try { + return nGetMinCursorSize(); + } finally { + decDisplay(); + } } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred in getMinCursorSize: " + e); return 0; @@ -578,9 +785,11 @@ final class LinuxDisplay implements DisplayImplementation { lockAWT(); try { incDisplay(); - int max_size = nGetMaxCursorSize(); - decDisplay(); - return max_size; + try { + return nGetMaxCursorSize(); + } finally { + decDisplay(); + } } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred in getMaxCursorSize: " + e); return 0; @@ -594,36 +803,41 @@ final class LinuxDisplay implements DisplayImplementation { public void createKeyboard() throws LWJGLException { lockAWT(); try { - nCreateKeyboard(current_window_mode); + keyboard = new LinuxKeyboard(getDisplay(), getWindow()); } finally { unlockAWT(); } } - private static native void nCreateKeyboard(int window_mode) throws LWJGLException; public void destroyKeyboard() { lockAWT(); - nDestroyKeyboard(); - unlockAWT(); + try { + keyboard.destroy(); + keyboard = null; + } finally { + unlockAWT(); + } } - private static native void nDestroyKeyboard(); public void pollKeyboard(ByteBuffer keyDownBuffer) { update(); lockAWT(); - nPollKeyboard(keyDownBuffer); - unlockAWT(); + try { + keyboard.poll(keyDownBuffer); + } finally { + unlockAWT(); + } } - private static native void nPollKeyboard(ByteBuffer keyDownBuffer); public int readKeyboard(IntBuffer buffer) { update(); lockAWT(); - int count = nReadKeyboard(buffer, buffer.position()); - unlockAWT(); - return count; + try { + return keyboard.read(buffer); + } finally { + unlockAWT(); + } } - private static native int nReadKeyboard(IntBuffer buffer, int buffer_position); /* public int isStateKeySet(int key) { return Keyboard.STATE_UNKNOWN; @@ -631,6 +845,11 @@ final class LinuxDisplay implements DisplayImplementation { */ private static native ByteBuffer nCreateCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, int images_offset, IntBuffer delays, int delays_offset) throws LWJGLException; + private static ByteBuffer createBlankCursor() { + return nCreateBlankCursor(getDisplay(), getWindow()); + } + private static native ByteBuffer nCreateBlankCursor(long display, long window); + public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException { lockAWT(); try { @@ -648,9 +867,12 @@ final class LinuxDisplay implements DisplayImplementation { public void destroyCursor(Object cursorHandle) { lockAWT(); - nDestroyCursor(cursorHandle); - decDisplay(); - unlockAWT(); + try { + nDestroyCursor(cursorHandle); + decDisplay(); + } finally { + unlockAWT(); + } } private static native void nDestroyCursor(Object cursorHandle); @@ -658,9 +880,11 @@ final class LinuxDisplay implements DisplayImplementation { lockAWT(); try { incDisplay(); - int caps = nGetPbufferCapabilities(); - decDisplay(); - return caps; + try { + return nGetPbufferCapabilities(); + } finally { + decDisplay(); + } } catch (LWJGLException e) { LWJGLUtil.log("Exception occurred in getPbufferCapabilities: " + e); return 0; @@ -753,4 +977,25 @@ final class LinuxDisplay implements DisplayImplementation { } private static native void nSetWindowIcon(ByteBuffer icon, int icons_size, int width, int height); + + /* Callbacks from nUpdate() */ + private static void handleButtonEvent(long millis, int type, int button, int state) { + if (mouse != null) + mouse.handleButtonEvent(grab, type, button); + } + + private static void handleKeyEvent(long event_ptr, long millis, int type, int keycode, int state) { + if (keyboard != null) + keyboard.handleKeyEvent(event_ptr, millis, type, keycode, state); + } + + private static void handlePointerMotionEvent(long root_window, int x_root, int y_root, int x, int y, int state) { + if (mouse != null) + mouse.handlePointerMotion(grab, pointer_grabbed, shouldGrab(), root_window, x_root, y_root, x, y); + } + + private static void handleWarpEvent(int x, int y) { + if (mouse != null) + mouse.handleWarpEvent(x, y); + } } diff --git a/src/java/org/lwjgl/opengl/LinuxKeyboard.java b/src/java/org/lwjgl/opengl/LinuxKeyboard.java new file mode 100644 index 00000000..32d270d2 --- /dev/null +++ b/src/java/org/lwjgl/opengl/LinuxKeyboard.java @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.CharBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.input.Keyboard; + +import java.nio.charset.CharsetDecoder; +import java.nio.charset.Charset; + +final class LinuxKeyboard { + private static final int LockMapIndex = 1; + private static final int KeyPress = 2; + private static final int KeyRelease = 3; + private static final long NoSymbol = 0; + private static final long ShiftMask = 1 << 0; + private static final long LockMask = 1 << 1; + private static final int XLookupChars = 2; + private static final int XLookupBoth = 4; + + + private static final int EVENT_SIZE = 3; + private static final int KEYBOARD_BUFFER_SIZE = 50; + + private final long xim; + private final long xic; + + private final int numlock_mask; + private final int modeswitch_mask; + private final int caps_lock_mask; + private final int shift_lock_mask; + + private final ByteBuffer compose_status; + + private final byte[] key_down_buffer = new byte[Keyboard.KEYBOARD_SIZE]; + private final EventQueue event_queue = new EventQueue(EVENT_SIZE); + + private final int[] tmp_event = new int[3]; + private final int[] temp_translation_buffer = new int[KEYBOARD_BUFFER_SIZE]; + private final ByteBuffer native_translation_buffer = BufferUtils.createByteBuffer(KEYBOARD_BUFFER_SIZE); + private final CharsetDecoder utf8_decoder = Charset.forName("UTF-8").newDecoder(); + private final CharBuffer char_buffer = CharBuffer.allocate(KEYBOARD_BUFFER_SIZE); + + public LinuxKeyboard(long display, long window) { + long modifier_map = getModifierMapping(display); + int tmp_numlock_mask = 0; + int tmp_modeswitch_mask = 0; + int tmp_caps_lock_mask = 0; + int tmp_shift_lock_mask = 0; + if (modifier_map != 0) { + int max_keypermod = getMaxKeyPerMod(modifier_map); + // Find modifier masks + int i, j; + for (i = 0; i < 8; i++) { + for (j = 0; j < max_keypermod; j++) { + int key_code = lookupModifierMap(modifier_map, i*max_keypermod + j); + int key_sym = (int)keycodeToKeySym(display, key_code); + int mask = 1 << i; + switch (key_sym) { + case LinuxKeycodes.XK_Num_Lock: + tmp_numlock_mask |= mask; + break; + case LinuxKeycodes.XK_Mode_switch: + tmp_modeswitch_mask |= mask; + break; + case LinuxKeycodes.XK_Caps_Lock: + if (i == LockMapIndex) { + tmp_caps_lock_mask = mask; + tmp_shift_lock_mask = 0; + } + break; + case LinuxKeycodes.XK_Shift_Lock: + if (i == LockMapIndex && tmp_caps_lock_mask == 0) + tmp_shift_lock_mask = mask; + break; + default: + break; + } + } + } + freeModifierMapping(modifier_map); + } + numlock_mask = tmp_numlock_mask; + modeswitch_mask = tmp_modeswitch_mask; + caps_lock_mask = tmp_caps_lock_mask; + shift_lock_mask = tmp_shift_lock_mask; + xim = openIM(display); + if (xim != 0) { + xic = createIC(xim, window); + if (xic != 0) { + setupIMEventMask(display, window, xic); + } else { + destroy(); + } + } else { + xic = 0; + } + compose_status = allocateComposeStatus(); + } + private static native long getModifierMapping(long display); + private static native void freeModifierMapping(long modifier_map); + private static native int getMaxKeyPerMod(long modifier_map); + private static native int lookupModifierMap(long modifier_map, int index); + private static native long keycodeToKeySym(long display, int key_code); + + private static native long openIM(long display); + private static native long createIC(long xim, long window); + private static native void setupIMEventMask(long display, long window, long xic); + private static native ByteBuffer allocateComposeStatus(); + + public void destroy() { + destroyIC(xic); + closeIM(xim); + } + private static native void destroyIC(long xic); + private static native void closeIM(long xim); + + public int read(IntBuffer buffer) { + return event_queue.copyEvents(buffer); + } + + public void poll(ByteBuffer keyDownBuffer) { + int old_position = keyDownBuffer.position(); + keyDownBuffer.put(key_down_buffer); + keyDownBuffer.position(old_position); + } + + private void putKeyboardEvent(int keycode, int state, int ch) { + tmp_event[0] = keycode; + tmp_event[1] = state; + tmp_event[2] = ch; + event_queue.putEvent(tmp_event); + } + + private int lookupStringISO88591(long event_ptr, int[] translation_buffer) { + int i; + + int num_chars = lookupString(event_ptr, native_translation_buffer, compose_status); + for (i = 0; i < num_chars; i++) { + translation_buffer[i] = ((int)native_translation_buffer.get(i)) & 0xff; + } + return num_chars; + } + private static native int lookupString(long event_ptr, ByteBuffer buffer, ByteBuffer compose_status); + + private int lookupStringUnicode(long event_ptr, int[] translation_buffer) { + int status = utf8LookupString(xic, event_ptr, native_translation_buffer, native_translation_buffer.position(), native_translation_buffer.remaining()); + if (status != XLookupChars && status != XLookupBoth) + return 0; + native_translation_buffer.flip(); + utf8_decoder.decode(native_translation_buffer, char_buffer, true); + native_translation_buffer.compact(); + char_buffer.flip(); + int i = 0; + while (char_buffer.hasRemaining() && i < translation_buffer.length) { + translation_buffer[i++] = char_buffer.get(); + } + char_buffer.compact(); + return i; + } + private static native int utf8LookupString(long xic, long event_ptr, ByteBuffer buffer, int pos, int size); + + private int lookupString(long event_ptr, int[] translation_buffer) { + if (xic != 0) { + return lookupStringUnicode(event_ptr, translation_buffer); + } else + return lookupStringISO88591(event_ptr, translation_buffer); + } + + private void translateEvent(long event_ptr, int event_type, int keycode, int key_state) { + int num_chars, i; + int ch; + + if (event_type == KeyRelease) { + putKeyboardEvent(keycode, key_state, 0); + return; + } + num_chars = lookupString(event_ptr, temp_translation_buffer); + if (num_chars > 0) { + ch = temp_translation_buffer[0]; + putKeyboardEvent(keycode, key_state, ch); + for (i = 1; i < num_chars; i++) { + ch = temp_translation_buffer[i]; + putKeyboardEvent(0, 0, ch); + } + } else { + putKeyboardEvent(keycode, key_state, 0); + } + } + + private static boolean isKeypadKeysym(long keysym) { + return (0xFF80 <= keysym && keysym <= 0xFFBD) || + (0x11000000 <= keysym && keysym <= 0x1100FFFF); + } + + private static boolean isNoSymbolOrVendorSpecific(long keysym) { + return keysym == NoSymbol || (keysym & (1 << 28)) != 0; + } + + private static long getKeySym(long event_ptr, int group, int index) { + long keysym = lookupKeysym(event_ptr, group*2 + index); + if (isNoSymbolOrVendorSpecific(keysym) && index == 1) { + keysym = lookupKeysym(event_ptr, group*2 + 0); + } + if (isNoSymbolOrVendorSpecific(keysym) && group == 1) + keysym = getKeySym(event_ptr, 0, index); + return keysym; + } + private static native long lookupKeysym(long event_ptr, int index); + private static native long toUpper(long keysym); + + private long mapEventToKeySym(long event_ptr, int event_state) { + int group; + long keysym; + if ((event_state & modeswitch_mask) != 0) + group = 1; + else + group = 0; + if ((event_state & numlock_mask) != 0 && isKeypadKeysym(keysym = getKeySym(event_ptr, group, 1))) { + if ((event_state & (ShiftMask | shift_lock_mask)) != 0) { + return getKeySym(event_ptr, group, 0); + } else { + return keysym; + } + } else if ((event_state & (ShiftMask | LockMask)) == 0) { + return getKeySym(event_ptr, group, 0); + } else if ((event_state & ShiftMask) == 0) { + keysym = getKeySym(event_ptr, group, 0); + if ((event_state & caps_lock_mask) != 0) + keysym = toUpper(keysym); + return keysym; + } else { + keysym = getKeySym(event_ptr, group, 1); + if ((event_state & caps_lock_mask) != 0) + keysym = toUpper(keysym); + return keysym; + } + } + + private int getKeycode(long event_ptr, int event_state) { + long keysym = mapEventToKeySym(event_ptr, event_state); + int keycode = LinuxKeycodes.mapKeySymToLWJGLKeyCode(keysym); + if (keycode == Keyboard.KEY_NONE) { + // Try unshifted keysym mapping + keysym = lookupKeysym(event_ptr, 0); + keycode = LinuxKeycodes.mapKeySymToLWJGLKeyCode(keysym); + } + return keycode; + } + + private byte getKeyState(int event_type) { + switch (event_type) { + case KeyPress: + return 1; + case KeyRelease: + return 0; + default: + throw new IllegalArgumentException("Unknown event_type: " + event_type); + } + } + + public void handleKeyEvent(long event_ptr, long millis, int event_type, int event_keycode, int event_state) { + int keycode = getKeycode(event_ptr, event_state); + byte key_state = getKeyState(event_type); + key_down_buffer[keycode] = key_state; + translateEvent(event_ptr, event_type, keycode, key_state); + } +} diff --git a/src/java/org/lwjgl/opengl/LinuxKeycodes.java b/src/java/org/lwjgl/opengl/LinuxKeycodes.java new file mode 100644 index 00000000..aa0e6ec5 --- /dev/null +++ b/src/java/org/lwjgl/opengl/LinuxKeycodes.java @@ -0,0 +1,760 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * @author elias_naur + */ + +import org.lwjgl.input.Keyboard; + +final class LinuxKeycodes { + public final static int XK_Kanji = 0xff21; + + public final static int XK_ISO_Left_Tab = 0xfe20; + + public final static int XK_dead_grave = 0xfe50; + public final static int XK_dead_acute = 0xfe51; + public final static int XK_dead_circumflex = 0xfe52; + public final static int XK_dead_tilde = 0xfe53; + public final static int XK_dead_macron = 0xfe54; + public final static int XK_dead_breve = 0xfe55; + public final static int XK_dead_abovedot = 0xfe56; + public final static int XK_dead_diaeresis = 0xfe57; + public final static int XK_dead_abovering = 0xfe58; + public final static int XK_dead_doubleacute = 0xfe59; + public final static int XK_dead_caron = 0xfe5a; + public final static int XK_dead_cedilla = 0xfe5b; + public final static int XK_dead_ogonek = 0xfe5c; + public final static int XK_dead_iota = 0xfe5d; + public final static int XK_dead_voiced_sound = 0xfe5e; + public final static int XK_dead_semivoiced_sound = 0xfe5f; + public final static int XK_dead_belowdot = 0xfe60; + public final static int XK_dead_hook = 0xfe61; + public final static int XK_dead_horn = 0xfe62; + + public final static int XK_BackSpace = 0xff08; + public final static int XK_Tab = 0xff09; + public final static int XK_Linefeed = 0xff0a; + public final static int XK_Clear = 0xff0b; + public final static int XK_Return = 0xff0d; + public final static int XK_Pause = 0xff13; + public final static int XK_Scroll_Lock = 0xff14; + public final static int XK_Sys_Req = 0xff15; + public final static int XK_Escape = 0xff1b; + public final static int XK_Delete = 0xffff; + + public final static int XK_Home = 0xff50; + public final static int XK_Left = 0xff51; + public final static int XK_Up = 0xff52; + public final static int XK_Right = 0xff53; + public final static int XK_Down = 0xff54; + public final static int XK_Prior = 0xff55; + public final static int XK_Page_Up = 0xff55; + public final static int XK_Next = 0xff56; + public final static int XK_Page_Down = 0xff56; + public final static int XK_End = 0xff57; + public final static int XK_Begin = 0xff58; + + +/* Misc functions */ + + public final static int XK_Select = 0xff60; + public final static int XK_Print = 0xff61; + public final static int XK_Execute = 0xff62; + public final static int XK_Insert = 0xff63; + public final static int XK_Undo = 0xff65; + public final static int XK_Redo = 0xff66; + public final static int XK_Menu = 0xff67; + public final static int XK_Find = 0xff68; + public final static int XK_Cancel = 0xff69; + public final static int XK_Help = 0xff6a; + public final static int XK_Break = 0xff6b; + public final static int XK_Mode_switch = 0xff7e; + public final static int XK_script_switch = 0xff7e; + public final static int XK_Num_Lock = 0xff7f; + +/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ + + public final static int XK_KP_Space = 0xff80; + public final static int XK_KP_Tab = 0xff89; + public final static int XK_KP_Enter = 0xff8d; + public final static int XK_KP_F1 = 0xff91; + public final static int XK_KP_F2 = 0xff92; + public final static int XK_KP_F3 = 0xff93; + public final static int XK_KP_F4 = 0xff94; + public final static int XK_KP_Home = 0xff95; + public final static int XK_KP_Left = 0xff96; + public final static int XK_KP_Up = 0xff97; + public final static int XK_KP_Right = 0xff98; + public final static int XK_KP_Down = 0xff99; + public final static int XK_KP_Prior = 0xff9a; + public final static int XK_KP_Page_Up = 0xff9a; + public final static int XK_KP_Next = 0xff9b; + public final static int XK_KP_Page_Down = 0xff9b; + public final static int XK_KP_End = 0xff9c; + public final static int XK_KP_Begin = 0xff9d; + public final static int XK_KP_Insert = 0xff9e; + public final static int XK_KP_Delete = 0xff9f; + public final static int XK_KP_Equal = 0xffbd; + public final static int XK_KP_Multiply = 0xffaa; + public final static int XK_KP_Add = 0xffab; + public final static int XK_KP_Separator = 0xffac; + public final static int XK_KP_Subtract = 0xffad; + public final static int XK_KP_Decimal = 0xffae; + public final static int XK_KP_Divide = 0xffaf; + + public final static int XK_KP_0 = 0xffb0; + public final static int XK_KP_1 = 0xffb1; + public final static int XK_KP_2 = 0xffb2; + public final static int XK_KP_3 = 0xffb3; + public final static int XK_KP_4 = 0xffb4; + public final static int XK_KP_5 = 0xffb5; + public final static int XK_KP_6 = 0xffb6; + public final static int XK_KP_7 = 0xffb7; + public final static int XK_KP_8 = 0xffb8; + public final static int XK_KP_9 = 0xffb9; + + + +/* + * Auxilliary functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + + public final static int XK_F1 = 0xffbe; + public final static int XK_F2 = 0xffbf; + public final static int XK_F3 = 0xffc0; + public final static int XK_F4 = 0xffc1; + public final static int XK_F5 = 0xffc2; + public final static int XK_F6 = 0xffc3; + public final static int XK_F7 = 0xffc4; + public final static int XK_F8 = 0xffc5; + public final static int XK_F9 = 0xffc6; + public final static int XK_F10 = 0xffc7; + public final static int XK_F11 = 0xffc8; + public final static int XK_L1 = 0xffc8; + public final static int XK_F12 = 0xffc9; + public final static int XK_L2 = 0xffc9; + public final static int XK_F13 = 0xffca; + public final static int XK_L3 = 0xffca; + public final static int XK_F14 = 0xffcb; + public final static int XK_L4 = 0xffcb; + public final static int XK_F15 = 0xffcc; + public final static int XK_L5 = 0xffcc; + public final static int XK_F16 = 0xffcd; + public final static int XK_L6 = 0xffcd; + public final static int XK_F17 = 0xffce; + public final static int XK_L7 = 0xffce; + public final static int XK_F18 = 0xffcf; + public final static int XK_L8 = 0xffcf; + public final static int XK_F19 = 0xffd0; + public final static int XK_L9 = 0xffd0; + public final static int XK_F20 = 0xffd1; + public final static int XK_L10 = 0xffd1; + public final static int XK_F21 = 0xffd2; + public final static int XK_R1 = 0xffd2; + public final static int XK_F22 = 0xffd3; + public final static int XK_R2 = 0xffd3; + public final static int XK_F23 = 0xffd4; + public final static int XK_R3 = 0xffd4; + public final static int XK_F24 = 0xffd5; + public final static int XK_R4 = 0xffd5; + public final static int XK_F25 = 0xffd6; + public final static int XK_R5 = 0xffd6; + public final static int XK_F26 = 0xffd7; + public final static int XK_R6 = 0xffd7; + public final static int XK_F27 = 0xffd8; + public final static int XK_R7 = 0xffd8; + public final static int XK_F28 = 0xffd9; + public final static int XK_R8 = 0xffd9; + public final static int XK_F29 = 0xffda; + public final static int XK_R9 = 0xffda; + public final static int XK_F30 = 0xffdb; + public final static int XK_R10 = 0xffdb; + public final static int XK_F31 = 0xffdc; + public final static int XK_R11 = 0xffdc; + public final static int XK_F32 = 0xffdd; + public final static int XK_R12 = 0xffdd; + public final static int XK_F33 = 0xffde; + public final static int XK_R13 = 0xffde; + public final static int XK_F34 = 0xffdf; + public final static int XK_R14 = 0xffdf; + public final static int XK_F35 = 0xffe0; + public final static int XK_R15 = 0xffe0; + +/* Modifiers */ + + public final static int XK_Shift_L = 0xffe1; + public final static int XK_Shift_R = 0xffe2; + public final static int XK_Control_L = 0xffe3; + public final static int XK_Control_R = 0xffe4; + public final static int XK_Caps_Lock = 0xffe5; + public final static int XK_Shift_Lock = 0xffe6; + + public final static int XK_Meta_L = 0xffe7; + public final static int XK_Meta_R = 0xffe8; + public final static int XK_Alt_L = 0xffe9; + public final static int XK_Alt_R = 0xffea; + public final static int XK_Super_L = 0xffeb; + public final static int XK_Super_R = 0xffec; + public final static int XK_Hyper_L = 0xffed; + public final static int XK_Hyper_R = 0xffee; + public final static int XK_space = 0x0020; + public final static int XK_exclam = 0x0021; + public final static int XK_quotedbl = 0x0022; + public final static int XK_numbersign = 0x0023; + public final static int XK_dollar = 0x0024; + public final static int XK_percent = 0x0025; + public final static int XK_ampersand = 0x0026; + public final static int XK_apostrophe = 0x0027; + public final static int XK_quoteright = 0x0027; + public final static int XK_parenleft = 0x0028; + public final static int XK_parenright = 0x0029; + public final static int XK_asterisk = 0x002a; + public final static int XK_plus = 0x002b; + public final static int XK_comma = 0x002c; + public final static int XK_minus = 0x002d; + public final static int XK_period = 0x002e; + public final static int XK_slash = 0x002f; + + public final static int XK_0 = 0x0030; + public final static int XK_1 = 0x0031; + public final static int XK_2 = 0x0032; + public final static int XK_3 = 0x0033; + public final static int XK_4 = 0x0034; + public final static int XK_5 = 0x0035; + public final static int XK_6 = 0x0036; + public final static int XK_7 = 0x0037; + public final static int XK_8 = 0x0038; + public final static int XK_9 = 0x0039; + public final static int XK_colon = 0x003a; + public final static int XK_semicolon = 0x003b; + public final static int XK_less = 0x003c; + public final static int XK_equal = 0x003d; + public final static int XK_greater = 0x003e; + public final static int XK_question = 0x003f; + public final static int XK_at = 0x0040; + public final static int XK_A = 0x0041; + public final static int XK_B = 0x0042; + public final static int XK_C = 0x0043; + public final static int XK_D = 0x0044; + public final static int XK_E = 0x0045; + public final static int XK_F = 0x0046; + public final static int XK_G = 0x0047; + public final static int XK_H = 0x0048; + public final static int XK_I = 0x0049; + public final static int XK_J = 0x004a; + public final static int XK_K = 0x004b; + public final static int XK_L = 0x004c; + public final static int XK_M = 0x004d; + public final static int XK_N = 0x004e; + public final static int XK_O = 0x004f; + public final static int XK_P = 0x0050; + public final static int XK_Q = 0x0051; + public final static int XK_R = 0x0052; + public final static int XK_S = 0x0053; + public final static int XK_T = 0x0054; + public final static int XK_U = 0x0055; + public final static int XK_V = 0x0056; + public final static int XK_W = 0x0057; + public final static int XK_X = 0x0058; + public final static int XK_Y = 0x0059; + public final static int XK_Z = 0x005a; + public final static int XK_bracketleft = 0x005b; + public final static int XK_backslash = 0x005c; + public final static int XK_bracketright = 0x005d; + public final static int XK_asciicircum = 0x005e; + public final static int XK_underscore = 0x005f; + public final static int XK_grave = 0x0060; + public final static int XK_quoteleft = 0x0060; + public final static int XK_a = 0x0061; + public final static int XK_b = 0x0062; + public final static int XK_c = 0x0063; + public final static int XK_d = 0x0064; + public final static int XK_e = 0x0065; + public final static int XK_f = 0x0066; + public final static int XK_g = 0x0067; + public final static int XK_h = 0x0068; + public final static int XK_i = 0x0069; + public final static int XK_j = 0x006a; + public final static int XK_k = 0x006b; + public final static int XK_l = 0x006c; + public final static int XK_m = 0x006d; + public final static int XK_n = 0x006e; + public final static int XK_o = 0x006f; + public final static int XK_p = 0x0070; + public final static int XK_q = 0x0071; + public final static int XK_r = 0x0072; + public final static int XK_s = 0x0073; + public final static int XK_t = 0x0074; + public final static int XK_u = 0x0075; + public final static int XK_v = 0x0076; + public final static int XK_w = 0x0077; + public final static int XK_x = 0x0078; + public final static int XK_y = 0x0079; + public final static int XK_z = 0x007a; + public final static int XK_braceleft = 0x007b; + public final static int XK_bar = 0x007c; + public final static int XK_braceright = 0x007d; + public final static int XK_asciitilde = 0x007e; + + public final static int XK_nobreakspace = 0x00a0; + public final static int XK_exclamdown = 0x00a1; + public final static int XK_cent = 0x00a2; + public final static int XK_sterling = 0x00a3; + public final static int XK_currency = 0x00a4; + public final static int XK_yen = 0x00a5; + public final static int XK_brokenbar = 0x00a6; + public final static int XK_section = 0x00a7; + public final static int XK_diaeresis = 0x00a8; + public final static int XK_copyright = 0x00a9; + public final static int XK_ordfeminine = 0x00aa; + public final static int XK_guillemotleft = 0x00ab; + public final static int XK_notsign = 0x00ac; + public final static int XK_hyphen = 0x00ad; + public final static int XK_registered = 0x00ae; + public final static int XK_macron = 0x00af; + public final static int XK_degree = 0x00b0; + public final static int XK_plusminus = 0x00b1; + public final static int XK_twosuperior = 0x00b2; + public final static int XK_threesuperior = 0x00b3; + public final static int XK_acute = 0x00b4; + public final static int XK_mu = 0x00b5; + public final static int XK_paragraph = 0x00b6; + public final static int XK_periodcentered = 0x00b7; + public final static int XK_cedilla = 0x00b8; + public final static int XK_onesuperior = 0x00b9; + public final static int XK_masculine = 0x00ba; + public final static int XK_guillemotright = 0x00bb; + public final static int XK_onequarter = 0x00bc; + public final static int XK_onehalf = 0x00bd; + public final static int XK_threequarters = 0x00be; + public final static int XK_questiondown = 0x00bf; + public final static int XK_Agrave = 0x00c0; + public final static int XK_Aacute = 0x00c1; + public final static int XK_Acircumflex = 0x00c2; + public final static int XK_Atilde = 0x00c3; + public final static int XK_Adiaeresis = 0x00c4; + public final static int XK_Aring = 0x00c5; + public final static int XK_AE = 0x00c6; + public final static int XK_Ccedilla = 0x00c7; + public final static int XK_Egrave = 0x00c8; + public final static int XK_Eacute = 0x00c9; + public final static int XK_Ecircumflex = 0x00ca; + public final static int XK_Ediaeresis = 0x00cb; + public final static int XK_Igrave = 0x00cc; + public final static int XK_Iacute = 0x00cd; + public final static int XK_Icircumflex = 0x00ce; + public final static int XK_Idiaeresis = 0x00cf; + public final static int XK_ETH = 0x00d0; + public final static int XK_Eth = 0x00d0; + public final static int XK_Ntilde = 0x00d1; + public final static int XK_Ograve = 0x00d2; + public final static int XK_Oacute = 0x00d3; + public final static int XK_Ocircumflex = 0x00d4; + public final static int XK_Otilde = 0x00d5; + public final static int XK_Odiaeresis = 0x00d6; + public final static int XK_multiply = 0x00d7; + public final static int XK_Oslash = 0x00d8; + public final static int XK_Ooblique = 0x00d8; + public final static int XK_Ugrave = 0x00d9; + public final static int XK_Uacute = 0x00da; + public final static int XK_Ucircumflex = 0x00db; + public final static int XK_Udiaeresis = 0x00dc; + public final static int XK_Yacute = 0x00dd; + public final static int XK_THORN = 0x00de; + public final static int XK_Thorn = 0x00de; + public final static int XK_ssharp = 0x00df; + public final static int XK_agrave = 0x00e0; + public final static int XK_aacute = 0x00e1; + public final static int XK_acircumflex = 0x00e2; + public final static int XK_atilde = 0x00e3; + public final static int XK_adiaeresis = 0x00e4; + public final static int XK_aring = 0x00e5; + public final static int XK_ae = 0x00e6; + public final static int XK_ccedilla = 0x00e7; + public final static int XK_egrave = 0x00e8; + public final static int XK_eacute = 0x00e9; + public final static int XK_ecircumflex = 0x00ea; + public final static int XK_ediaeresis = 0x00eb; + public final static int XK_igrave = 0x00ec; + public final static int XK_iacute = 0x00ed; + public final static int XK_icircumflex = 0x00ee; + public final static int XK_idiaeresis = 0x00ef; + public final static int XK_eth = 0x00f0; + public final static int XK_ntilde = 0x00f1; + public final static int XK_ograve = 0x00f2; + public final static int XK_oacute = 0x00f3; + public final static int XK_ocircumflex = 0x00f4; + public final static int XK_otilde = 0x00f5; + public final static int XK_odiaeresis = 0x00f6; + public final static int XK_division = 0x00f7; + public final static int XK_oslash = 0x00f8; + public final static int XK_ooblique = 0x00f8; + public final static int XK_ugrave = 0x00f9; + public final static int XK_uacute = 0x00fa; + public final static int XK_ucircumflex = 0x00fb; + public final static int XK_udiaeresis = 0x00fc; + public final static int XK_yacute = 0x00fd; + public final static int XK_thorn = 0x00fe; + public final static int XK_ydiaeresis = 0x00ff; + + public static int mapKeySymToLWJGLKeyCode(long keysym) { + switch ((int)keysym) { + case XK_BackSpace: + return Keyboard.KEY_BACK; + case XK_ISO_Left_Tab: + case XK_Tab: + return Keyboard.KEY_TAB; + case XK_Return: + return Keyboard.KEY_RETURN; + case XK_Pause: + return Keyboard.KEY_PAUSE; + case XK_Scroll_Lock: + return Keyboard.KEY_SCROLL; + case XK_Sys_Req: + return Keyboard.KEY_SYSRQ; + case XK_Escape: + return Keyboard.KEY_ESCAPE; + case XK_Delete: + return Keyboard.KEY_DELETE; + + /* Japanese keyboard support */ + + case XK_Kanji: + return Keyboard.KEY_KANJI; + + /* Cursor control & motion */ + + case XK_Home: + return Keyboard.KEY_HOME; + case XK_Left: + return Keyboard.KEY_LEFT; + case XK_Up: + return Keyboard.KEY_UP; + case XK_Right: + return Keyboard.KEY_RIGHT; + case XK_Down: + return Keyboard.KEY_DOWN; + case XK_Page_Up: + return Keyboard.KEY_PRIOR; + case XK_Page_Down: + return Keyboard.KEY_NEXT; + case XK_End: + return Keyboard.KEY_END; + + + /* Misc Functions */ + + case XK_Break: + return Keyboard.KEY_PAUSE; + case XK_Insert: + return Keyboard.KEY_INSERT; + case XK_Num_Lock: + return Keyboard.KEY_NUMLOCK; + + /* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + + case XK_KP_Space: + return Keyboard.KEY_SPACE; + case XK_KP_Tab: + return Keyboard.KEY_TAB; + case XK_KP_Enter: + return Keyboard.KEY_NUMPADENTER; + case XK_KP_F1: + return Keyboard.KEY_F1; + case XK_KP_F2: + return Keyboard.KEY_F2; + case XK_KP_F3: + return Keyboard.KEY_F3; + case XK_KP_F4: + return Keyboard.KEY_F4; + case XK_KP_Home: + return Keyboard.KEY_HOME; + case XK_KP_Left: + return Keyboard.KEY_LEFT; + case XK_KP_Up: + return Keyboard.KEY_UP; + case XK_KP_Right: + return Keyboard.KEY_RIGHT; + case XK_KP_Down: + return Keyboard.KEY_DOWN; + case XK_KP_Page_Up: + return Keyboard.KEY_PRIOR; + case XK_KP_Page_Down: + return Keyboard.KEY_NEXT; + case XK_KP_End: + return Keyboard.KEY_END; + case XK_KP_Insert: + return Keyboard.KEY_INSERT; + case XK_KP_Delete: + return Keyboard.KEY_DELETE; + case XK_KP_Equal: + return Keyboard.KEY_NUMPADEQUALS; + case XK_KP_Multiply: + return Keyboard.KEY_MULTIPLY; + case XK_KP_Add: + return Keyboard.KEY_ADD; + case XK_KP_Subtract: + return Keyboard.KEY_SUBTRACT; + case XK_KP_Decimal: + return Keyboard.KEY_DECIMAL; + case XK_KP_Divide: + return Keyboard.KEY_DIVIDE; + + case XK_KP_0: + return Keyboard.KEY_NUMPAD0; + case XK_KP_1: + return Keyboard.KEY_NUMPAD1; + case XK_KP_2: + return Keyboard.KEY_NUMPAD2; + case XK_KP_3: + return Keyboard.KEY_NUMPAD3; + case XK_KP_4: + return Keyboard.KEY_NUMPAD4; + case XK_KP_5: + return Keyboard.KEY_NUMPAD5; + case XK_KP_6: + return Keyboard.KEY_NUMPAD6; + case XK_KP_7: + return Keyboard.KEY_NUMPAD7; + case XK_KP_8: + return Keyboard.KEY_NUMPAD8; + case XK_KP_9: + return Keyboard.KEY_NUMPAD9; + + /* + * Auxilliary Functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + + case XK_F1: + return Keyboard.KEY_F1; + case XK_F2: + return Keyboard.KEY_F2; + case XK_F3: + return Keyboard.KEY_F3; + case XK_F4: + return Keyboard.KEY_F4; + case XK_F5: + return Keyboard.KEY_F5; + case XK_F6: + return Keyboard.KEY_F6; + case XK_F7: + return Keyboard.KEY_F7; + case XK_F8: + return Keyboard.KEY_F8; + case XK_F9: + return Keyboard.KEY_F9; + case XK_F10: + return Keyboard.KEY_F10; + case XK_F11: + return Keyboard.KEY_F11; + case XK_F12: + return Keyboard.KEY_F12; + case XK_F13: + return Keyboard.KEY_F13; + case XK_F14: + return Keyboard.KEY_F14; + case XK_F15: + return Keyboard.KEY_F15; + + /* Modifiers */ + + case XK_Shift_L: + return Keyboard.KEY_LSHIFT; + case XK_Shift_R: + return Keyboard.KEY_RSHIFT; + case XK_Control_L: + return Keyboard.KEY_LCONTROL; + case XK_Control_R: + return Keyboard.KEY_RCONTROL; + case XK_Caps_Lock: + return Keyboard.KEY_CAPITAL; + + case XK_Meta_L: + return Keyboard.KEY_LMENU; + case XK_Meta_R: + return Keyboard.KEY_RMENU; + case XK_Alt_L: + return Keyboard.KEY_LMENU; + case XK_Alt_R: + return Keyboard.KEY_RMENU; + + case XK_dead_grave: + return Keyboard.KEY_GRAVE; + case XK_dead_circumflex: + return Keyboard.KEY_CIRCUMFLEX; + + /* + * Latin 1 + * Byte 3 = 0 + */ + case XK_space: + return Keyboard.KEY_SPACE; + case XK_apostrophe: + return Keyboard.KEY_APOSTROPHE; + case XK_comma: + return Keyboard.KEY_COMMA; + case XK_minus: + return Keyboard.KEY_MINUS; + case XK_period: + return Keyboard.KEY_PERIOD; + case XK_slash: + return Keyboard.KEY_SLASH; + case XK_0: + return Keyboard.KEY_0; + case XK_1: + return Keyboard.KEY_1; + case XK_2: + return Keyboard.KEY_2; + case XK_3: + return Keyboard.KEY_3; + case XK_4: + return Keyboard.KEY_4; + case XK_5: + return Keyboard.KEY_5; + case XK_6: + return Keyboard.KEY_6; + case XK_7: + return Keyboard.KEY_7; + case XK_8: + return Keyboard.KEY_8; + case XK_9: + return Keyboard.KEY_9; + case XK_colon: + return Keyboard.KEY_COLON; + case XK_semicolon: + return Keyboard.KEY_SEMICOLON; + case XK_equal: + return Keyboard.KEY_EQUALS; + case XK_at: + return Keyboard.KEY_AT; + case XK_bracketleft: + return Keyboard.KEY_LBRACKET; + case XK_bracketright: + return Keyboard.KEY_RBRACKET; + case XK_asciicircum: + return Keyboard.KEY_CIRCUMFLEX; + case XK_underscore: + return Keyboard.KEY_UNDERLINE; + case XK_grave: + return Keyboard.KEY_GRAVE; + case XK_a: + case XK_A: + return Keyboard.KEY_A; + case XK_b: + case XK_B: + return Keyboard.KEY_B; + case XK_c: + case XK_C: + return Keyboard.KEY_C; + case XK_d: + case XK_D: + return Keyboard.KEY_D; + case XK_e: + case XK_E: + return Keyboard.KEY_E; + case XK_f: + case XK_F: + return Keyboard.KEY_F; + case XK_g: + case XK_G: + return Keyboard.KEY_G; + case XK_h: + case XK_H: + return Keyboard.KEY_H; + case XK_i: + case XK_I: + return Keyboard.KEY_I; + case XK_j: + case XK_J: + return Keyboard.KEY_J; + case XK_k: + case XK_K: + return Keyboard.KEY_K; + case XK_l: + case XK_L: + return Keyboard.KEY_L; + case XK_m: + case XK_M: + return Keyboard.KEY_M; + case XK_n: + case XK_N: + return Keyboard.KEY_N; + case XK_o: + case XK_O: + return Keyboard.KEY_O; + case XK_p: + case XK_P: + return Keyboard.KEY_P; + case XK_q: + case XK_Q: + return Keyboard.KEY_Q; + case XK_r: + case XK_R: + return Keyboard.KEY_R; + case XK_s: + case XK_S: + return Keyboard.KEY_S; + case XK_t: + case XK_T: + return Keyboard.KEY_T; + case XK_u: + case XK_U: + return Keyboard.KEY_U; + case XK_v: + case XK_V: + return Keyboard.KEY_V; + case XK_w: + case XK_W: + return Keyboard.KEY_W; + case XK_x: + case XK_X: + return Keyboard.KEY_X; + case XK_y: + case XK_Y: + return Keyboard.KEY_Y; + case XK_z: + case XK_Z: + return Keyboard.KEY_Z; + default: + return Keyboard.KEY_NONE; + } + } + +} diff --git a/src/java/org/lwjgl/opengl/LinuxMouse.java b/src/java/org/lwjgl/opengl/LinuxMouse.java new file mode 100644 index 00000000..00cba51a --- /dev/null +++ b/src/java/org/lwjgl/opengl/LinuxMouse.java @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.CharBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.input.Mouse; + +import java.nio.charset.CharsetDecoder; +import java.nio.charset.Charset; + +final class LinuxMouse { + private static final int EVENT_SIZE = 5; + private static final int NUM_BUTTONS = 3; + private static final int POINTER_WARP_BORDER = 10; + // scale the mouse wheel according to DirectInput + private static final int WHEEL_SCALE = 120; + + /* X11 constants */ + private final static int Button1 = 1; + private final static int Button2 = 2; + private final static int Button3 = 3; + private final static int Button4 = 4; + private final static int Button5 = 5; + + private final static int ButtonPress = 4; + private final static int ButtonRelease = 5; + + private final long display; + private final long window; + private final IntBuffer query_pointer_buffer = BufferUtils.createIntBuffer(4); + private final int[] event_buffer = new int[EVENT_SIZE]; + + private int last_x; + private int last_y; + private int accum_dx; + private int accum_dy; + private int accum_dz; + private byte[] buttons = new byte[NUM_BUTTONS]; + private EventQueue event_queue; + + public LinuxMouse(long display, long window) { + this.display = display; + this.window = window; + reset(); + } + + private void reset() { + event_queue = new EventQueue(EVENT_SIZE); + accum_dx = accum_dy = 0; + } + + public int read(IntBuffer buffer) { + return event_queue.copyEvents(buffer); + } + + public void poll(boolean grab, IntBuffer coord_buffer, ByteBuffer buttons_buffer) { + if (grab) { + coord_buffer.put(0, accum_dx); + coord_buffer.put(1, accum_dy); + } else { + coord_buffer.put(0, last_x); + coord_buffer.put(1, last_y); + } + coord_buffer.put(2, accum_dz); + accum_dx = accum_dy = accum_dz = 0; + for (int i = 0; i < buttons.length; i++) + buttons_buffer.put(i, buttons[i]); + } + + private boolean putMouseEventWithCoords(int button, int state, int coord1, int coord2, int dz) { + event_buffer[0] = button; + event_buffer[1] = state; + event_buffer[2] = coord1; + event_buffer[3] = coord2; + event_buffer[4] = dz; + return event_queue.putEvent(event_buffer); + } + + private void setCursorPos(boolean grab, int x, int y) { + y = transformY(y); + int dx = x - last_x; + int dy = y - last_y; + accum_dx += dx; + accum_dy += dy; + last_x = x; + last_y = y; + if (grab) { + putMouseEventWithCoords(-1, 0, dx, dy, 0); + } else { + putMouseEventWithCoords(-1, 0, x, y, 0); + } + } + + private void doWarpPointer(int center_x, int center_y) { + nSendWarpEvent(display, window, center_x, center_y); + nWarpCursor(display, window, center_x, center_y); + } + private static native void nSendWarpEvent(long display, long window, int center_x, int center_y); + + private void doHandlePointerMotion(boolean grab, boolean pointer_grabbed, boolean should_grab, long root_window, int root_x, int root_y, int win_x, int win_y) { + setCursorPos(grab, win_x, win_y); + if (!pointer_grabbed || !should_grab) + return; + int root_window_height = nGetWindowHeight(display, root_window); + int root_window_width = nGetWindowWidth(display, root_window); + int window_height = nGetWindowHeight(display, window); + int window_width = nGetWindowWidth(display, window); + + // find the window position in root coordinates + int win_left = root_x - win_x; + int win_top = root_y - win_y; + int win_right = win_left + window_width; + int win_bottom = win_top + window_height; + // cap the window position to the screen dimensions + int border_left = Math.max(0, win_left); + int border_top = Math.max(0, win_top); + int border_right = Math.min(root_window_width, win_right); + int border_bottom = Math.min(root_window_height, win_bottom); + // determine whether the cursor is outside the bounds + boolean outside_limits = root_x < border_left + POINTER_WARP_BORDER || root_y < border_top + POINTER_WARP_BORDER || + root_x > border_right - POINTER_WARP_BORDER || root_y > border_bottom - POINTER_WARP_BORDER; + if (outside_limits) { + // Find the center of the limits in window coordinates + int center_x = (border_right - border_left)/2; + int center_y = (border_bottom - border_top)/2; + doWarpPointer(center_x, center_y); + } + } + + public void changeGrabbed(boolean grab, boolean pointer_grabbed, boolean should_grab) { + reset(); + long root_window = nQueryPointer(display, window, query_pointer_buffer); + doHandlePointerMotion(grab, pointer_grabbed, should_grab, root_window, query_pointer_buffer.get(0), query_pointer_buffer.get(1), query_pointer_buffer.get(2), query_pointer_buffer.get(3)); + } + + public int getButtonCount() { + return buttons.length; + } + + private int transformY(int y) { + return nGetWindowHeight(display, window) - 1 - y; + } + private static native int nGetWindowHeight(long display, long window); + private static native int nGetWindowWidth(long display, long window); + + private static native long nQueryPointer(long display, long window, IntBuffer result); + + public void setCursorPosition(int x, int y) { + nWarpCursor(display, window, x, transformY(y)); + } + private static native void nWarpCursor(long display, long window, int x, int y); + + public void handlePointerMotion(boolean grab, boolean pointer_grabbed, boolean should_grab, long root_window, int x_root, int y_root, int x, int y) { + doHandlePointerMotion(grab, pointer_grabbed, should_grab, root_window, x_root, y_root, x, y); + } + + private void handleButton(boolean grab, int button, byte state) { + int button_num; + switch (button) { + case Button1: + button_num = 0; + break; + case Button2: + button_num = 2; + break; + case Button3: + button_num = 1; + break; + default: + return; + } + buttons[button_num] = state; + putMouseEvent(grab, button_num, state, 0); + } + + private void putMouseEvent(boolean grab, int button, int state, int dz) { + if (grab) + putMouseEventWithCoords(button, state, 0, 0, dz); + else + putMouseEventWithCoords(button, state, last_x, last_y, dz); + } + + private void handleButtonPress(boolean grab, int button) { + int delta = 0; + switch (button) { + case Button4: + delta = WHEEL_SCALE; + putMouseEvent(grab, -1, 0, delta); + accum_dz += delta; + break; + case Button5: + delta = -WHEEL_SCALE; + putMouseEvent(grab, -1, 0, delta); + accum_dz += delta; + break; + default: + handleButton(grab, button, (byte)1); + break; + } + } + + private void handleButtonRelease(boolean grab, int button) { + handleButton(grab, button, (byte)0); + } + + public void handleButtonEvent(boolean grab, int type, int button) { + switch (type) { + case ButtonRelease: + handleButton(grab, button, (byte)0); + break; + case ButtonPress: + handleButtonPress(grab, button); + break; + default: + break; + } + } + + private void resetCursor(int x, int y) { + last_x = x; + last_y = transformY(y); + } + + public void handleWarpEvent(int x, int y) { + resetCursor(x, y); + } +} diff --git a/src/native/common/common_tools.c b/src/native/common/common_tools.c index 6a3b9e35..fd9c3abb 100644 --- a/src/native/common/common_tools.c +++ b/src/native/common/common_tools.c @@ -119,66 +119,6 @@ void printfDebug(const char *format, ...) { va_end(ap); } -int getElementCapacity(event_queue_t *queue) { - return queue->limit - queue->position; -} - -void initEventQueue(event_queue_t *queue, int event_size) { - queue->position = 0; - queue->limit = EVENT_BUFFER_SIZE; - queue->event_size = event_size; -} - -bool putEvent(event_queue_t *queue, jint *event) { - int i; - if (getElementCapacity(queue) < queue->event_size) { - return false; - } - for (i = 0; i < queue->event_size; i++) { - queue->input_event_buffer[queue->position] = event[i]; - queue->position++; - } - return true; -} - -static void flip(event_queue_t *queue) { - queue->limit = queue->position; - queue->position = 0; -} - -static void compact(event_queue_t *queue) { - int new_position = 0; - while (getElementCapacity(queue) > 0) { - queue->input_event_buffer[new_position] = queue->input_event_buffer[queue->position]; - queue->position++; - new_position++; - } - queue->position = new_position; - queue->limit = EVENT_BUFFER_SIZE; -} - -static void copyEvent(event_queue_t *queue, jint *output_event_buffer, int output_index) { - int i; - for (i = 0; i < queue->event_size; i++) { - output_event_buffer[output_index] = queue->input_event_buffer[queue->position]; - queue->position++; - output_index++; - } -} - -int copyEvents(event_queue_t *queue, jint *output_event_buffer, int buffer_size) { - int num_events = 0; - int index = 0; - flip(queue); - while (index + queue->event_size <= buffer_size && getElementCapacity(queue) >= queue->event_size) { - copyEvent(queue, output_event_buffer, index); - num_events++; - index += queue->event_size; - } - compact(queue); - return num_events; -} - static void throwFormattedGeneralException(JNIEnv * env, const char *exception_name, const char *format, va_list ap) { jclass cls; jstring str; @@ -361,3 +301,17 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { } + +bool positionBuffer(JNIEnv *env, jobject buffer, jint position) { + jclass buffer_class; + jmethodID position_method; + + buffer_class = (*env)->GetObjectClass(env, buffer); + if (buffer_class == NULL) + return false; + position_method = (*env)->GetMethodID(env, buffer_class, "position", "(I)Ljava/nio/Buffer;"); + if (position_method == NULL) + return false; + (*env)->CallObjectMethod(env, buffer, position_method, position); + return true; +} diff --git a/src/native/common/common_tools.h b/src/native/common/common_tools.h index 23e8dafc..e4931e0c 100644 --- a/src/native/common/common_tools.h +++ b/src/native/common/common_tools.h @@ -44,16 +44,8 @@ #include #include -#define EVENT_BUFFER_SIZE 256 #define ATTRIB_LIST_SIZE (256) -typedef struct { - int event_size; - int position; - int limit; - jint input_event_buffer[EVENT_BUFFER_SIZE]; -} event_queue_t; - typedef struct { int current_index; int attribs[ATTRIB_LIST_SIZE]; @@ -135,9 +127,6 @@ extern void putAttrib(attrib_list_t *list, int attrib); extern bool isDebugEnabled(void); extern jstring getVersionString(JNIEnv *env); -extern void initEventQueue(event_queue_t *event_queue, int event_size); -extern int copyEvents(event_queue_t *event_queue, jint *output_event_buffer, int buffer_size); -extern bool putEvent(event_queue_t *queue, jint *event); extern void throwGeneralException(JNIEnv * env, const char *exception_name, const char * err); extern void throwException(JNIEnv *env, const char *msg); extern void throwFormattedException(JNIEnv * env, const char *format, ...); @@ -149,6 +138,7 @@ extern bool getBooleanProperty(JNIEnv *env, const char* propertyName); extern char * GetStringNativeChars(JNIEnv *env, jstring jstr); extern jstring NewStringNative(JNIEnv *env, const char *str); extern jobject newJavaManagedByteBuffer(JNIEnv *env, const int size); +extern bool positionBuffer(JNIEnv *env, jobject buffer, jint position); extern void ext_InitializeClass(JNIEnv *env, jclass clazz, ExtGetProcAddressPROC gpa, int num_functions, JavaMethodAndExtFunction *functions); extern bool ext_InitializeFunctions(ExtGetProcAddressPROC gpa, int num_functions, ExtFunction *functions); diff --git a/src/native/linux/Window.h b/src/native/linux/Window.h index db4126a6..3d83c387 100644 --- a/src/native/linux/Window.h +++ b/src/native/linux/Window.h @@ -51,19 +51,6 @@ extern bool checkXError(JNIEnv *, Display *); extern Atom getWarpAtom(void); - /* - * Various functions to release/acquire keyboard and mouse - */ - extern void handleWarpEvent(XClientMessageEvent *); - extern void handlePointerMotion(XMotionEvent *); - extern void handleButtonPress(XButtonEvent *); - extern void handleButtonRelease(XButtonEvent *); - extern void handleKeyEvent(XKeyEvent *); - extern void updatePointerGrab(jint); - extern void updateKeyboardGrab(jint); - extern void setGrab(jint, bool); - extern bool isGrabbed(void); - extern bool shouldGrab(void); /* * get the current display @@ -80,14 +67,4 @@ */ extern Window getCurrentWindow(void); - /* - * Return true if we are in fullscreen mode - */ - extern bool isFullscreen(jint window_mode); - - /* - * Return true if we are in exclusive fullscreen mode - */ - extern bool isLegacyFullscreen(jint window_mode); - #endif /* _LWJGL_WINDOW_H_INCLUDED_ */ diff --git a/src/native/linux/display.c b/src/native/linux/display.c index 23c850b0..9a38e217 100644 --- a/src/native/linux/display.c +++ b/src/native/linux/display.c @@ -408,15 +408,16 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetAvailableD return getAvailableDisplayModes(env, getDisplay(), getCurrentScreen(), extension); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSwitchDisplayMode(JNIEnv *env, jclass clazz, jint extension, jobject mode) { - switchDisplayMode(env, getCurrentScreen(), extension, mode); +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSwitchDisplayMode(JNIEnv *env, jclass clazz, jint screen, jint extension, jobject mode) { + switchDisplayMode(env, screen, extension, mode); } -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetGammaRampLength(JNIEnv *env, jclass clazz) { - return (jint)getGammaRampLengthOfDisplay(env, getDisplay(), getCurrentScreen()); +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetGammaRampLength(JNIEnv *env, jclass clazz, jlong display_ptr, jint screen) { + Display *disp = (Display *)(intptr_t)display_ptr; + return (jint)getGammaRampLengthOfDisplay(env, disp, screen); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetGammaRamp(JNIEnv *env, jclass clazz, jobject gamma_buffer) { - setGammaRamp(env, getCurrentScreen(), gamma_buffer); +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetGammaRamp(JNIEnv *env, jclass clazz, jint screen, jobject gamma_buffer) { + setGammaRamp(env, screen, gamma_buffer); } diff --git a/src/native/linux/org_lwjgl_input_Keyboard.c b/src/native/linux/org_lwjgl_input_Keyboard.c deleted file mode 100644 index 3d05f185..00000000 --- a/src/native/linux/org_lwjgl_input_Keyboard.c +++ /dev/null @@ -1,692 +0,0 @@ -/* - * Copyright (c) 2002-2004 LWJGL Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * $Id$ - * - * Linux keyboard handling. - * - * @author elias_naur - * @version $Revision$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Window.h" -#include "common_tools.h" -#include "org_lwjgl_input_Keyboard.h" -#include "org_lwjgl_opengl_LinuxDisplay.h" - -#define KEYBOARD_BUFFER_SIZE 50 - -static jbyte key_buf[org_lwjgl_input_Keyboard_KEYBOARD_SIZE]; -static int numlock_mask; -static int modeswitch_mask; -static int caps_lock_mask; -static int shift_lock_mask; - -static event_queue_t event_queue; - -static bool keyboard_grabbed; -static bool created = false; - -// X input manager values -static iconv_t iconv_descriptor = (iconv_t)-1; -static XIM xim = NULL; -static XIC xic = NULL; - -static void grabKeyboard(void) { - if (!keyboard_grabbed) { - int result = XGrabKeyboard(getDisplay(), getCurrentWindow(), False, GrabModeAsync, GrabModeAsync, CurrentTime); - if (result == GrabSuccess) - keyboard_grabbed = true; - } -} - -static void ungrabKeyboard(void) { - if (keyboard_grabbed) { - keyboard_grabbed = false; - XUngrabKeyboard(getDisplay(), CurrentTime); - } -} - -void updateKeyboardGrab(jint window_mode) { - if (!created) - return; - if (isLegacyFullscreen(window_mode)) { - grabKeyboard(); - } else { - ungrabKeyboard(); - } -} - -static void cleanup() { - if (iconv_descriptor != (iconv_t)-1) { - iconv_close(iconv_descriptor); - iconv_descriptor = (iconv_t)-1; - } - if (xic != NULL) { - XDestroyIC(xic); - xic = NULL; - } - if (xim != NULL) { - XCloseIM(xim); - xim = NULL; - } -} - -static void setupIMEventMask() { - long im_event_mask; - XWindowAttributes win_attributes; - - XGetWindowAttributes(getDisplay(), getCurrentWindow(), &win_attributes); - XGetICValues(xic, XNFilterEvents, &im_event_mask, NULL); - XSelectInput(getDisplay(), getCurrentWindow(), win_attributes.your_event_mask | im_event_mask); - XSetICFocus(xic); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateKeyboard - (JNIEnv * env, jclass clazz, jint window_mode) -{ - memset(key_buf, 0, org_lwjgl_input_Keyboard_KEYBOARD_SIZE*sizeof(jbyte)); - created = true; - keyboard_grabbed = false; - initEventQueue(&event_queue, 3); - updateKeyboardGrab(window_mode); - XModifierKeymap *modifier_map = XGetModifierMapping(getDisplay()); - numlock_mask = 0; - modeswitch_mask = 0; - caps_lock_mask = 0; - shift_lock_mask = 0; - if (modifier_map != NULL) { - // Find modifier masks - int i, j; - for (i = 0; i < 8; i++) { - for (j = 0; j < modifier_map->max_keypermod; j++) { - KeyCode key_code = modifier_map->modifiermap[i*modifier_map->max_keypermod + j]; - KeySym key_sym = XKeycodeToKeysym(getDisplay(), key_code, 0); - int mask = 1 << i; - switch (key_sym) { - case XK_Num_Lock: - numlock_mask |= mask; - break; - case XK_Mode_switch: - modeswitch_mask |= mask; - break; - case XK_Caps_Lock: - if (i == LockMapIndex) { - caps_lock_mask = mask; - shift_lock_mask = 0; - } - break; - case XK_Shift_Lock: - if (i == LockMapIndex && caps_lock_mask == 0) - shift_lock_mask = mask; - break; - default: - break; - } - } - } - XFreeModifiermap(modifier_map); - } - - // Allocate unicode structures - iconv_descriptor = iconv_open("UCS-2", "UTF-8"); - if (iconv_descriptor != (iconv_t)-1) { - xim = XOpenIM(getDisplay(), NULL, NULL, NULL); - if (xim != NULL) { - xic = XCreateIC(xim, XNClientWindow, getCurrentWindow(), XNFocusWindow, getCurrentWindow(), XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL); - if (xic != NULL) { - setupIMEventMask(); - } else { - cleanup(); - } - } else - cleanup(); - } -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nDestroyKeyboard - (JNIEnv * env, jclass clazz) -{ - cleanup(); - ungrabKeyboard(); - created = false; -} - -static unsigned char mapKeySymToLWJGLKeyCode(KeySym keysym) { - switch (keysym) { - case XK_BackSpace: - return org_lwjgl_input_Keyboard_KEY_BACK; - case XK_ISO_Left_Tab: - case XK_Tab: - return org_lwjgl_input_Keyboard_KEY_TAB; - case XK_Return: - return org_lwjgl_input_Keyboard_KEY_RETURN; - case XK_Pause: - return org_lwjgl_input_Keyboard_KEY_PAUSE; - case XK_Scroll_Lock: - return org_lwjgl_input_Keyboard_KEY_SCROLL; - case XK_Sys_Req: - return org_lwjgl_input_Keyboard_KEY_SYSRQ; - case XK_Escape: - return org_lwjgl_input_Keyboard_KEY_ESCAPE; - case XK_Delete: - return org_lwjgl_input_Keyboard_KEY_DELETE; - -/* Japanese keyboard support */ - - case XK_Kanji: - return org_lwjgl_input_Keyboard_KEY_KANJI; - -/* Cursor control & motion */ - - case XK_Home: - return org_lwjgl_input_Keyboard_KEY_HOME; - case XK_Left: - return org_lwjgl_input_Keyboard_KEY_LEFT; - case XK_Up: - return org_lwjgl_input_Keyboard_KEY_UP; - case XK_Right: - return org_lwjgl_input_Keyboard_KEY_RIGHT; - case XK_Down: - return org_lwjgl_input_Keyboard_KEY_DOWN; - case XK_Page_Up: - return org_lwjgl_input_Keyboard_KEY_PRIOR; - case XK_Page_Down: - return org_lwjgl_input_Keyboard_KEY_NEXT; - case XK_End: - return org_lwjgl_input_Keyboard_KEY_END; - - -/* Misc Functions */ - - case XK_Break: - return org_lwjgl_input_Keyboard_KEY_PAUSE; - case XK_Insert: - return org_lwjgl_input_Keyboard_KEY_INSERT; - case XK_Num_Lock: - return org_lwjgl_input_Keyboard_KEY_NUMLOCK; - -/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ - - case XK_KP_Space: - return org_lwjgl_input_Keyboard_KEY_SPACE; - case XK_KP_Tab: - return org_lwjgl_input_Keyboard_KEY_TAB; - case XK_KP_Enter: - return org_lwjgl_input_Keyboard_KEY_NUMPADENTER; - case XK_KP_F1: - return org_lwjgl_input_Keyboard_KEY_F1; - case XK_KP_F2: - return org_lwjgl_input_Keyboard_KEY_F2; - case XK_KP_F3: - return org_lwjgl_input_Keyboard_KEY_F3; - case XK_KP_F4: - return org_lwjgl_input_Keyboard_KEY_F4; - case XK_KP_Home: - return org_lwjgl_input_Keyboard_KEY_HOME; - case XK_KP_Left: - return org_lwjgl_input_Keyboard_KEY_LEFT; - case XK_KP_Up: - return org_lwjgl_input_Keyboard_KEY_UP; - case XK_KP_Right: - return org_lwjgl_input_Keyboard_KEY_RIGHT; - case XK_KP_Down: - return org_lwjgl_input_Keyboard_KEY_DOWN; - case XK_KP_Page_Up: - return org_lwjgl_input_Keyboard_KEY_PRIOR; - case XK_KP_Page_Down: - return org_lwjgl_input_Keyboard_KEY_NEXT; - case XK_KP_End: - return org_lwjgl_input_Keyboard_KEY_END; - case XK_KP_Insert: - return org_lwjgl_input_Keyboard_KEY_INSERT; - case XK_KP_Delete: - return org_lwjgl_input_Keyboard_KEY_DELETE; - case XK_KP_Equal: - return org_lwjgl_input_Keyboard_KEY_NUMPADEQUALS; - case XK_KP_Multiply: - return org_lwjgl_input_Keyboard_KEY_MULTIPLY; - case XK_KP_Add: - return org_lwjgl_input_Keyboard_KEY_ADD; - case XK_KP_Subtract: - return org_lwjgl_input_Keyboard_KEY_SUBTRACT; - case XK_KP_Decimal: - return org_lwjgl_input_Keyboard_KEY_DECIMAL; - case XK_KP_Divide: - return org_lwjgl_input_Keyboard_KEY_DIVIDE; - - case XK_KP_0: - return org_lwjgl_input_Keyboard_KEY_NUMPAD0; - case XK_KP_1: - return org_lwjgl_input_Keyboard_KEY_NUMPAD1; - case XK_KP_2: - return org_lwjgl_input_Keyboard_KEY_NUMPAD2; - case XK_KP_3: - return org_lwjgl_input_Keyboard_KEY_NUMPAD3; - case XK_KP_4: - return org_lwjgl_input_Keyboard_KEY_NUMPAD4; - case XK_KP_5: - return org_lwjgl_input_Keyboard_KEY_NUMPAD5; - case XK_KP_6: - return org_lwjgl_input_Keyboard_KEY_NUMPAD6; - case XK_KP_7: - return org_lwjgl_input_Keyboard_KEY_NUMPAD7; - case XK_KP_8: - return org_lwjgl_input_Keyboard_KEY_NUMPAD8; - case XK_KP_9: - return org_lwjgl_input_Keyboard_KEY_NUMPAD9; - -/* - * Auxilliary Functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufactures have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - - case XK_F1: - return org_lwjgl_input_Keyboard_KEY_F1; - case XK_F2: - return org_lwjgl_input_Keyboard_KEY_F2; - case XK_F3: - return org_lwjgl_input_Keyboard_KEY_F3; - case XK_F4: - return org_lwjgl_input_Keyboard_KEY_F4; - case XK_F5: - return org_lwjgl_input_Keyboard_KEY_F5; - case XK_F6: - return org_lwjgl_input_Keyboard_KEY_F6; - case XK_F7: - return org_lwjgl_input_Keyboard_KEY_F7; - case XK_F8: - return org_lwjgl_input_Keyboard_KEY_F8; - case XK_F9: - return org_lwjgl_input_Keyboard_KEY_F9; - case XK_F10: - return org_lwjgl_input_Keyboard_KEY_F10; - case XK_F11: - return org_lwjgl_input_Keyboard_KEY_F11; - case XK_F12: - return org_lwjgl_input_Keyboard_KEY_F12; - case XK_F13: - return org_lwjgl_input_Keyboard_KEY_F13; - case XK_F14: - return org_lwjgl_input_Keyboard_KEY_F14; - case XK_F15: - return org_lwjgl_input_Keyboard_KEY_F15; - -/* Modifiers */ - - case XK_Shift_L: - return org_lwjgl_input_Keyboard_KEY_LSHIFT; - case XK_Shift_R: - return org_lwjgl_input_Keyboard_KEY_RSHIFT; - case XK_Control_L: - return org_lwjgl_input_Keyboard_KEY_LCONTROL; - case XK_Control_R: - return org_lwjgl_input_Keyboard_KEY_RCONTROL; - case XK_Caps_Lock: - return org_lwjgl_input_Keyboard_KEY_CAPITAL; - - case XK_Meta_L: - return org_lwjgl_input_Keyboard_KEY_LMENU; - case XK_Meta_R: - return org_lwjgl_input_Keyboard_KEY_RMENU; - case XK_Alt_L: - return org_lwjgl_input_Keyboard_KEY_LMENU; - case XK_Alt_R: - return org_lwjgl_input_Keyboard_KEY_RMENU; - - case XK_dead_grave: - return org_lwjgl_input_Keyboard_KEY_GRAVE; - case XK_dead_circumflex: - return org_lwjgl_input_Keyboard_KEY_CIRCUMFLEX; - - /* - * Latin 1 - * Byte 3 = 0 - */ - case XK_space: - return org_lwjgl_input_Keyboard_KEY_SPACE; - case XK_apostrophe: - return org_lwjgl_input_Keyboard_KEY_APOSTROPHE; - case XK_comma: - return org_lwjgl_input_Keyboard_KEY_COMMA; - case XK_minus: - return org_lwjgl_input_Keyboard_KEY_MINUS; - case XK_period: - return org_lwjgl_input_Keyboard_KEY_PERIOD; - case XK_slash: - return org_lwjgl_input_Keyboard_KEY_SLASH; - case XK_0: - return org_lwjgl_input_Keyboard_KEY_0; - case XK_1: - return org_lwjgl_input_Keyboard_KEY_1; - case XK_2: - return org_lwjgl_input_Keyboard_KEY_2; - case XK_3: - return org_lwjgl_input_Keyboard_KEY_3; - case XK_4: - return org_lwjgl_input_Keyboard_KEY_4; - case XK_5: - return org_lwjgl_input_Keyboard_KEY_5; - case XK_6: - return org_lwjgl_input_Keyboard_KEY_6; - case XK_7: - return org_lwjgl_input_Keyboard_KEY_7; - case XK_8: - return org_lwjgl_input_Keyboard_KEY_8; - case XK_9: - return org_lwjgl_input_Keyboard_KEY_9; - case XK_colon: - return org_lwjgl_input_Keyboard_KEY_COLON; - case XK_semicolon: - return org_lwjgl_input_Keyboard_KEY_SEMICOLON; - case XK_equal: - return org_lwjgl_input_Keyboard_KEY_EQUALS; - case XK_at: - return org_lwjgl_input_Keyboard_KEY_AT; - case XK_bracketleft: - return org_lwjgl_input_Keyboard_KEY_LBRACKET; - case XK_bracketright: - return org_lwjgl_input_Keyboard_KEY_RBRACKET; - case XK_asciicircum: - return org_lwjgl_input_Keyboard_KEY_CIRCUMFLEX; - case XK_underscore: - return org_lwjgl_input_Keyboard_KEY_UNDERLINE; - case XK_grave: - return org_lwjgl_input_Keyboard_KEY_GRAVE; - case XK_a: - case XK_A: - return org_lwjgl_input_Keyboard_KEY_A; - case XK_b: - case XK_B: - return org_lwjgl_input_Keyboard_KEY_B; - case XK_c: - case XK_C: - return org_lwjgl_input_Keyboard_KEY_C; - case XK_d: - case XK_D: - return org_lwjgl_input_Keyboard_KEY_D; - case XK_e: - case XK_E: - return org_lwjgl_input_Keyboard_KEY_E; - case XK_f: - case XK_F: - return org_lwjgl_input_Keyboard_KEY_F; - case XK_g: - case XK_G: - return org_lwjgl_input_Keyboard_KEY_G; - case XK_h: - case XK_H: - return org_lwjgl_input_Keyboard_KEY_H; - case XK_i: - case XK_I: - return org_lwjgl_input_Keyboard_KEY_I; - case XK_j: - case XK_J: - return org_lwjgl_input_Keyboard_KEY_J; - case XK_k: - case XK_K: - return org_lwjgl_input_Keyboard_KEY_K; - case XK_l: - case XK_L: - return org_lwjgl_input_Keyboard_KEY_L; - case XK_m: - case XK_M: - return org_lwjgl_input_Keyboard_KEY_M; - case XK_n: - case XK_N: - return org_lwjgl_input_Keyboard_KEY_N; - case XK_o: - case XK_O: - return org_lwjgl_input_Keyboard_KEY_O; - case XK_p: - case XK_P: - return org_lwjgl_input_Keyboard_KEY_P; - case XK_q: - case XK_Q: - return org_lwjgl_input_Keyboard_KEY_Q; - case XK_r: - case XK_R: - return org_lwjgl_input_Keyboard_KEY_R; - case XK_s: - case XK_S: - return org_lwjgl_input_Keyboard_KEY_S; - case XK_t: - case XK_T: - return org_lwjgl_input_Keyboard_KEY_T; - case XK_u: - case XK_U: - return org_lwjgl_input_Keyboard_KEY_U; - case XK_v: - case XK_V: - return org_lwjgl_input_Keyboard_KEY_V; - case XK_w: - case XK_W: - return org_lwjgl_input_Keyboard_KEY_W; - case XK_x: - case XK_X: - return org_lwjgl_input_Keyboard_KEY_X; - case XK_y: - case XK_Y: - return org_lwjgl_input_Keyboard_KEY_Y; - case XK_z: - case XK_Z: - return org_lwjgl_input_Keyboard_KEY_Z; - default: - return org_lwjgl_input_Keyboard_KEY_NONE; - } -} - -static bool isKeypadKeysym(KeySym keysym) { - return (0xFF80 <= keysym && keysym <= 0xFFBD) || - (0x11000000 <= keysym && keysym <= 0x1100FFFF); -} - -static bool isNoSymbolOrVendorSpecific(KeySym keysym) { - return keysym == NoSymbol || (keysym & (1 << 28)) != 0; -} - -static KeySym getKeySym(XKeyEvent *event, int group, int index) { - KeySym keysym = XLookupKeysym(event, group*2 + index); - if (isNoSymbolOrVendorSpecific(keysym) && index == 1) { - keysym = XLookupKeysym(event, group*2 + 0); - } - if (isNoSymbolOrVendorSpecific(keysym) && group == 1) - keysym = getKeySym(event, 0, index); - return keysym; -} - -static KeySym toUpper(KeySym keysym) { - KeySym lower_case, upper_case; - XConvertCase(keysym, &lower_case, &upper_case); - return upper_case; -} - -/* Map an event to a KeySym. Use the rules described in - * http://tronche.com/gui/x/xlib/input/keyboard-encoding.html - */ -static KeySym mapEventToKeySym(XKeyEvent *event) { - int group; - KeySym keysym; - if ((event->state & modeswitch_mask) != 0) - group = 1; - else - group = 0; - if ((event->state & numlock_mask) != 0 && isKeypadKeysym(keysym = getKeySym(event, group, 1))) { - if ((event->state & (ShiftMask | shift_lock_mask)) != 0) { - return getKeySym(event, group, 0); - } else { - return keysym; - } - } else if ((event->state & (ShiftMask | LockMask)) == 0) { - return getKeySym(event, group, 0); - } else if ((event->state & ShiftMask) == 0) { - KeySym keysym = getKeySym(event, group, 0); - if ((event->state & caps_lock_mask) != 0) - keysym = toUpper(keysym); - return keysym; - } else { - KeySym keysym = getKeySym(event, group, 1); - if ((event->state & caps_lock_mask) != 0) - keysym = toUpper(keysym); - return keysym; - } -} - -static unsigned char getKeycode(XKeyEvent *event) { - unsigned char keycode; - KeySym keysym = mapEventToKeySym(event); - keycode = mapKeySymToLWJGLKeyCode(keysym); - if (keycode == org_lwjgl_input_Keyboard_KEY_NONE) { - // Try unshifted keysym mapping - keysym = XLookupKeysym(event, 0); - keycode = mapKeySymToLWJGLKeyCode(keysym); - } - return keycode; -} - -static void putKeyboardEvent(jint keycode, jint state, jint ch) { - int event_list[] = {keycode, state, ch}; - putEvent(&event_queue, event_list); -} - -static int lookupStringISO88591(XKeyEvent *event, jint *translation_buffer) { - static XComposeStatus status; - char char_translation_buffer[KEYBOARD_BUFFER_SIZE]; - int i; - - int num_chars = XLookupString(event, char_translation_buffer, KEYBOARD_BUFFER_SIZE*sizeof(char), NULL, &status); - for (i = 0; i < num_chars; i++) - translation_buffer[i] = ((jint)char_translation_buffer[i]) & 0xff; - return num_chars; -} - -static int lookupStringUnicode(XKeyEvent *event, jint *translation_buffer) { - char utf8_translation_buffer[KEYBOARD_BUFFER_SIZE]; - - jchar ucs2_translation_buffer[KEYBOARD_BUFFER_SIZE]; - char *utf8_buf = utf8_translation_buffer; - jchar *ucs2_buf = ucs2_translation_buffer; - size_t ucs2_bytes = KEYBOARD_BUFFER_SIZE*sizeof(jchar); - Status status; - int i; - - size_t utf8_bytes = Xutf8LookupString(xic, event, utf8_translation_buffer, KEYBOARD_BUFFER_SIZE*sizeof(char), NULL, &status); - if (status != XLookupChars && status != XLookupBoth) - return 0; - // reset converter - iconv(iconv_descriptor, NULL, NULL, NULL, NULL); - // convert from UTF-8 to UCS-2 - size_t iconv_result = iconv(iconv_descriptor, &utf8_buf, &utf8_bytes, (void *)&ucs2_buf, &ucs2_bytes); - // compute number of characters converted - int num_chars_converted = KEYBOARD_BUFFER_SIZE - ucs2_bytes/sizeof(jchar); - if (iconv_result == (size_t)-1) { - errno = 0; // ignore conversion error and return no chars converted - return 0; - } - for (i = 0; i < num_chars_converted; i++) { - translation_buffer[i] = ((jint)ucs2_translation_buffer[i]) & 0xffff; - } - return num_chars_converted; -} - -static int lookupString(XKeyEvent *event, jint *translation_buffer) { - if (xic != NULL) { - return lookupStringUnicode(event, translation_buffer); - } else - return lookupStringISO88591(event, translation_buffer); -} - -static void translateEvent(XKeyEvent *event, jint keycode, jint state) { - jint temp_translation_buffer[KEYBOARD_BUFFER_SIZE]; - int num_chars, i; - jint ch; - - if (event->type == KeyRelease) { - putKeyboardEvent(keycode, state, 0); - return; - } - num_chars = lookupString(event, temp_translation_buffer); - if (num_chars > 0) { - ch = temp_translation_buffer[0]; - putKeyboardEvent(keycode, state, ch); - for (i = 1; i < num_chars; i++) { - ch = temp_translation_buffer[i]; - putKeyboardEvent(0, 0, ch); - } - } else { - putKeyboardEvent(keycode, state, 0); - } -} - -static jbyte eventState(XKeyEvent *event) { - if (event->type == KeyPress) { - return 1; - } else if (event->type == KeyRelease) { - return 0; - } else - assert(0); -} - -static void bufferEvent(XKeyEvent *key_event) { - unsigned char keycode = getKeycode(key_event); - unsigned char state = eventState(key_event); - translateEvent(key_event, keycode, state); -} - -void handleKeyEvent(XKeyEvent *event) { - unsigned char keycode = getKeycode(event); - jbyte state = eventState(event); - key_buf[keycode] = state; - bufferEvent(event); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nPollKeyboard(JNIEnv * env, jclass clazz, jobject buffer) { - jbyte *new_keyboard_buffer = (jbyte *)(*env)->GetDirectBufferAddress(env, buffer); - memcpy(new_keyboard_buffer, key_buf, org_lwjgl_input_Keyboard_KEYBOARD_SIZE*sizeof(jbyte)); -} - -JNIEXPORT int JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nReadKeyboard(JNIEnv * env, jclass clazz, jobject buffer, jint buffer_position) { - jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer); - int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer))/sizeof(jint) - buffer_position; - return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size); -} diff --git a/src/native/linux/org_lwjgl_input_Mouse.c b/src/native/linux/org_lwjgl_input_Mouse.c deleted file mode 100644 index 6ac003f5..00000000 --- a/src/native/linux/org_lwjgl_input_Mouse.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2002-2004 LWJGL Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'LWJGL' nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * $Id$ - * - * Linux mouse handling. - * - * @author elias_naur - * @version $Revision$ - */ - -#include -#include -#include -#include -#include -#include -#include "Window.h" -#include "common_tools.h" -#include "display.h" -#include "org_lwjgl_input_Mouse.h" -#include "org_lwjgl_opengl_LinuxDisplay.h" - -#define EVENT_SIZE 5 - -#define POINTER_WARP_BORDER 10 -// scale the mouse wheel according to win32 -#define WHEEL_SCALE 120 - -static bool pointer_grabbed; -static bool created; - -static int accum_dx; -static int accum_dy; -static int accum_dz; -static int last_x; -static int last_y; -static jbyte buttons[org_lwjgl_opengl_LinuxDisplay_NUM_BUTTONS]; -static event_queue_t event_queue; - -static Cursor blank_cursor; -static Cursor current_cursor; - -static bool putMouseEventWithCoords(jint button, jint state, jint coord1, jint coord2, jint dz) { - jint event[] = {button, state, coord1, coord2, dz}; - return putEvent(&event_queue, event); -} - -static bool putMouseEvent(jint button, jint state, jint dz) { - if (isGrabbed()) - return putMouseEventWithCoords(button, state, 0, 0, dz); - else - return putMouseEventWithCoords(button, state, last_x, last_y, dz); -} - -static int transformY(int y) { - XWindowAttributes window_attributes; - XGetWindowAttributes(getDisplay(), getCurrentWindow(), &window_attributes); - return window_attributes.height - 1 - y; -} - -static void setCursorPos(int x, int y) { - y = transformY(y); - jint dx = x - last_x; - jint dy = y - last_y; - accum_dx += dx; - accum_dy += dy; - last_x = x; - last_y = y; - if (isGrabbed()) { - putMouseEventWithCoords(-1, 0, dx, dy, 0); - } else { - putMouseEventWithCoords(-1, 0, x, y, 0); - } -} - -static void resetCursor(int x, int y) { - last_x = x; - last_y = transformY(y); -} - -static bool blankCursor(JNIEnv *env) { - unsigned int best_width, best_height; - if (XQueryBestCursor(getDisplay(), getCurrentWindow(), 1, 1, &best_width, &best_height) == 0) { - throwException(env, "Could not query best cursor size"); - return false; - } - Pixmap mask = XCreatePixmap(getDisplay(), getCurrentWindow(), best_width, best_height, 1); - XGCValues gc_values; - gc_values.foreground = 0; - GC gc = XCreateGC(getDisplay(), mask, GCForeground, &gc_values); - XFillRectangle(getDisplay(), mask, gc, 0, 0, best_width, best_height); - XFreeGC(getDisplay(), gc); - XColor dummy_color; - blank_cursor = XCreatePixmapCursor(getDisplay(), mask, mask, &dummy_color, &dummy_color, 0, 0); - XFreePixmap(getDisplay(), mask); - return true; -} - -static void updateCursor(void) { - Cursor cursor; - if (shouldGrab()) { - cursor = blank_cursor; - } else { - cursor = current_cursor; - } - XDefineCursor(getDisplay(), getCurrentWindow(), cursor); -} - -static void grabPointer(jint window_mode) { - if (!pointer_grabbed) { - int result; - int grab_mask = PointerMotionMask | ButtonPressMask | ButtonReleaseMask; - result = XGrabPointer(getDisplay(), getCurrentWindow(), False, grab_mask, GrabModeAsync, - GrabModeAsync, getCurrentWindow(), None, CurrentTime); - if (result == GrabSuccess) { - pointer_grabbed = true; - // make sure we have a centered window - if (isLegacyFullscreen(window_mode)) { - XWindowAttributes win_attribs; - XGetWindowAttributes(getDisplay(), getCurrentWindow(), &win_attribs); - XF86VidModeSetViewPort(getDisplay(), getCurrentScreen(), win_attribs.x, win_attribs.y); - } - XFlush(getDisplay()); - } - } -} - -static void ungrabPointer(void) { - if (pointer_grabbed) { - pointer_grabbed = false; - XUngrabPointer(getDisplay(), CurrentTime); - XFlush(getDisplay()); - } -} - -void updatePointerGrab(jint window_mode) { - if (!created) - return; - if (isFullscreen(window_mode) || shouldGrab()) { - grabPointer(window_mode); - } else { - ungrabPointer(); - } - updateCursor(); -} - -void handleWarpEvent(XClientMessageEvent *event) { - int center_x = event->data.l[0]; - int center_y = event->data.l[1]; - resetCursor(center_x, center_y); -} - -static void doWarpPointer(int center_x, int center_y) { - XEvent warp_event; - warp_event.type = ClientMessage; - warp_event.xclient.window = getCurrentWindow(); - warp_event.xclient.message_type = getWarpAtom(); - warp_event.xclient.format = 32; - warp_event.xclient.data.l[0] = center_x; - warp_event.xclient.data.l[1] = center_y; - XSendEvent(getDisplay(), getCurrentWindow(), False, 0, &warp_event); - XWarpPointer(getDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, center_x, center_y); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetNativeCursor(JNIEnv *env, jclass clazz, jobject cursor_handle) { - if (cursor_handle != NULL) { - Cursor *cursor = (Cursor *)(*env)->GetDirectBufferAddress(env, cursor_handle); - current_cursor = *cursor; - } else - current_cursor = None; - updateCursor(); -} - -static void reset(void) { - initEventQueue(&event_queue, EVENT_SIZE); - accum_dx = accum_dy = 0; -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateMouse - (JNIEnv * env, jclass clazz, jint window_mode) -{ - int i; - last_y = last_x = accum_dx = accum_dy = accum_dz = 0; - reset(); - for (i = 0; i < org_lwjgl_opengl_LinuxDisplay_NUM_BUTTONS; i++) - buttons[i] = 0; - if (!blankCursor(env)) { - return; - } - current_cursor = None; - created = true; - pointer_grabbed = false; - updatePointerGrab(window_mode); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nDestroyMouse - (JNIEnv * env, jclass clazz) -{ - ungrabPointer(); - XFreeCursor(getDisplay(), blank_cursor); - created = false; -} - -static unsigned char mapButton(XButtonEvent *event) { - switch (event->button) { - case Button1: - return 0; - case Button2: - return 2; - case Button3: - return 1; - default: return org_lwjgl_opengl_LinuxDisplay_NUM_BUTTONS; - } -} - -static void handleButton(XButtonEvent *event, unsigned char state) { - unsigned char button_num = mapButton(event); - if (button_num == org_lwjgl_opengl_LinuxDisplay_NUM_BUTTONS) - return; - buttons[button_num] = state; - putMouseEvent(button_num, state, 0); -} - -void handleButtonPress(XButtonEvent *event) { - jint delta = 0; - switch (event->button) { - case Button4: - delta = WHEEL_SCALE; - putMouseEvent(-1, 0, delta); - break; - case Button5: - delta = -WHEEL_SCALE; - putMouseEvent(-1, 0, delta); - break; - default: - break; - } - accum_dz += delta; - handleButton(event, 1); -} - -void handleButtonRelease(XButtonEvent *event) { - handleButton(event, 0); -} - -static int max(int v1, int v2) { - return v1 > v2 ? v1 : v2; -} - -static int min(int v1, int v2) { - return v1 < v2 ? v1 : v2; -} - -static void doHandlePointerMotion(Window root_window, Window window, int root_x, int root_y, int win_x, int win_y) { - setCursorPos(win_x, win_y); - if (!pointer_grabbed || !shouldGrab()) - return; - XWindowAttributes window_attributes; - XGetWindowAttributes(getDisplay(), root_window, &window_attributes); - int root_window_width = window_attributes.width; - int root_window_height = window_attributes.height; - XGetWindowAttributes(getDisplay(), window, &window_attributes); - int window_width = window_attributes.width; - int window_height = window_attributes.height; - - // find the window position in root coordinates - int win_left = root_x - win_x; - int win_top = root_y - win_y; - int win_right = win_left + window_width; - int win_bottom = win_top + window_height; - // cap the window position to the screen dimensions - int border_left = max(0, win_left); - int border_top = max(0, win_top); - int border_right = min(root_window_width, win_right); - int border_bottom = min(root_window_height, win_bottom); - // determine whether the cursor is outside the bounds - bool outside_limits = root_x < border_left + POINTER_WARP_BORDER || root_y < border_top + POINTER_WARP_BORDER || - root_x > border_right - POINTER_WARP_BORDER || root_y > border_bottom - POINTER_WARP_BORDER; - if (outside_limits) { - // Find the center of the limits in window coordinates - int center_x = (border_right - border_left)/2; - int center_y = (border_bottom - border_top)/2; - doWarpPointer(center_x, center_y); - } -} - -void handlePointerMotion(XMotionEvent *event) { - doHandlePointerMotion(event->root, getCurrentWindow(), event->x_root, event->y_root, event->x, event->y); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nPollMouse(JNIEnv * env, jclass clazz, jobject coord_buffer_obj, jobject button_buffer_obj) { - int *coords = (int *)(*env)->GetDirectBufferAddress(env, coord_buffer_obj); - int coords_length = (*env)->GetDirectBufferCapacity(env, coord_buffer_obj); - unsigned char *buttons_buffer = (unsigned char *)(*env)->GetDirectBufferAddress(env, button_buffer_obj); - int buttons_length = (*env)->GetDirectBufferCapacity(env, button_buffer_obj); - if (coords_length < 3) { - printfDebugJava(env, "ERROR: Not enough space in coords array: %d < 3", coords_length); - return; - } - if (isGrabbed()) { - coords[0] = accum_dx; - coords[1] = accum_dy; - } else { - coords[0] = last_x; - coords[1] = last_y; - } - coords[2] = accum_dz; - accum_dx = accum_dy = accum_dz = 0; - int num_buttons = org_lwjgl_opengl_LinuxDisplay_NUM_BUTTONS; - if (num_buttons > buttons_length) - num_buttons = buttons_length; - int i; - for (i = 0; i < num_buttons; i++) - buttons_buffer[i] = buttons[i]; -} - -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nReadMouse(JNIEnv *env, jclass clazz, jobject buffer, jint buffer_position) { - jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer); - int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer))/sizeof(jint) - buffer_position; - return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetCursorPosition(JNIEnv * env, jclass clazz, jint x, jint y) { - XWarpPointer(getDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, x, transformY(y)); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGrabMouse(JNIEnv * env, jclass clazz, jint window_mode, jboolean new_grab) { - Window root_return, child_return; - int root_x, root_y, win_x, win_y; - unsigned int mask_return; - - setGrab(window_mode, new_grab == JNI_TRUE ? true : false); - reset(); - XQueryPointer(getDisplay(), getCurrentWindow(), &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return); - doHandlePointerMotion(root_return, getCurrentWindow(), root_x, root_y, win_x, win_y); -} diff --git a/src/native/linux/org_lwjgl_opengl_Display.c b/src/native/linux/org_lwjgl_opengl_Display.c index df4fea03..a519be09 100644 --- a/src/native/linux/org_lwjgl_opengl_Display.c +++ b/src/native/linux/org_lwjgl_opengl_Display.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -78,11 +79,8 @@ static Pixmap current_icon_pixmap; static Visual *current_visual; -static bool input_released; - static bool dirty; static bool minimized; -static bool focused; static bool closerequested; static bool grab; @@ -151,25 +149,15 @@ static void waitMapped(Window win) { } while ((event.type != MapNotify) || (event.xmap.event != win)); } -static void updateInputGrab(jint window_mode) { - updatePointerGrab(window_mode); - updateKeyboardGrab(window_mode); -} - -static void setRepeatMode(JNIEnv *env, int mode) { - XKeyboardControl repeat_mode; - repeat_mode.auto_repeat_mode = mode; +static void __attribute__ ((destructor)) my_fini(void) { Display *disp = XOpenDisplay(NULL); - if (disp == NULL && env != NULL) { - printfDebugJava(env, "Could not open display to set repeat mode"); + if (disp == NULL) { return; } + XKeyboardControl repeat_mode; + repeat_mode.auto_repeat_mode = AutoRepeatModeDefault; XChangeKeyboardControl(disp, KBAutoRepeatMode, &repeat_mode); XCloseDisplay(disp); -} - -static void __attribute__ ((destructor)) my_fini(void) { - setRepeatMode(NULL, AutoRepeatModeDefault); } static void setDecorations(int dec) { @@ -180,71 +168,25 @@ static void setDecorations(int dec) { XChangeProperty (getDisplay(), getCurrentWindow(), motif_hints_atom, motif_hints_atom, 32, PropModeReplace, (unsigned char *)&motif_hints, sizeof(MotifWmHints)/sizeof(long)); } -static bool releaseInput(JNIEnv *env, jint extension, jint window_mode, jobject gamma_ramp, jobject saved_mode) { - if (isLegacyFullscreen(window_mode) || input_released) - return false; - input_released = true; - setRepeatMode(env, AutoRepeatModeDefault); - updateInputGrab(window_mode); - if (window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_NETWM) { - XIconifyWindow(getDisplay(), getCurrentWindow(), getCurrentScreen()); - switchDisplayMode(env, getCurrentScreen(), extension, saved_mode); - setGammaRamp(env, getCurrentScreen(), gamma_ramp); - } - return true; -} - -static void acquireInput(JNIEnv *env, jint extension, jint window_mode, jobject gamma_ramp, jobject mode) { - if (isLegacyFullscreen(window_mode) || !input_released) - return; - input_released = false; - setRepeatMode(env, AutoRepeatModeOff); - updateInputGrab(window_mode); - if (window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_NETWM) { - switchDisplayMode(env, getCurrentScreen(), extension, mode); - setGammaRamp(env, getCurrentScreen(), gamma_ramp); - } -} - -bool isFullscreen(jint window_mode) { - return window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_LEGACY || window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_NETWM; -} - -bool isLegacyFullscreen(jint window_mode) { +static bool isLegacyFullscreen(jint window_mode) { return window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_LEGACY; } -bool shouldGrab(void) { - return !input_released && grab; -} - -bool isGrabbed(void) { - return grab; -} - -void setGrab(jint window_mode, bool new_grab) { - if (new_grab != grab) { - grab = new_grab; - updateInputGrab(window_mode); - } -} - -static void checkInput(JNIEnv *env, jint extension, jint window_mode, jobject saved_gamma, jobject current_gamma, jobject saved_mode, jobject current_mode) { - Window win; - int revert_mode; - XGetInputFocus(getDisplay(), &win, &revert_mode); - if (win == current_win) { - acquireInput(env, extension, window_mode, current_gamma, current_mode); - focused = true; - } else { - releaseInput(env, extension, window_mode, saved_gamma, saved_mode); - focused = false; - } -} - -static void handleMessages(JNIEnv *env, jint extension, jint window_mode, jobject saved_gamma, jobject current_gamma, jobject saved_mode, jobject current_mode) { +static void handleMessages(JNIEnv *env, jclass disp_class) { XEvent event; - while (XPending(getDisplay()) > 0) { + jmethodID handleKeyEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handleKeyEvent", "(JJIII)V"); + if (handleKeyEvent_method == NULL) + return; + jmethodID handleButtonEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handleButtonEvent", "(JIII)V"); + if (handleButtonEvent_method == NULL) + return; + jmethodID handlePointerMotionEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handlePointerMotionEvent", "(JIIIII)V"); + if (handlePointerMotionEvent_method == NULL) + return; + jmethodID handleWarpEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handleWarpEvent", "(II)V"); + if (handleWarpEvent_method == NULL) + return; + while (!(*env)->ExceptionOccurred(env) && XPending(getDisplay()) > 0) { XNextEvent(getDisplay(), &event); if (XFilterEvent(&event, None) == True) continue; @@ -254,7 +196,7 @@ static void handleMessages(JNIEnv *env, jint extension, jint window_mode, jobjec switch (event.type) { case ClientMessage: if (event.xclient.message_type == warp_atom) { - handleWarpEvent(&(event.xclient)); + (*env)->CallStaticVoidMethod(env, disp_class, handleWarpEvent_method, (jint)event.xclient.data.l[0], (jint)event.xclient.data.l[1]); } else if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom)) closerequested = true; break; @@ -269,22 +211,19 @@ static void handleMessages(JNIEnv *env, jint extension, jint window_mode, jobjec case Expose: dirty = true; break; - case ButtonPress: - handleButtonPress(&(event.xbutton)); - break; + case ButtonPress: /* Fall through */ case ButtonRelease: - handleButtonRelease(&(event.xbutton)); + (*env)->CallStaticVoidMethod(env, disp_class, handleButtonEvent_method, (jlong)event.xbutton.time, (jint)event.xbutton.type, (jint)event.xbutton.button, (jint)event.xbutton.state); break; case MotionNotify: - handlePointerMotion(&(event.xmotion)); + (*env)->CallStaticVoidMethod(env, disp_class, handlePointerMotionEvent_method, (jlong)event.xbutton.root, (jint)event.xbutton.x_root, (jint)event.xbutton.y_root, (jint)event.xbutton.x, (jint)event.xbutton.y, (jint)event.xbutton.state); break; case KeyPress: case KeyRelease: - handleKeyEvent(&(event.xkey)); + (*env)->CallStaticVoidMethod(env, disp_class, handleKeyEvent_method, (jlong)(intptr_t)&(event.xkey), (jlong)event.xkey.time, (jint)event.xkey.type, (jint)event.xkey.keycode, (jint)event.xkey.state); break; } } - checkInput(env, extension, window_mode, saved_gamma, current_gamma, saved_mode, current_mode); } static void setWindowTitle(const char *title) { @@ -332,7 +271,6 @@ static void destroyWindow(JNIEnv *env) { XDestroyWindow(getDisplay(), current_win); XFreeColormap(getDisplay(), cmap); freeIconPixmap(); - setRepeatMode(env, AutoRepeatModeDefault); } static bool isNetWMFullscreenSupported(JNIEnv *env) { @@ -371,7 +309,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nReshape(JNIEnv *env, static bool createWindow(JNIEnv* env, jint window_mode, X11PeerInfo *peer_info, int x, int y, int width, int height) { bool undecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated"); dirty = true; - focused = true; minimized = false; closerequested = false; grab = false; @@ -380,7 +317,6 @@ static bool createWindow(JNIEnv* env, jint window_mode, X11PeerInfo *peer_info, XSetWindowAttributes attribs; int attribmask; - input_released = false; root_win = RootWindow(getDisplay(), getCurrentScreen()); XVisualInfo *vis_info = getVisualInfoFromPeerInfo(env, peer_info); if (vis_info == NULL) @@ -429,7 +365,6 @@ static bool createWindow(JNIEnv* env, jint window_mode, X11PeerInfo *peer_info, XMapRaised(getDisplay(), win); waitMapped(win); XClearWindow(getDisplay(), win); - setRepeatMode(env, AutoRepeatModeOff); if (!checkXError(env, getDisplay())) { destroyWindow(env); return false; @@ -444,7 +379,7 @@ Window getCurrentWindow(void) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUpdate (JNIEnv *env, jclass clazz, jint extension, jint window_mode, jobject saved_gamma, jobject current_gamma, jobject saved_mode, jobject current_mode) { - handleMessages(env, extension, window_mode, saved_gamma, current_gamma, saved_mode, current_mode); + handleMessages(env, clazz); } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject mode, jint window_mode, jint x, jint y) { @@ -497,11 +432,6 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nIsCloseRequested return saved; } -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nIsActive - (JNIEnv *env, jclass clazz, jint window_mode) { - return focused || isLegacyFullscreen(window_mode) ? JNI_TRUE : JNI_FALSE; -} - JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nLockAWT(JNIEnv *env, jclass clazz) { JAWT jawt; jawt.version = JAWT_VERSION_1_4; @@ -572,3 +502,103 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetWindowIcon setIcon(env, imgData, icon_size, width, height); } +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getDisplay(JNIEnv *env, jclass unused) { + return (intptr_t)getDisplay(); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getWindow(JNIEnv *env, jclass unused) { + return getCurrentWindow(); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUngrabKeyboard(JNIEnv *env, jclass unused, jlong display_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + return XUngrabKeyboard(disp, CurrentTime); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGrabKeyboard(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + return XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGrabPointer(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + int grab_mask = PointerMotionMask | ButtonPressMask | ButtonReleaseMask; + return XGrabPointer(disp, win, False, grab_mask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetViewPort(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jint screen) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + XWindowAttributes win_attribs; + + XGetWindowAttributes(disp, win, &win_attribs); + XF86VidModeSetViewPort(disp, screen, win_attribs.x, win_attribs.y); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUngrabPointer(JNIEnv *env, jclass unused, jlong display_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + return XUngrabPointer(disp, CurrentTime); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nDefineCursor(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jobject cursor_handle) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + Cursor cursor; + if (cursor_handle != NULL) + cursor = *((Cursor *)(*env)->GetDirectBufferAddress(env, cursor_handle)); + else + cursor = None; + XDefineCursor(disp, win, cursor); +} + +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateBlankCursor(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + jobject handle_buffer = newJavaManagedByteBuffer(env, sizeof(Cursor)); + if (handle_buffer == NULL) { + return NULL; + } + Cursor *cursor = (Cursor *)(*env)->GetDirectBufferAddress(env, handle_buffer); + unsigned int best_width, best_height; + if (XQueryBestCursor(disp, win, 1, 1, &best_width, &best_height) == 0) { + throwException(env, "Could not query best cursor size"); + return false; + } + Pixmap mask = XCreatePixmap(disp, win, best_width, best_height, 1); + XGCValues gc_values; + gc_values.foreground = 0; + GC gc = XCreateGC(disp, mask, GCForeground, &gc_values); + XFillRectangle(disp, mask, gc, 0, 0, best_width, best_height); + XFreeGC(disp, gc); + XColor dummy_color; + *cursor = XCreatePixmapCursor(disp, mask, mask, &dummy_color, &dummy_color, 0, 0); + XFreePixmap(disp, mask); + return handle_buffer; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getScreen(JNIEnv *env, jclass unsused) { + return getCurrentScreen(); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetInputFocus(JNIEnv *env, jclass unused, jlong display_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + int revert_mode; + Window win; + XGetInputFocus(disp, &win, &revert_mode); + return win; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetRepeatMode(JNIEnv *env, jclass unused, jlong display_ptr, jint mode) { + Display *disp = (Display *)(intptr_t)display_ptr; + XKeyboardControl repeat_mode; + repeat_mode.auto_repeat_mode = mode; + XChangeKeyboardControl(disp, KBAutoRepeatMode, &repeat_mode); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nIconifyWindow(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jint screen) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + XIconifyWindow(disp, win, screen); +} diff --git a/src/native/linux/org_lwjgl_opengl_LinuxKeyboard.c b/src/native/linux/org_lwjgl_opengl_LinuxKeyboard.c new file mode 100644 index 00000000..46d64b04 --- /dev/null +++ b/src/native/linux/org_lwjgl_opengl_LinuxKeyboard.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2399 2006-06-30 19:28:00Z elias_naur $ + * + * Linux keyboard handling. + * + * @author elias_naur + * @version $Revision: 2399 $ + */ + +#include +#include +#include +#include +#include "Window.h" +#include "common_tools.h" +#include "org_lwjgl_opengl_LinuxKeyboard.h" + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_getModifierMapping(JNIEnv *env, jclass unused, jlong display_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + XModifierKeymap *modifier_map = XGetModifierMapping(disp); + return (intptr_t)modifier_map; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_freeModifierMapping(JNIEnv *env, jclass unused, jlong mapping_ptr) { + XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr; + XFreeModifiermap(modifier_map); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_getMaxKeyPerMod(JNIEnv *env, jclass unsused, jlong mapping_ptr) { + XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr; + return modifier_map->max_keypermod; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_lookupModifierMap(JNIEnv *env, jclass unused, jlong mapping_ptr, jint index) { + XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr; + KeyCode key_code = modifier_map->modifiermap[index]; + return key_code; +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_keycodeToKeySym(JNIEnv *env, jclass unused, jlong display_ptr, jint key_code) { + Display *disp = (Display *)(intptr_t)display_ptr; + KeySym key_sym = XKeycodeToKeysym(disp, key_code, 0); + return key_sym; +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_openIM(JNIEnv *env, jclass unused, jlong display_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + XIM xim = XOpenIM(disp, NULL, NULL, NULL); + return (intptr_t)xim; +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_createIC(JNIEnv *env, jclass unused, jlong xim_ptr, jlong window_ptr) { + Window win = (Window)window_ptr; + XIM xim = (XIM)(intptr_t)xim_ptr; + XIC xic = XCreateIC(xim, XNClientWindow, win, XNFocusWindow, win, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL); + return (intptr_t)xic; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_setupIMEventMask(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jlong xic_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + XIC xic = (XIC)(intptr_t)xic_ptr; + long im_event_mask; + XWindowAttributes win_attributes; + + XGetWindowAttributes(disp, win, &win_attributes); + XGetICValues(xic, XNFilterEvents, &im_event_mask, NULL); + XSelectInput(disp, win, win_attributes.your_event_mask | im_event_mask); + XSetICFocus(xic); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_destroyIC(JNIEnv *env, jclass unused, jlong xic_ptr) { + XIC xic = (XIC)(intptr_t)xic_ptr; + XDestroyIC(xic); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_closeIM(JNIEnv *env, jclass unused, jlong xim_ptr) { + XIM xim = (XIM)(intptr_t)xim_ptr; + XCloseIM(xim); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_lookupKeysym(JNIEnv *env, jclass unused, jlong event_ptr, jint index) { + XKeyEvent *event = (XKeyEvent *)(intptr_t)event_ptr; + return XLookupKeysym(event, index); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_toUpper(JNIEnv *env, jclass unused, jlong keysym) { + KeySym lower_case, upper_case; + XConvertCase(keysym, &lower_case, &upper_case); + return upper_case; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_lookupString(JNIEnv *env, jclass unused, jlong event_ptr, jobject buffer_obj, jobject compose_status_obj) { + XKeyEvent *event = (XKeyEvent *)(intptr_t)event_ptr; + char *buffer = (char *)(*env)->GetDirectBufferAddress(env, buffer_obj); + int capacity = (*env)->GetDirectBufferCapacity(env, buffer_obj); + XComposeStatus *status = (XComposeStatus *)(*env)->GetDirectBufferAddress(env, compose_status_obj); + return XLookupString(event, buffer, capacity, NULL, status); +} + +JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_allocateComposeStatus(JNIEnv *env, jclass unused) { + return newJavaManagedByteBuffer(env, sizeof(XComposeStatus)); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_utf8LookupString(JNIEnv *env, jclass unused, jlong xic_ptr, jlong event_ptr, jobject buffer_obj, jint buffer_position, jint buffer_size) { + XIC xic = (XIC)(intptr_t)xic_ptr; + XKeyEvent *event = (XKeyEvent *)(intptr_t)event_ptr; + char *buffer = buffer_position + (char *)(*env)->GetDirectBufferAddress(env, buffer_obj); + Status status; + size_t num_bytes = Xutf8LookupString(xic, event, buffer, buffer_size, NULL, &status); + positionBuffer(env, buffer_obj, num_bytes); + return status; +} diff --git a/src/native/linux/org_lwjgl_opengl_LinuxMouse.c b/src/native/linux/org_lwjgl_opengl_LinuxMouse.c new file mode 100644 index 00000000..827a0fb0 --- /dev/null +++ b/src/native/linux/org_lwjgl_opengl_LinuxMouse.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2399 2006-06-30 19:28:00Z elias_naur $ + * + * Linux mouse handling. + * + * @author elias_naur + * @version $Revision: 2399 $ + */ + +#include +#include +#include +#include "Window.h" +#include "common_tools.h" +#include "org_lwjgl_opengl_LinuxMouse.h" + +static void getWindowAttributes(jlong display_ptr, jlong window_ptr, XWindowAttributes *attr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + XGetWindowAttributes(disp, win, attr); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxMouse_nGetWindowHeight(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + XWindowAttributes window_attributes; + getWindowAttributes(display_ptr, window_ptr, &window_attributes); + return window_attributes.height; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxMouse_nGetWindowWidth(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + XWindowAttributes window_attributes; + getWindowAttributes(display_ptr, window_ptr, &window_attributes); + return window_attributes.width; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxMouse_nWarpCursor(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jint x, jint y) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + XWarpPointer(disp, None, win, 0, 0, 0, 0, x, y); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxMouse_nQueryPointer(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr, jobject result_buffer) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + Window root_return, child_return; + int root_x, root_y, win_x, win_y; + unsigned int mask_return; + jint *result = (jint *)(*env)->GetDirectBufferAddress(env, result_buffer); + int result_size = (*env)->GetDirectBufferCapacity(env, result_buffer); + if (result_size < 4) { + throwFormattedException(env, "Not enough space in result buffer (%d)", result_size); + return (intptr_t)NULL; + } + + XQueryPointer(disp, win, &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return); + result[0] = root_x; + result[1] = root_y; + result[2] = win_x; + result[3] = win_y; + return root_return; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxMouse_nSendWarpEvent(JNIEnv *env, jclass unusued, jlong display_ptr, jlong window_ptr, jint x, jint y) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = (Window)window_ptr; + XEvent warp_event; + warp_event.type = ClientMessage; + warp_event.xclient.window = win; + warp_event.xclient.message_type = getWarpAtom(); + warp_event.xclient.format = 32; + warp_event.xclient.data.l[0] = x; + warp_event.xclient.data.l[1] = y; + XSendEvent(disp, win, False, 0, &warp_event); +} diff --git a/src/native/win32/dinputhelper.c b/src/native/win32/dinputhelper.c index e8b85f61..e61ef671 100644 --- a/src/native/win32/dinputhelper.c +++ b/src/native/win32/dinputhelper.c @@ -61,17 +61,3 @@ HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const return should_continue == JNI_TRUE ? true : false; } -bool positionBuffer(JNIEnv *env, jobject buffer, jint position) { - jclass buffer_class; - jmethodID position_method; - - buffer_class = (*env)->GetObjectClass(env, buffer); - if (buffer_class == NULL) - return false; - position_method = (*env)->GetMethodID(env, buffer_class, "position", "(I)Ljava/nio/Buffer;"); - if (position_method == NULL) - return false; - (*env)->CallObjectMethod(env, buffer, position_method, position); - return true; -} - diff --git a/src/native/win32/dinputhelper.h b/src/native/win32/dinputhelper.h index e544f65d..2de09bf4 100755 --- a/src/native/win32/dinputhelper.h +++ b/src/native/win32/dinputhelper.h @@ -49,6 +49,5 @@ typedef struct { } enum_context_t; HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const char *tszName); -bool positionBuffer(JNIEnv *env, jobject buffer, jint position); #endif