Added experimental Display.setParent to allow Display to be embedded in an AWT Canvas. Added basic linux implementation and test.

This commit is contained in:
Elias Naur 2008-04-06 20:56:52 +00:00
parent 350c3c2661
commit c499f33bcf
16 changed files with 282 additions and 59 deletions

View File

@ -33,7 +33,7 @@ package org.lwjgl.opengl;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Component;
import java.awt.Canvas;
import org.lwjgl.LWJGLException;
@ -47,7 +47,7 @@ interface AWTCanvasImplementation {
/**
* Return an opaque handle to the canvas peer information required to create a context from it.
*/
PeerInfo createPeerInfo(Component component, PixelFormat pixel_format) throws LWJGLException;
PeerInfo createPeerInfo(Canvas component, PixelFormat pixel_format) throws LWJGLException;
/**
* Find a proper GraphicsConfiguration from the given GraphicsDevice and PixelFormat.

View File

@ -31,7 +31,7 @@
*/
package org.lwjgl.opengl;
import java.awt.Component;
import java.awt.Canvas;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedActionException;
@ -60,7 +60,7 @@ final class AWTSurfaceLock {
private static native ByteBuffer createHandle();
public ByteBuffer lockAndGetHandle(Component component) throws LWJGLException {
public ByteBuffer lockAndGetHandle(Canvas component) throws LWJGLException {
while (!privilegedLockAndInitHandle(component)) {
LWJGLUtil.log("Could not get drawing surface info, retrying...");
try {
@ -73,12 +73,12 @@ final class AWTSurfaceLock {
return lock_buffer;
}
private boolean privilegedLockAndInitHandle(final Component component) throws LWJGLException {
private boolean privilegedLockAndInitHandle(final Canvas component) throws LWJGLException {
// Workaround for Sun JDK bug 4796548 which still exists in java for OS X
// We need to elevate privileges because of an AWT bug. Please see
// http://192.18.37.44/forums/index.php?topic=10572 for a discussion.
// It is only needed on first call, so we avoid it on all subsequent calls
// due to performance.
// due to performance.
if (firstLockSucceeded)
return lockAndInitHandle(lock_buffer, component);
else
@ -96,7 +96,7 @@ final class AWTSurfaceLock {
}
}
private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Component component) throws LWJGLException;
private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas component) throws LWJGLException;
protected void unlock() throws LWJGLException {
nUnlock(lock_buffer);

View File

@ -49,6 +49,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashSet;
import java.awt.Canvas;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
@ -71,6 +72,9 @@ public final class Display {
/** The initial display mode */
private static final DisplayMode initial_mode;
/** The parent, if any */
private static Canvas parent;
/** The current display mode, if created */
private static DisplayMode current_mode;
@ -244,7 +248,7 @@ public final class Display {
}
int window_x;
int window_y;
if (!fullscreen) {
if (!fullscreen && parent == null) {
// if no display location set, center window
if (x == -1 && y == -1) {
window_x = Math.max(0, (initial_mode.getWidth() - current_mode.getWidth()) / 2);
@ -257,7 +261,10 @@ public final class Display {
window_x = 0;
window_y = 0;
}
display_impl.createWindow(current_mode, fullscreen, window_x, window_y);
Canvas tmp_parent = fullscreen ? null : parent;
if (tmp_parent != null && !tmp_parent.isDisplayable()) // Only a best effort check, since the parent can turn undisplayable hereafter
throw new LWJGLException("Parent.isDisplayable() must be true");
display_impl.createWindow(current_mode, fullscreen, tmp_parent, window_x, window_y);
window_created = true;
setTitle(title);
@ -464,6 +471,50 @@ public final class Display {
}
}
/**
* Return the last parent set with setParent().
*/
public static Canvas getParent() {
synchronized (GlobalLock.lock) {
return parent;
}
}
/**
* Set the parent of the Display. If parent is null, the Display will appear as a top level window.
* If parent is not null, the Display is made a child of the parent. A parent's isDisplayable() must be true when
* setParent() is called and remain true until setParent() is called again with
* null or a different parent. This generally means that the parent component must remain added to it's parent container.<p>
* It is not advisable to call this method from an AWT thread, since the context will be made current on the thread
* and it is difficult to predict which AWT thread will process any given AWT event.<p>
* If the Display is in fullscreen mode, the current parent will be ignored.
*
*/
public static void setParent(Canvas parent) throws LWJGLException {
synchronized (GlobalLock.lock) {
if (Display.parent != parent) {
Display.parent = parent;
if (!isCreated())
return;
destroyWindow();
try {
if (fullscreen) {
switchDisplayMode();
} else {
display_impl.resetDisplayMode();
}
createWindow();
makeCurrentAndSetSwapInterval();
} catch (LWJGLException e) {
destroyContext();
destroyPeerInfo();
display_impl.resetDisplayMode();
throw e;
}
}
}
}
/**
* Set the fullscreen mode of the context. If no context has been created through create(),
* the mode will apply when create() is called. If fullscreen is true, the context will become
@ -914,7 +965,7 @@ public final class Display {
}
/**
* Set the window's location. This is a no-op on fullscreen windows.
* Set the window's location. This is a no-op on fullscreen windows or when getParent() != null.
* The window is clamped to remain entirely on the screen. If you attempt
* to position the window such that it would extend off the screen, the window
* is simply placed as close to the edge as possible.

View File

@ -41,12 +41,13 @@ package org.lwjgl.opengl;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.awt.Canvas;
import org.lwjgl.LWJGLException;
interface DisplayImplementation extends InputImplementation {
void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException;
void createWindow(DisplayMode mode, boolean fullscreen, Canvas parent, int x, int y) throws LWJGLException;
void destroyWindow();

View File

@ -35,7 +35,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import java.awt.Component;
import java.awt.Canvas;
/**
*
@ -44,11 +44,11 @@ import java.awt.Component;
* $Id$
*/
final class LinuxAWTGLCanvasPeerInfo extends LinuxPeerInfo {
private final Component component;
private final Canvas component;
private final AWTSurfaceLock awt_surface = new AWTSurfaceLock();
private int screen = -1;
public LinuxAWTGLCanvasPeerInfo(Component component) {
public LinuxAWTGLCanvasPeerInfo(Canvas component) {
this.component = component;
}

View File

@ -33,7 +33,7 @@ package org.lwjgl.opengl;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Component;
import java.awt.Canvas;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
@ -76,7 +76,7 @@ final class LinuxCanvasImplementation implements AWTCanvasImplementation {
}
}
public PeerInfo createPeerInfo(Component component, PixelFormat pixel_format) throws LWJGLException {
public PeerInfo createPeerInfo(Canvas component, PixelFormat pixel_format) throws LWJGLException {
return new LinuxAWTGLCanvasPeerInfo(component);
}

View File

@ -42,6 +42,8 @@ import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.awt.Canvas;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
@ -103,6 +105,7 @@ final class LinuxDisplay implements DisplayImplementation {
private boolean focused_at_least_once;
private long current_cursor;
private long blank_cursor;
private Canvas parent;
private LinuxKeyboard keyboard;
private LinuxMouse mouse;
@ -357,7 +360,7 @@ final class LinuxDisplay implements DisplayImplementation {
ungrabKeyboard();
}
public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException {
public void createWindow(DisplayMode mode, boolean fullscreen, Canvas parent, int x, int y) throws LWJGLException {
lockAWT();
try {
incDisplay();
@ -365,7 +368,10 @@ final class LinuxDisplay implements DisplayImplementation {
ByteBuffer handle = peer_info.lockAndGetHandle();
try {
current_window_mode = getWindowMode(fullscreen);
current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y);
boolean undecorated = Display.getPrivilegedBoolean("org.lwjgl.opengl.Window.undecorated") || current_window_mode != WINDOWED;
this.parent = parent;
long parent_window = parent != null ? getHandle(parent) : getRootWindow(getDisplay(), getDefaultScreen());
current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window);
blank_cursor = createBlankCursor();
current_cursor = None;
focused = true;
@ -388,7 +394,19 @@ 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) 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) throws LWJGLException;
private static native long getRootWindow(long display, int screen);
private static long getHandle(Canvas parent) throws LWJGLException {
AWTCanvasImplementation awt_impl = AWTGLCanvas.createImplementation();
LinuxPeerInfo parent_peer_info = (LinuxPeerInfo)awt_impl.createPeerInfo(parent, null);
ByteBuffer parent_peer_info_handle = parent_peer_info.lockAndGetHandle();
try {
return parent_peer_info.getDrawable();
} finally {
parent_peer_info.unlock();
}
}
private void updateInputGrab() {
updatePointerGrab();
@ -602,7 +620,11 @@ final class LinuxDisplay implements DisplayImplementation {
return peer_info;
}
private native static void setInputFocus(long display, long window);
private void processEvents() {
if (!focused && parent != null && parent.isFocusOwner())
setInputFocus(getDisplay(), getWindow());
while (LinuxEvent.getPending(getDisplay()) > 0) {
event_buffer.nextEvent(getDisplay());
long event_window = event_buffer.getWindow();

View File

@ -33,7 +33,7 @@ package org.lwjgl.opengl;
import org.lwjgl.LWJGLException;
import java.awt.Component;
import java.awt.Canvas;
/**
*
@ -42,9 +42,9 @@ import java.awt.Component;
* $Id$
*/
final class MacOSXAWTGLCanvasPeerInfo extends MacOSXCanvasPeerInfo {
private final Component component;
private final Canvas component;
public MacOSXAWTGLCanvasPeerInfo(Component component, PixelFormat pixel_format, boolean support_pbuffer) throws LWJGLException {
public MacOSXAWTGLCanvasPeerInfo(Canvas component, PixelFormat pixel_format, boolean support_pbuffer) throws LWJGLException {
super(pixel_format, support_pbuffer);
this.component = component;
}

View File

@ -33,7 +33,7 @@ package org.lwjgl.opengl;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Component;
import java.awt.Canvas;
import org.lwjgl.LWJGLException;
@ -44,7 +44,7 @@ import org.lwjgl.LWJGLException;
* $Id$
*/
final class MacOSXCanvasImplementation implements AWTCanvasImplementation {
public PeerInfo createPeerInfo(Component component, PixelFormat pixel_format) throws LWJGLException {
public PeerInfo createPeerInfo(Canvas component, PixelFormat pixel_format) throws LWJGLException {
try {
return new MacOSXAWTGLCanvasPeerInfo(component, pixel_format, true);
} catch (LWJGLException e) {

View File

@ -31,7 +31,7 @@
*/
package org.lwjgl.opengl;
import java.awt.Component;
import java.awt.Canvas;
import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
@ -49,7 +49,7 @@ abstract class MacOSXCanvasPeerInfo extends MacOSXPeerInfo {
super(pixel_format, true, true, support_pbuffer, true);
}
protected void initHandle(Component component) throws LWJGLException {
protected void initHandle(Canvas component) throws LWJGLException {
nInitHandle(awt_surface.lockAndGetHandle(component), getHandle());
}
private static native void nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle) throws LWJGLException;

View File

@ -39,6 +39,7 @@ package org.lwjgl.opengl;
*/
import java.awt.Cursor;
import java.awt.Canvas;
import java.awt.Robot;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@ -73,7 +74,7 @@ final class MacOSXDisplay implements DisplayImplementation {
new MacOSXApplicationListener();
}
public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException {
public void createWindow(DisplayMode mode, boolean fullscreen, Canvas parent, int x, int y) throws LWJGLException {
hideUI(fullscreen);
close_requested = false;
try {

View File

@ -35,7 +35,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import java.awt.Component;
import java.awt.Canvas;
/**
*
@ -44,12 +44,12 @@ import java.awt.Component;
* $Id$
*/
final class WindowsAWTGLCanvasPeerInfo extends WindowsPeerInfo {
private final Component component;
private final Canvas component;
private final AWTSurfaceLock awt_surface = new AWTSurfaceLock();
private final PixelFormat pixel_format;
private boolean has_pixel_format= false;
public WindowsAWTGLCanvasPeerInfo(Component component, PixelFormat pixel_format) {
public WindowsAWTGLCanvasPeerInfo(Canvas component, PixelFormat pixel_format) {
this.component = component;
this.pixel_format = pixel_format;
}

View File

@ -34,7 +34,7 @@ package org.lwjgl.opengl;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Toolkit;
import java.awt.Component;
import java.awt.Canvas;
import java.security.PrivilegedAction;
import java.security.AccessController;
@ -70,7 +70,7 @@ final class WindowsCanvasImplementation implements AWTCanvasImplementation {
return new WindowsAWTInput(canvas);
}
public PeerInfo createPeerInfo(Component component, PixelFormat pixel_format) throws LWJGLException {
public PeerInfo createPeerInfo(Canvas component, PixelFormat pixel_format) throws LWJGLException {
return new WindowsAWTGLCanvasPeerInfo(component, pixel_format);
}

View File

@ -41,6 +41,7 @@ package org.lwjgl.opengl;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.awt.Canvas;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
@ -139,7 +140,7 @@ final class WindowsDisplay implements DisplayImplementation {
current_display = this;
}
public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException {
public void createWindow(DisplayMode mode, boolean fullscreen, Canvas container, int x, int y) throws LWJGLException {
close_requested = false;
is_dirty = false;
isFullscreen = fullscreen;

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2002-2005 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.test.opengl.awt;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Container;
import java.awt.Component;
import java.awt.Canvas;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.AWTGLCanvas;
import org.lwjgl.opengl.GL11;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
/**
* <p>
* Tests Display.setParent()
* <p>
* @version $Revision$
* @author $Author$
* $Id$
*/
public class DisplayParentTest extends Frame {
public DisplayParentTest() throws LWJGLException {
setTitle("LWJGL Display Parent Test");
setSize(640, 320);
setLayout(new GridLayout(1, 2));
final Canvas display_parent = new Canvas();
display_parent.setFocusable(true);
add(display_parent);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
setResizable(true);
setVisible(true);
Display.setParent(display_parent);
Display.create();
float angle = 0f;
int current_height = 0;
int current_width = 0;
while (isVisible()) {
angle += 1.0f;
if (getWidth() != current_width || getHeight() != current_height) {
current_width = getWidth();
current_height = getHeight();
Display.setDisplayMode(new DisplayMode(getWidth(), getHeight()));
GL11.glViewport(0, 0, current_width, current_height);
}
GL11.glViewport(0, 0, getWidth(), getHeight());
GL11.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluOrtho2D(0.0f, (float) getWidth(), 0.0f, (float) getHeight());
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
GL11.glTranslatef(getWidth() / 2.0f, getHeight() / 2.0f, 0.0f);
GL11.glRotatef(2*angle, 0f, 0f, -1.0f);
GL11.glRectf(-50.0f, -50.0f, 50.0f, 50.0f);
GL11.glPopMatrix();
Display.update();
while(Keyboard.next()) {
// closing on ESCAPE
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE && Keyboard.getEventKeyState()) {
dispose();
}
if(Keyboard.getEventKey() == Keyboard.KEY_SPACE && Keyboard.getEventKeyState()) {
Mouse.setGrabbed(!Mouse.isGrabbed());
}
}
/* while (Mouse.next()) {
System.out.println(" Mouse.getEventX() = " + Mouse.getEventX() + " | Mouse.getEventY() = " + Mouse.getEventY());
}*/
}
System.exit(0);
}
public static void main(String[] args) throws LWJGLException {
new DisplayParentTest();
}
}

View File

@ -242,18 +242,44 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nReshape(JNIEnv *env,
XMoveWindow(disp, window, x, y);
}
static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_mode, X11PeerInfo *peer_info, int x, int y, int width, int height) {
bool undecorated = getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated");
Window root_win;
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getRootWindow(JNIEnv *env, jclass clazz, jlong display, jint screen) {
Display *disp = (Display *)(intptr_t)display;
return RootWindow(disp, screen);
}
static void updateWindowHints(JNIEnv *env, Display *disp, Window window) {
XWMHints* win_hints = XAllocWMHints();
if (win_hints == NULL) {
throwException(env, "XAllocWMHints failed");
return;
}
win_hints->flags = InputHint;
win_hints->input = True;
if (current_icon_pixmap != 0) {
win_hints->flags |= IconPixmapHint;
win_hints->icon_pixmap = current_icon_pixmap;
}
if (current_icon_mask_pixmap != 0) {
win_hints->flags |= IconMaskHint;
win_hints->icon_mask = current_icon_mask_pixmap;
}
XSetWMHints(disp, window, win_hints);
XFree(win_hints);
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) {
Window parent = (Window)parent_handle;
Window win;
XSetWindowAttributes attribs;
int attribmask;
root_win = RootWindow(disp, screen);
XVisualInfo *vis_info = getVisualInfoFromPeerInfo(env, peer_info);
if (vis_info == NULL)
return false;
cmap = XCreateColormap(disp, root_win, vis_info->visual, AllocNone);
cmap = XCreateColormap(disp, parent, vis_info->visual, AllocNone);
attribs.colormap = cmap;
attribs.event_mask = ExposureMask | /*FocusChangeMask | */VisibilityChangeMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
attribmask = CWColormap | CWEventMask;
@ -261,7 +287,7 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
attribmask |= CWOverrideRedirect;
attribs.override_redirect = True;
}
win = XCreateWindow(disp, root_win, x, y, width, height, 0, vis_info->depth, InputOutput, vis_info->visual, attribmask, &attribs);
win = XCreateWindow(disp, parent, x, y, width, height, 0, vis_info->depth, InputOutput, vis_info->visual, attribmask, &attribs);
current_depth = vis_info->depth;
current_visual = vis_info->visual;
@ -271,8 +297,8 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
XFreeColormap(disp, cmap);
return false;
}
printfDebugJava(env, "Created window");
if (window_mode != org_lwjgl_opengl_LinuxDisplay_WINDOWED || undecorated) {
// printfDebugJava(env, "Created window");
if (undecorated) {
// Use Motif decoration hint property and hope the window manager respects them
setDecorations(disp, win, 0);
}
@ -283,9 +309,11 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
size_hints->min_height = height;
size_hints->max_height = height;
XSetWMNormalHints(disp, win, size_hints);
updateWindowHints(env, disp, win);
XFree(size_hints);
Atom delete_atom = XInternAtom(disp, "WM_DELETE_WINDOW", False);
XSetWMProtocols(disp, win, &delete_atom, 1);
#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);
if (window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_NETWM) {
Atom fullscreen_atom = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False);
XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_STATE", False),
@ -299,7 +327,17 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
return win;
}
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) {
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_setInputFocus(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr) {
Display *disp = (Display *)(intptr_t)display;
Window window = (Window)window_ptr;
// Normally, a real time stamp from an event should be passed instead of CurrentTime, but we don't get timestamps
// from awt. Instead we grab the server before and ungrab it after the request
XGrabServer(disp);
XSetInputFocus(disp, window, RevertToParent, CurrentTime);
XUngrabServer(disp);
}
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) {
Display *disp = (Display *)(intptr_t)display;
X11PeerInfo *peer_info = (*env)->GetDirectBufferAddress(env, peer_info_handle);
GLXFBConfig *fb_config = NULL;
@ -313,7 +351,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);
Window win = createWindow(env, disp, screen, window_mode, peer_info, x, y, width, height, undecorated, parent_handle);
if ((*env)->ExceptionOccurred(env)) {
return 0;
}
@ -384,7 +422,6 @@ static Pixmap createPixmapFromBuffer(JNIEnv *env, Display *disp, Window window,
}
static void setIcon(JNIEnv *env, Display *disp, Window window, char *rgb_data, char *mask_data, int icon_size, int width, int height) {
XWMHints* win_hints;
freeIconPixmap(disp);
current_icon_pixmap = createPixmapFromBuffer(env, disp, window, rgb_data, icon_size, width, height);
if ((*env)->ExceptionCheck(env))
@ -395,19 +432,7 @@ static void setIcon(JNIEnv *env, Display *disp, Window window, char *rgb_data, c
return;
}
win_hints = XAllocWMHints();
if (win_hints == NULL) {
throwException(env, "XAllocWMHints failed");
return;
}
win_hints->flags = IconPixmapHint | IconMaskHint;
win_hints->icon_pixmap = current_icon_pixmap;
win_hints->icon_mask = current_icon_mask_pixmap;
XSetWMHints(disp, window, win_hints);
XFree(win_hints);
XFlush(disp);
updateWindowHints(env, disp, window);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetWindowIcon