jogamp.newt.driver.x11.WindowDriver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jogl Show documentation
Show all versions of jogl Show documentation
Java™ Binding for the OpenGL® API (Atomic Jar files)
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution 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 Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
* ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
* DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
*/
package jogamp.newt.driver.x11;
import java.nio.Buffer;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.PointerIconImpl;
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.PNGIcon;
import javax.media.nativewindow.*;
import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseEvent;
public class WindowDriver extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
private static final int X11_WHEEL_ONE_UP_BUTTON = 4;
private static final int X11_WHEEL_ONE_DOWN_BUTTON = 5;
private static final int X11_WHEEL_TWO_UP_BUTTON = 6;
private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
private static final int defaultIconDataSize;
private static final Buffer defaultIconData;
static {
ScreenDriver.initSingleton();
int _icon_data_size=0, _icon_elem_bytesize=0;
Buffer _icon_data=null;
if( PNGIcon.isAvailable() ) {
try {
// NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
final int[] data_size = { 0 }, elem_bytesize = { 0 };
_icon_data = PNGIcon.arrayToX11BGRAImages(NewtFactory.getWindowIcons(), data_size, elem_bytesize);
_icon_data_size = data_size[0];
_icon_elem_bytesize = elem_bytesize[0];
} catch (final Exception e) {
e.printStackTrace();
}
}
defaultIconDataSize = _icon_data_size;
defaultIconData = _icon_data;
if(DEBUG_IMPLEMENTATION) {
System.err.println("Def. Icon: data_size "+defaultIconDataSize+" * elem_size "+_icon_elem_bytesize+" = data "+defaultIconData);
}
}
public WindowDriver() {
}
@Override
protected void createNativeImpl() {
final ScreenDriver screen = (ScreenDriver) getScreen();
final DisplayDriver display = (DisplayDriver) screen.getDisplay();
final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
// Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
final long renderDeviceHandle = X11Util.openDisplay(edtDevice.getConnection());
if( 0 == renderDeviceHandle ) {
throw new RuntimeException("Error creating display(GfxCfg/Render): "+edtDevice.getConnection());
}
renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
final AbstractGraphicsScreen renderScreen = new X11GraphicsScreen(renderDevice, screen.getIndex());
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested);
final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, renderScreen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
final int visualID = cfg.getVisualID(VIDType.NATIVE);
if(VisualIDHolder.VID_UNDEFINED == visualID) {
throw new NativeWindowException("Chosen Configuration w/o native visual ID: "+cfg);
}
setGraphicsConfiguration(cfg);
final int flags = getReconfigureFlags(0, true) &
( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
edtDevice.lock();
try {
setWindowHandle(CreateWindow(getParentWindowHandle(),
edtDevice.getHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
getX(), getY(), getWidth(), getHeight(), autoPosition(), flags,
defaultIconDataSize, defaultIconData));
} finally {
edtDevice.unlock();
}
windowHandleClose = getWindowHandle();
if (0 == windowHandleClose) {
throw new NativeWindowException("Error creating window");
}
}
@Override
protected void closeNativeImpl() {
if(0!=windowHandleClose && null!=getScreen() ) {
final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
edtDevice.lock();
try {
CloseWindow0(edtDevice.getHandle(), windowHandleClose,
display.getJavaObjectAtom(), display.getWindowDeleteAtom() /* , display.getKbdHandle() */); // XKB disabled for now
} catch (final Throwable t) {
if(DEBUG_IMPLEMENTATION) {
final Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
e.printStackTrace();
}
} finally {
edtDevice.unlock();
windowHandleClose = 0;
}
}
if(null != renderDevice) {
renderDevice.close(); // closes X11 display
renderDevice = null;
}
}
/**
*
* X11 Window supports {@link #FLAG_IS_FULLSCREEN_SPAN}
*
* {@inheritDoc}
*/
@Override
protected boolean isReconfigureFlagSupported(final int changeFlags) {
return true; // all flags!
}
@Override
protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) {
final int _x, _y;
final InsetsImmutable _insets;
if( 0 == ( FLAG_IS_UNDECORATED & flags) ) {
// client position -> top-level window position
_insets = getInsets();
_x = x - _insets.getLeftWidth() ;
_y = y - _insets.getTopHeight() ;
} else {
_insets = null;
_x = x;
_y = y;
}
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window reconfig: "+x+"/"+y+" -> "+_x+"/"+_y+" "+width+"x"+height+", insets "+_insets+", "+ getReconfigureFlagsAsString(null, flags));
}
if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags ) ) {
if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) {
tempFSAlwaysOnTop = true;
flags |= FLAG_IS_ALWAYSONTOP;
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window reconfig.2: temporary "+getReconfigureFlagsAsString(null, flags));
}
} else {
tempFSAlwaysOnTop = false;
}
}
final int fflags = flags;
final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable