Linux: Moved most input related stuff from native to java
This commit is contained in:
parent
5671f93656
commit
cbe41294a5
|
@ -450,6 +450,7 @@
|
||||||
<target name="headers" description="invokes javah on java classes" depends="compile">
|
<target name="headers" description="invokes javah on java classes" depends="compile">
|
||||||
<!-- platform specific classes -->
|
<!-- platform specific classes -->
|
||||||
<javah classpath="${lwjgl.bin}" destdir="${lwjgl.src.native}/linux" force="yes">
|
<javah classpath="${lwjgl.bin}" destdir="${lwjgl.src.native}/linux" force="yes">
|
||||||
|
<class name="org.lwjgl.opengl.LinuxMouse" />
|
||||||
<class name="org.lwjgl.opengl.LinuxKeyboard" />
|
<class name="org.lwjgl.opengl.LinuxKeyboard" />
|
||||||
<class name="org.lwjgl.opengl.LinuxDisplay" />
|
<class name="org.lwjgl.opengl.LinuxDisplay" />
|
||||||
<class name="org.lwjgl.opengl.LinuxPeerInfo" />
|
<class name="org.lwjgl.opengl.LinuxPeerInfo" />
|
||||||
|
|
|
@ -47,6 +47,13 @@ import org.lwjgl.LWJGLUtil;
|
||||||
import org.lwjgl.input.Keyboard;
|
import org.lwjgl.input.Keyboard;
|
||||||
|
|
||||||
final class LinuxDisplay implements DisplayImplementation {
|
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 */
|
/** Window mode enum */
|
||||||
private static final int FULLSCREEN_LEGACY = 1;
|
private static final int FULLSCREEN_LEGACY = 1;
|
||||||
private static final int FULLSCREEN_NETWM = 2;
|
private static final int FULLSCREEN_NETWM = 2;
|
||||||
|
@ -63,8 +70,6 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
/** Current mode swithcing API */
|
/** Current mode swithcing API */
|
||||||
private static int current_displaymode_extension = NONE;
|
private static int current_displaymode_extension = NONE;
|
||||||
|
|
||||||
private static final int NUM_BUTTONS = 3;
|
|
||||||
|
|
||||||
/** Keep track on the current awt lock owner to avoid
|
/** Keep track on the current awt lock owner to avoid
|
||||||
* depending on JAWT locking to be re-entrant (This is a
|
* depending on JAWT locking to be re-entrant (This is a
|
||||||
* problem with GCJ). JAWT locking is not that well specified
|
* 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 saved_mode;
|
||||||
private static DisplayMode current_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 {
|
private static ByteBuffer getCurrentGammaRamp() throws LWJGLException {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
|
@ -257,39 +273,155 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
return WINDOWED;
|
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 {
|
public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
try {
|
||||||
|
incDisplay();
|
||||||
try {
|
try {
|
||||||
ByteBuffer handle = peer_info.lockAndGetHandle();
|
ByteBuffer handle = peer_info.lockAndGetHandle();
|
||||||
try {
|
try {
|
||||||
current_window_mode = getWindowMode(fullscreen);
|
current_window_mode = getWindowMode(fullscreen);
|
||||||
nCreateWindow(handle, mode, current_window_mode, x, y);
|
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 {
|
} finally {
|
||||||
peer_info.unlock();
|
peer_info.unlock();
|
||||||
}
|
}
|
||||||
|
} catch (LWJGLException e) {
|
||||||
|
decDisplay();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static native void nCreateWindow(ByteBuffer peer_info_handle, DisplayMode mode, int window_mode, int x, int y) throws LWJGLException;
|
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() {
|
public void destroyWindow() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
setNativeCursor(null);
|
||||||
|
} catch (LWJGLException e) {
|
||||||
|
LWJGLUtil.log("Failed to reset cursor: " + e.getMessage());
|
||||||
|
}
|
||||||
|
nDestroyCursor(blank_cursor);
|
||||||
|
blank_cursor = null;
|
||||||
|
ungrabKeyboard();
|
||||||
nDestroyWindow();
|
nDestroyWindow();
|
||||||
|
nSetRepeatMode(getDisplay(), AutoRepeatModeDefault);
|
||||||
|
decDisplay();
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static native void nDestroyWindow();
|
private static native void nDestroyWindow();
|
||||||
|
|
||||||
public void switchDisplayMode(DisplayMode mode) throws LWJGLException {
|
public void switchDisplayMode(DisplayMode mode) throws LWJGLException {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
nSwitchDisplayMode(current_displaymode_extension, mode);
|
nSwitchDisplayMode(getScreen(), current_displaymode_extension, mode);
|
||||||
current_mode = mode;
|
current_mode = mode;
|
||||||
} finally {
|
} finally {
|
||||||
unlockAWT();
|
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() {
|
public void resetDisplayMode() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
@ -312,7 +444,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
try {
|
try {
|
||||||
incDisplay();
|
incDisplay();
|
||||||
try {
|
try {
|
||||||
return nGetGammaRampLength();
|
return nGetGammaRampLength(getDisplay(), getScreen());
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
LWJGLUtil.log("Got exception while querying gamma length: " + e);
|
LWJGLUtil.log("Got exception while querying gamma length: " + e);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -327,7 +459,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
unlockAWT();
|
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 {
|
public void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException {
|
||||||
if (!isXF86VidModeSupported())
|
if (!isXF86VidModeSupported())
|
||||||
|
@ -338,13 +470,13 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
private static void doSetGamma(ByteBuffer native_gamma) throws LWJGLException {
|
private static void doSetGamma(ByteBuffer native_gamma) throws LWJGLException {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
nSetGammaRamp(native_gamma);
|
nSetGammaRamp(getScreen(), native_gamma);
|
||||||
current_gamma = native_gamma;
|
current_gamma = native_gamma;
|
||||||
} finally {
|
} finally {
|
||||||
unlockAWT();
|
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 {
|
private static ByteBuffer convertToNativeRamp(FloatBuffer ramp) throws LWJGLException {
|
||||||
return nConvertToNativeRamp(ramp, ramp.position(), ramp.remaining());
|
return nConvertToNativeRamp(ramp, ramp.position(), ramp.remaining());
|
||||||
|
@ -406,34 +538,42 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
try {
|
||||||
nSetTitle(title);
|
nSetTitle(title);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static native void nSetTitle(String title);
|
private static native void nSetTitle(String title);
|
||||||
|
|
||||||
public boolean isCloseRequested() {
|
public boolean isCloseRequested() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
boolean result = nIsCloseRequested();
|
try {
|
||||||
|
return nIsCloseRequested();
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
private static native boolean nIsCloseRequested();
|
private static native boolean nIsCloseRequested();
|
||||||
|
|
||||||
public boolean isVisible() {
|
public boolean isVisible() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
boolean result = nIsVisible();
|
try {
|
||||||
|
return nIsVisible();
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
private static native boolean nIsVisible();
|
private static native boolean nIsVisible();
|
||||||
|
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
boolean result = nIsActive(current_window_mode);
|
try {
|
||||||
|
return focused || isLegacyFullscreen();
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
private static native boolean nIsActive(int window_mode);
|
}
|
||||||
|
|
||||||
public boolean isDirty() {
|
public boolean isDirty() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
@ -452,18 +592,23 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
nUpdate(current_displaymode_extension, current_window_mode, saved_gamma, current_gamma, saved_mode, current_mode);
|
nUpdate(current_displaymode_extension, current_window_mode, saved_gamma, current_gamma, saved_mode, current_mode);
|
||||||
|
checkInput();
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
LWJGLUtil.log("Caught exception while processing messages: " + 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;
|
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) {
|
public void reshape(int x, int y, int width, int height) {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
try {
|
||||||
nReshape(x, y, width, height);
|
nReshape(x, y, width, height);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static native void nReshape(int x, int y, int width, int height);
|
private static native void nReshape(int x, int y, int width, int height);
|
||||||
|
|
||||||
public DisplayMode[] getAvailableDisplayModes() throws LWJGLException {
|
public DisplayMode[] getAvailableDisplayModes() throws LWJGLException {
|
||||||
|
@ -488,61 +633,118 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getButtonCount() {
|
public int getButtonCount() {
|
||||||
return NUM_BUTTONS;
|
return mouse.getButtonCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createMouse() {
|
public void createMouse() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
nCreateMouse(current_window_mode);
|
try {
|
||||||
|
mouse = new LinuxMouse(getDisplay(), getWindow());
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private static native void nCreateMouse(int window_mode);
|
}
|
||||||
|
|
||||||
public void destroyMouse() {
|
public void destroyMouse() {
|
||||||
lockAWT();
|
mouse = null;
|
||||||
nDestroyMouse();
|
|
||||||
unlockAWT();
|
|
||||||
}
|
}
|
||||||
private static native void nDestroyMouse();
|
|
||||||
|
|
||||||
public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) {
|
public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) {
|
||||||
update();
|
update();
|
||||||
lockAWT();
|
lockAWT();
|
||||||
nPollMouse(coord_buffer, buttons);
|
try {
|
||||||
|
mouse.poll(grab, coord_buffer, buttons);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private static native void nPollMouse(IntBuffer coord_buffer, ByteBuffer buttons);
|
}
|
||||||
|
|
||||||
public int readMouse(IntBuffer buffer) {
|
public int readMouse(IntBuffer buffer) {
|
||||||
update();
|
update();
|
||||||
lockAWT();
|
lockAWT();
|
||||||
int count = nReadMouse(buffer, buffer.position());
|
try {
|
||||||
|
return mouse.read(buffer);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
private static native int nReadMouse(IntBuffer buffer, int buffer_position);
|
}
|
||||||
|
|
||||||
public void setCursorPosition(int x, int y) {
|
public void setCursorPosition(int x, int y) {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
nSetCursorPosition(x, y);
|
try {
|
||||||
|
mouse.setCursorPosition(x, y);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private native void nSetCursorPosition(int x, int y);
|
}
|
||||||
|
|
||||||
public void grabMouse(boolean grab) {
|
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();
|
lockAWT();
|
||||||
nGrabMouse(current_window_mode, grab);
|
try {
|
||||||
|
if (new_grab != grab) {
|
||||||
|
grab = new_grab;
|
||||||
|
updateInputGrab();
|
||||||
|
mouse.changeGrabbed(grab, pointer_grabbed, shouldGrab());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private static native void nGrabMouse(int window_mode, boolean grab);
|
}
|
||||||
|
|
||||||
public int getNativeCursorCapabilities() {
|
public int getNativeCursorCapabilities() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
incDisplay();
|
incDisplay();
|
||||||
int caps = nGetNativeCursorCapabilities();
|
try {
|
||||||
|
return nGetNativeCursorCapabilities();
|
||||||
|
} finally {
|
||||||
decDisplay();
|
decDisplay();
|
||||||
return caps;
|
}
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -552,19 +754,24 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
private static native int nGetNativeCursorCapabilities() throws LWJGLException;
|
private static native int nGetNativeCursorCapabilities() throws LWJGLException;
|
||||||
|
|
||||||
public void setNativeCursor(Object handle) throws LWJGLException {
|
public void setNativeCursor(Object handle) throws LWJGLException {
|
||||||
|
current_cursor = (ByteBuffer)handle;
|
||||||
lockAWT();
|
lockAWT();
|
||||||
nSetNativeCursor(handle);
|
try {
|
||||||
|
updateCursor();
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private static native void nSetNativeCursor(Object handle) throws LWJGLException;
|
}
|
||||||
|
|
||||||
public int getMinCursorSize() {
|
public int getMinCursorSize() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
incDisplay();
|
incDisplay();
|
||||||
int min_size = nGetMinCursorSize();
|
try {
|
||||||
|
return nGetMinCursorSize();
|
||||||
|
} finally {
|
||||||
decDisplay();
|
decDisplay();
|
||||||
return min_size;
|
}
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
LWJGLUtil.log("Exception occurred in getMinCursorSize: " + e);
|
LWJGLUtil.log("Exception occurred in getMinCursorSize: " + e);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -578,9 +785,11 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
incDisplay();
|
incDisplay();
|
||||||
int max_size = nGetMaxCursorSize();
|
try {
|
||||||
|
return nGetMaxCursorSize();
|
||||||
|
} finally {
|
||||||
decDisplay();
|
decDisplay();
|
||||||
return max_size;
|
}
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
LWJGLUtil.log("Exception occurred in getMaxCursorSize: " + e);
|
LWJGLUtil.log("Exception occurred in getMaxCursorSize: " + e);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -594,36 +803,41 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
public void createKeyboard() throws LWJGLException {
|
public void createKeyboard() throws LWJGLException {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
nCreateKeyboard(current_window_mode);
|
keyboard = new LinuxKeyboard(getDisplay(), getWindow());
|
||||||
} finally {
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static native void nCreateKeyboard(int window_mode) throws LWJGLException;
|
|
||||||
|
|
||||||
public void destroyKeyboard() {
|
public void destroyKeyboard() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
nDestroyKeyboard();
|
try {
|
||||||
|
keyboard.destroy();
|
||||||
|
keyboard = null;
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private static native void nDestroyKeyboard();
|
}
|
||||||
|
|
||||||
public void pollKeyboard(ByteBuffer keyDownBuffer) {
|
public void pollKeyboard(ByteBuffer keyDownBuffer) {
|
||||||
update();
|
update();
|
||||||
lockAWT();
|
lockAWT();
|
||||||
nPollKeyboard(keyDownBuffer);
|
try {
|
||||||
|
keyboard.poll(keyDownBuffer);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
private static native void nPollKeyboard(ByteBuffer keyDownBuffer);
|
}
|
||||||
|
|
||||||
public int readKeyboard(IntBuffer buffer) {
|
public int readKeyboard(IntBuffer buffer) {
|
||||||
update();
|
update();
|
||||||
lockAWT();
|
lockAWT();
|
||||||
int count = nReadKeyboard(buffer, buffer.position());
|
try {
|
||||||
|
return keyboard.read(buffer);
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
private static native int nReadKeyboard(IntBuffer buffer, int buffer_position);
|
}
|
||||||
|
|
||||||
/* public int isStateKeySet(int key) {
|
/* public int isStateKeySet(int key) {
|
||||||
return Keyboard.STATE_UNKNOWN;
|
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 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 {
|
public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
|
@ -648,19 +867,24 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
|
|
||||||
public void destroyCursor(Object cursorHandle) {
|
public void destroyCursor(Object cursorHandle) {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
|
try {
|
||||||
nDestroyCursor(cursorHandle);
|
nDestroyCursor(cursorHandle);
|
||||||
decDisplay();
|
decDisplay();
|
||||||
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static native void nDestroyCursor(Object cursorHandle);
|
private static native void nDestroyCursor(Object cursorHandle);
|
||||||
|
|
||||||
public int getPbufferCapabilities() {
|
public int getPbufferCapabilities() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
incDisplay();
|
incDisplay();
|
||||||
int caps = nGetPbufferCapabilities();
|
try {
|
||||||
|
return nGetPbufferCapabilities();
|
||||||
|
} finally {
|
||||||
decDisplay();
|
decDisplay();
|
||||||
return caps;
|
}
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
LWJGLUtil.log("Exception occurred in getPbufferCapabilities: " + e);
|
LWJGLUtil.log("Exception occurred in getPbufferCapabilities: " + e);
|
||||||
return 0;
|
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -119,66 +119,6 @@ void printfDebug(const char *format, ...) {
|
||||||
va_end(ap);
|
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) {
|
static void throwFormattedGeneralException(JNIEnv * env, const char *exception_name, const char *format, va_list ap) {
|
||||||
jclass cls;
|
jclass cls;
|
||||||
jstring str;
|
jstring str;
|
||||||
|
@ -361,3 +301,17 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||||
|
|
||||||
JNIEXPORT void JNICALL JNI_OnUnload(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;
|
||||||
|
}
|
||||||
|
|
|
@ -44,16 +44,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define EVENT_BUFFER_SIZE 256
|
|
||||||
#define ATTRIB_LIST_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 {
|
typedef struct {
|
||||||
int current_index;
|
int current_index;
|
||||||
int attribs[ATTRIB_LIST_SIZE];
|
int attribs[ATTRIB_LIST_SIZE];
|
||||||
|
@ -135,9 +127,6 @@ extern void putAttrib(attrib_list_t *list, int attrib);
|
||||||
|
|
||||||
extern bool isDebugEnabled(void);
|
extern bool isDebugEnabled(void);
|
||||||
extern jstring getVersionString(JNIEnv *env);
|
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 throwGeneralException(JNIEnv * env, const char *exception_name, const char * err);
|
||||||
extern void throwException(JNIEnv *env, const char *msg);
|
extern void throwException(JNIEnv *env, const char *msg);
|
||||||
extern void throwFormattedException(JNIEnv * env, const char *format, ...);
|
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 char * GetStringNativeChars(JNIEnv *env, jstring jstr);
|
||||||
extern jstring NewStringNative(JNIEnv *env, const char *str);
|
extern jstring NewStringNative(JNIEnv *env, const char *str);
|
||||||
extern jobject newJavaManagedByteBuffer(JNIEnv *env, const int size);
|
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 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);
|
extern bool ext_InitializeFunctions(ExtGetProcAddressPROC gpa, int num_functions, ExtFunction *functions);
|
||||||
|
|
|
@ -51,19 +51,6 @@
|
||||||
|
|
||||||
extern bool checkXError(JNIEnv *, Display *);
|
extern bool checkXError(JNIEnv *, Display *);
|
||||||
extern Atom getWarpAtom(void);
|
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
|
* get the current display
|
||||||
|
@ -80,14 +67,4 @@
|
||||||
*/
|
*/
|
||||||
extern Window getCurrentWindow(void);
|
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_ */
|
#endif /* _LWJGL_WINDOW_H_INCLUDED_ */
|
||||||
|
|
|
@ -408,15 +408,16 @@ JNIEXPORT jobjectArray JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetAvailableD
|
||||||
return getAvailableDisplayModes(env, getDisplay(), getCurrentScreen(), extension);
|
return getAvailableDisplayModes(env, getDisplay(), getCurrentScreen(), extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSwitchDisplayMode(JNIEnv *env, jclass clazz, jint extension, jobject mode) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSwitchDisplayMode(JNIEnv *env, jclass clazz, jint screen, jint extension, jobject mode) {
|
||||||
switchDisplayMode(env, getCurrentScreen(), extension, mode);
|
switchDisplayMode(env, screen, extension, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetGammaRampLength(JNIEnv *env, jclass clazz) {
|
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetGammaRampLength(JNIEnv *env, jclass clazz, jlong display_ptr, jint screen) {
|
||||||
return (jint)getGammaRampLengthOfDisplay(env, getDisplay(), getCurrentScreen());
|
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) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetGammaRamp(JNIEnv *env, jclass clazz, jint screen, jobject gamma_buffer) {
|
||||||
setGammaRamp(env, getCurrentScreen(), gamma_buffer);
|
setGammaRamp(env, screen, gamma_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 <elias_naur@users.sourceforge.net>
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <X11/X.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <iconv.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#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);
|
|
||||||
}
|
|
|
@ -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 <elias_naur@users.sourceforge.net>
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <X11/X.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/extensions/xf86vmode.h>
|
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#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);
|
|
||||||
}
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/extensions/xf86vmode.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -78,11 +79,8 @@ static Pixmap current_icon_pixmap;
|
||||||
|
|
||||||
static Visual *current_visual;
|
static Visual *current_visual;
|
||||||
|
|
||||||
static bool input_released;
|
|
||||||
|
|
||||||
static bool dirty;
|
static bool dirty;
|
||||||
static bool minimized;
|
static bool minimized;
|
||||||
static bool focused;
|
|
||||||
static bool closerequested;
|
static bool closerequested;
|
||||||
static bool grab;
|
static bool grab;
|
||||||
|
|
||||||
|
@ -151,27 +149,17 @@ static void waitMapped(Window win) {
|
||||||
} while ((event.type != MapNotify) || (event.xmap.event != win));
|
} while ((event.type != MapNotify) || (event.xmap.event != win));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateInputGrab(jint window_mode) {
|
static void __attribute__ ((destructor)) my_fini(void) {
|
||||||
updatePointerGrab(window_mode);
|
|
||||||
updateKeyboardGrab(window_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setRepeatMode(JNIEnv *env, int mode) {
|
|
||||||
XKeyboardControl repeat_mode;
|
|
||||||
repeat_mode.auto_repeat_mode = mode;
|
|
||||||
Display *disp = XOpenDisplay(NULL);
|
Display *disp = XOpenDisplay(NULL);
|
||||||
if (disp == NULL && env != NULL) {
|
if (disp == NULL) {
|
||||||
printfDebugJava(env, "Could not open display to set repeat mode");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
XKeyboardControl repeat_mode;
|
||||||
|
repeat_mode.auto_repeat_mode = AutoRepeatModeDefault;
|
||||||
XChangeKeyboardControl(disp, KBAutoRepeatMode, &repeat_mode);
|
XChangeKeyboardControl(disp, KBAutoRepeatMode, &repeat_mode);
|
||||||
XCloseDisplay(disp);
|
XCloseDisplay(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__ ((destructor)) my_fini(void) {
|
|
||||||
setRepeatMode(NULL, AutoRepeatModeDefault);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setDecorations(int dec) {
|
static void setDecorations(int dec) {
|
||||||
Atom motif_hints_atom = XInternAtom(getDisplay(), "_MOTIF_WM_HINTS", False);
|
Atom motif_hints_atom = XInternAtom(getDisplay(), "_MOTIF_WM_HINTS", False);
|
||||||
MotifWmHints motif_hints;
|
MotifWmHints motif_hints;
|
||||||
|
@ -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));
|
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) {
|
static bool isLegacyFullscreen(jint window_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) {
|
|
||||||
return window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_LEGACY;
|
return window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_LEGACY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldGrab(void) {
|
static void handleMessages(JNIEnv *env, jclass disp_class) {
|
||||||
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) {
|
|
||||||
XEvent event;
|
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);
|
XNextEvent(getDisplay(), &event);
|
||||||
if (XFilterEvent(&event, None) == True)
|
if (XFilterEvent(&event, None) == True)
|
||||||
continue;
|
continue;
|
||||||
|
@ -254,7 +196,7 @@ static void handleMessages(JNIEnv *env, jint extension, jint window_mode, jobjec
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
if (event.xclient.message_type == warp_atom) {
|
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))
|
} else if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom))
|
||||||
closerequested = true;
|
closerequested = true;
|
||||||
break;
|
break;
|
||||||
|
@ -269,22 +211,19 @@ static void handleMessages(JNIEnv *env, jint extension, jint window_mode, jobjec
|
||||||
case Expose:
|
case Expose:
|
||||||
dirty = true;
|
dirty = true;
|
||||||
break;
|
break;
|
||||||
case ButtonPress:
|
case ButtonPress: /* Fall through */
|
||||||
handleButtonPress(&(event.xbutton));
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
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;
|
break;
|
||||||
case MotionNotify:
|
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;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
case KeyRelease:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkInput(env, extension, window_mode, saved_gamma, current_gamma, saved_mode, current_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setWindowTitle(const char *title) {
|
static void setWindowTitle(const char *title) {
|
||||||
|
@ -332,7 +271,6 @@ static void destroyWindow(JNIEnv *env) {
|
||||||
XDestroyWindow(getDisplay(), current_win);
|
XDestroyWindow(getDisplay(), current_win);
|
||||||
XFreeColormap(getDisplay(), cmap);
|
XFreeColormap(getDisplay(), cmap);
|
||||||
freeIconPixmap();
|
freeIconPixmap();
|
||||||
setRepeatMode(env, AutoRepeatModeDefault);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isNetWMFullscreenSupported(JNIEnv *env) {
|
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) {
|
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");
|
bool undecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated");
|
||||||
dirty = true;
|
dirty = true;
|
||||||
focused = true;
|
|
||||||
minimized = false;
|
minimized = false;
|
||||||
closerequested = false;
|
closerequested = false;
|
||||||
grab = false;
|
grab = false;
|
||||||
|
@ -380,7 +317,6 @@ static bool createWindow(JNIEnv* env, jint window_mode, X11PeerInfo *peer_info,
|
||||||
XSetWindowAttributes attribs;
|
XSetWindowAttributes attribs;
|
||||||
int attribmask;
|
int attribmask;
|
||||||
|
|
||||||
input_released = false;
|
|
||||||
root_win = RootWindow(getDisplay(), getCurrentScreen());
|
root_win = RootWindow(getDisplay(), getCurrentScreen());
|
||||||
XVisualInfo *vis_info = getVisualInfoFromPeerInfo(env, peer_info);
|
XVisualInfo *vis_info = getVisualInfoFromPeerInfo(env, peer_info);
|
||||||
if (vis_info == NULL)
|
if (vis_info == NULL)
|
||||||
|
@ -429,7 +365,6 @@ static bool createWindow(JNIEnv* env, jint window_mode, X11PeerInfo *peer_info,
|
||||||
XMapRaised(getDisplay(), win);
|
XMapRaised(getDisplay(), win);
|
||||||
waitMapped(win);
|
waitMapped(win);
|
||||||
XClearWindow(getDisplay(), win);
|
XClearWindow(getDisplay(), win);
|
||||||
setRepeatMode(env, AutoRepeatModeOff);
|
|
||||||
if (!checkXError(env, getDisplay())) {
|
if (!checkXError(env, getDisplay())) {
|
||||||
destroyWindow(env);
|
destroyWindow(env);
|
||||||
return false;
|
return false;
|
||||||
|
@ -444,7 +379,7 @@ Window getCurrentWindow(void) {
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUpdate
|
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)
|
(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) {
|
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;
|
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) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nLockAWT(JNIEnv *env, jclass clazz) {
|
||||||
JAWT jawt;
|
JAWT jawt;
|
||||||
jawt.version = JAWT_VERSION_1_4;
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 <elias_naur@users.sourceforge.net>
|
||||||
|
* @version $Revision: 2399 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -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 <elias_naur@users.sourceforge.net>
|
||||||
|
* @version $Revision: 2399 $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#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);
|
||||||
|
}
|
|
@ -61,17 +61,3 @@ HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const
|
||||||
return should_continue == JNI_TRUE ? true : false;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,5 @@ typedef struct {
|
||||||
} enum_context_t;
|
} enum_context_t;
|
||||||
|
|
||||||
HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const char *tszName);
|
HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const char *tszName);
|
||||||
bool positionBuffer(JNIEnv *env, jobject buffer, jint position);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue