Implement Resizing API for Linux.

This commit is contained in:
kappa1 2011-10-02 20:41:33 +00:00
parent 804f569268
commit b2c1002b84
3 changed files with 144 additions and 32 deletions

View File

@ -141,7 +141,12 @@ final class LinuxDisplay implements DisplayImplementation {
private long current_cursor;
private long blank_cursor;
private boolean mouseInside = true;
private boolean resizable;
private boolean resized;
private int window_width;
private int window_height;
private Canvas parent;
private long parent_window;
private static boolean xembedded;
@ -461,7 +466,11 @@ final class LinuxDisplay implements DisplayImplementation {
boolean undecorated = Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated") || (current_window_mode != WINDOWED && Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated_fs"));
this.parent = parent;
parent_window = parent != null ? getHandle(parent) : getRootWindow(getDisplay(), getDefaultScreen());
current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window);
resizable = Display.isResizable();
resized = false;
window_width = mode.getWidth();
window_height = mode.getHeight();
current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window, resizable);
mapRaised(getDisplay(), current_window);
xembedded = parent != null && isAncestorXEmbedded(parent_window);
blank_cursor = createBlankCursor();
@ -495,7 +504,7 @@ final class LinuxDisplay implements DisplayImplementation {
unlockAWT();
}
}
private static native long nCreateWindow(long display, int screen, ByteBuffer peer_info_handle, DisplayMode mode, int window_mode, int x, int y, boolean undecorated, long parent_handle) throws LWJGLException;
private static native long nCreateWindow(long display, int screen, ByteBuffer peer_info_handle, DisplayMode mode, int window_mode, int x, int y, boolean undecorated, long parent_handle, boolean resizable) throws LWJGLException;
private static native long getRootWindow(long display, int screen);
private static native boolean hasProperty(long display, long window, long property);
private static native long getParentWindow(long display, long window) throws LWJGLException;
@ -504,6 +513,9 @@ final class LinuxDisplay implements DisplayImplementation {
private static native void reparentWindow(long display, long window, long parent, int x, int y);
private static native long nGetInputFocus(long display) throws LWJGLException;
private static native void nSetInputFocus(long display, long window, long time);
private static native void nSetWindowSize(long display, long window, int width, int height, boolean resizable);
private static native int nGetWidth(long display, long window);
private static native int nGetHeight(long display, long window);
private static boolean isAncestorXEmbedded(long window) throws LWJGLException {
long xembed_atom = internAtom("_XEMBED_INFO", true);
@ -823,6 +835,16 @@ final class LinuxDisplay implements DisplayImplementation {
break;
case LinuxEvent.Expose:
dirty = true;
int width = nGetWidth(getDisplay(), getWindow());
int height = nGetHeight(getDisplay(), getWindow());
if (window_width != width || window_height != height) {
resized = true;
window_width = width;
window_height = height;
}
break;
case LinuxEvent.EnterNotify:
mouseInside = true;
@ -1346,11 +1368,11 @@ final class LinuxDisplay implements DisplayImplementation {
private static native void nSetWindowIcon(long display, long window, ByteBuffer icon_rgb, int icon_rgb_size, ByteBuffer icon_mask, int icon_mask_size, int width, int height);
public int getWidth() {
return Display.getDisplayMode().getWidth();
return window_width;
}
public int getHeight() {
return Display.getDisplayMode().getHeight();
return window_height;
}
public boolean isInsideWindow() {
@ -1358,10 +1380,20 @@ final class LinuxDisplay implements DisplayImplementation {
}
public void setResizable(boolean resizable) {
if (this.resizable == resizable) {
return;
}
this.resizable = resizable;
nSetWindowSize(getDisplay(), getWindow(), window_width, window_height, resizable);
}
public boolean wasResized() {
if (resized) {
resized = false;
return true;
}
return false;
}

View File

@ -278,6 +278,26 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getRootWindow(JNIEnv
return RootWindow(disp, screen);
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetWidth(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display_ptr;
Window win = (Window)window_ptr;
XWindowAttributes win_attribs;
XGetWindowAttributes(disp, win, &win_attribs);
return win_attribs.width;
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetHeight(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display_ptr;
Window win = (Window)window_ptr;
XWindowAttributes win_attribs;
XGetWindowAttributes(disp, win, &win_attribs);
return win_attribs.height;
}
static void updateWindowHints(JNIEnv *env, Display *disp, Window window) {
XWMHints* win_hints = XAllocWMHints();
if (win_hints == NULL) {
@ -301,7 +321,28 @@ static void updateWindowHints(JNIEnv *env, Display *disp, Window window) {
XFlush(disp);
}
static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_mode, X11PeerInfo *peer_info, int x, int y, int width, int height, jboolean undecorated, long parent_handle) {
static void updateWindowBounds(Display *disp, Window win, int x, int y, int width, int height, jboolean position, jboolean resizable) {
XSizeHints *window_hints = XAllocSizeHints();
if (position) {
window_hints->flags |= PPosition;
window_hints->x = x;
window_hints->y = y;
}
if (!resizable) {
window_hints->flags |= PMinSize | PMaxSize;
window_hints->min_width = width;
window_hints->max_width = width;
window_hints->min_height = height;
window_hints->max_height = height;
}
XSetWMNormalHints(disp, win, window_hints);
XFree(window_hints);
}
static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_mode, X11PeerInfo *peer_info, int x, int y, int width, int height, jboolean undecorated, long parent_handle, jboolean resizable) {
Window parent = (Window)parent_handle;
Window win;
XSetWindowAttributes attribs;
@ -334,17 +375,10 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
// Use Motif decoration hint property and hope the window manager respects them
setDecorations(disp, win, 0);
}
XSizeHints * window_hints = XAllocSizeHints();
window_hints->flags = PPosition | PMinSize | PMaxSize;
window_hints->x = x;
window_hints->y = y;
window_hints->min_width = width;
window_hints->max_width = width;
window_hints->min_height = height;
window_hints->max_height = height;
XSetWMNormalHints(disp, win, window_hints);
updateWindowBounds(disp, win, x, y, width, height, JNI_TRUE, resizable);
updateWindowHints(env, disp, win);
XFree(window_hints);
#define NUM_ATOMS 1
Atom protocol_atoms[NUM_ATOMS] = {XInternAtom(disp, "WM_DELETE_WINDOW", False)/*, XInternAtom(disp, "WM_TAKE_FOCUS", False)*/};
XSetWMProtocols(disp, win, protocol_atoms, NUM_ATOMS);
@ -437,7 +471,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetInputFocus(JNIEnv
XSetInputFocus(disp, window, RevertToParent, time);
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *env, jclass clazz, jlong display, jint screen, jobject peer_info_handle, jobject mode, jint window_mode, jint x, jint y, jboolean undecorated, jlong parent_handle) {
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *env, jclass clazz, jlong display, jint screen, jobject peer_info_handle, jobject mode, jint window_mode, jint x, jint y, jboolean undecorated, jlong parent_handle, jboolean resizable) {
Display *disp = (Display *)(intptr_t)display;
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
GLXFBConfig *fb_config = NULL;
@ -451,7 +485,7 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv
jfieldID fid_height = (*env)->GetFieldID(env, cls_displayMode, "height", "I");
int width = (*env)->GetIntField(env, mode, fid_width);
int height = (*env)->GetIntField(env, mode, fid_height);
Window win = createWindow(env, disp, screen, window_mode, peer_info, x, y, width, height, undecorated, parent_handle);
Window win = createWindow(env, disp, screen, window_mode, peer_info, x, y, width, height, undecorated, parent_handle, resizable);
if ((*env)->ExceptionOccurred(env)) {
return 0;
}
@ -466,6 +500,12 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv
return win;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetWindowSize(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr, jint width, jint height, jboolean resizable) {
Display *disp = (Display *)(intptr_t)display;
Window win = (Window)window_ptr;
updateWindowBounds(disp, win, 0, 0, width, height, JNI_FALSE, resizable);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nDestroyWindow(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display;
Window window = (Window)window_ptr;

View File

@ -268,6 +268,26 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getRootWindow(JNIEnv
return RootWindow(disp, screen);
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetWidth(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display_ptr;
Window win = (Window)window_ptr;
XWindowAttributes win_attribs;
XGetWindowAttributes(disp, win, &win_attribs);
return win_attribs.width;
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetHeight(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display_ptr;
Window win = (Window)window_ptr;
XWindowAttributes win_attribs;
XGetWindowAttributes(disp, win, &win_attribs);
return win_attribs.height;
}
static void updateWindowHints(JNIEnv *env, Display *disp, Window window) {
XWMHints* win_hints = XAllocWMHints();
if (win_hints == NULL) {
@ -291,7 +311,28 @@ static void updateWindowHints(JNIEnv *env, Display *disp, Window window) {
XFlush(disp);
}
static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_mode, X11PeerInfo *peer_info, int x, int y, int width, int height, jboolean undecorated, long parent_handle) {
static void updateWindowBounds(Display *disp, Window win, int x, int y, int width, int height, jboolean position, jboolean resizable) {
XSizeHints *window_hints = XAllocSizeHints();
if (position) {
window_hints->flags |= PPosition;
window_hints->x = x;
window_hints->y = y;
}
if (!resizable) {
window_hints->flags |= PMinSize | PMaxSize;
window_hints->min_width = width;
window_hints->max_width = width;
window_hints->min_height = height;
window_hints->max_height = height;
}
XSetWMNormalHints(disp, win, window_hints);
XFree(window_hints);
}
static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_mode, X11PeerInfo *peer_info, int x, int y, int width, int height, jboolean undecorated, long parent_handle, jboolean resizable) {
Window parent = (Window)parent_handle;
Window win;
XSetWindowAttributes attribs;
@ -328,17 +369,10 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
// Use Motif decoration hint property and hope the window manager respects them
setDecorations(disp, win, 0);
}
XSizeHints * window_hints = XAllocSizeHints();
window_hints->flags = PPosition | PMinSize | PMaxSize;
window_hints->x = x;
window_hints->y = y;
window_hints->min_width = width;
window_hints->max_width = width;
window_hints->min_height = height;
window_hints->max_height = height;
XSetWMNormalHints(disp, win, window_hints);
updateWindowBounds(disp, win, x, y, width, height, JNI_TRUE, resizable);
updateWindowHints(env, disp, win);
XFree(window_hints);
#define NUM_ATOMS 1
Atom protocol_atoms[NUM_ATOMS] = {XInternAtom(disp, "WM_DELETE_WINDOW", False)/*, XInternAtom(disp, "WM_TAKE_FOCUS", False)*/};
XSetWMProtocols(disp, win, protocol_atoms, NUM_ATOMS);
@ -431,7 +465,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetInputFocus(JNIEnv
XSetInputFocus(disp, window, RevertToParent, time);
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *env, jclass clazz, jlong display, jint screen, jobject peer_info_handle, jobject mode, jint window_mode, jint x, jint y, jboolean undecorated, jlong parent_handle) {
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv *env, jclass clazz, jlong display, jint screen, jobject peer_info_handle, jobject mode, jint window_mode, jint x, jint y, jboolean undecorated, jlong parent_handle, jboolean resizable) {
Display *disp = (Display *)(intptr_t)display;
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
@ -443,7 +477,7 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv
int width = (*env)->GetIntField(env, mode, fid_width);
int height = (*env)->GetIntField(env, mode, fid_height);
Window win = createWindow(env, disp, screen, window_mode, peer_info, x, y, width, height, undecorated, parent_handle);
Window win = createWindow(env, disp, screen, window_mode, peer_info, x, y, width, height, undecorated, parent_handle, resizable);
if ((*env)->ExceptionOccurred(env))
return 0;
@ -454,6 +488,12 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nCreateWindow(JNIEnv
return win;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetWindowSize(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr, jint width, jint height, jboolean resizable) {
Display *disp = (Display *)(intptr_t)display;
Window win = (Window)window_ptr;
updateWindowBounds(disp, win, 0, 0, width, height, JNI_FALSE, resizable);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nDestroyWindow(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display;
Window window = (Window)window_ptr;