All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jogamp.newt.NewtFactory Maven / Gradle / Ivy

There is a newer version: 2.3.2
Show newest version
/*
 * 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 com.jogamp.newt;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;

import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowFactory;

import com.jogamp.common.util.IOUtil;
import com.jogamp.common.util.PropertyAccess;

import jogamp.newt.Debug;
import jogamp.newt.DisplayImpl;
import jogamp.newt.ScreenImpl;
import jogamp.newt.WindowImpl;

public class NewtFactory {
    public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");

    public static final String DRIVER_DEFAULT_ROOT_PACKAGE = "jogamp.newt.driver";

    private static IOUtil.ClassResources defaultWindowIcons;

    static {
        AccessController.doPrivileged(new PrivilegedAction() {
            @Override
            public Object run() {
                NativeWindowFactory.initSingleton(); // last resort ..
                {
                    /** See API Doc in {@link Window} ! */
                    final String[] paths = PropertyAccess.getProperty("newt.window.icons", true, "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png").split("\\s");
                    if( paths.length < 2 ) {
                        throw new IllegalArgumentException("Property 'newt.window.icons' did not specify at least two PNG icons, but "+Arrays.toString(paths));
                    }
                    final Class clazz = NewtFactory.class;
                    defaultWindowIcons = new IOUtil.ClassResources(clazz, paths);
                }
                return null;
            } } );
    }

    /**
     * Returns the application window icon resources to be used.
     * 

* Property newt.window.icons may define a list of PNG icons separated by a whitespace character. * Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution. *

*

* Users may also specify application window icons using {@link #setWindowIcons(com.jogamp.common.util.IOUtil.ClassResources)}. *

*/ public static IOUtil.ClassResources getWindowIcons() { return defaultWindowIcons; } /** * Allow user to set custom window icons, only applicable at application start before creating any NEWT instance. *

* Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution. *

*/ public static void setWindowIcons(final IOUtil.ClassResources cres) { defaultWindowIcons = cres; } public static Class getCustomClass(final String packageName, final String classBaseName) { Class clazz = null; if(packageName!=null && classBaseName!=null) { final String clazzName; if( packageName.startsWith(".") ) { clazzName = DRIVER_DEFAULT_ROOT_PACKAGE + packageName + "." + classBaseName ; } else { clazzName = packageName + "." + classBaseName ; } try { clazz = Class.forName(clazzName); } catch (final Throwable t) { if(DEBUG_IMPLEMENTATION) { System.err.println("Warning: Failed to find class <"+clazzName+">: "+t.getMessage()); t.printStackTrace(); } } } return clazz; } private static boolean useEDT = true; /** * Toggles the usage of an EventDispatchThread while creating a Display.
* The default is enabled.
* The EventDispatchThread is thread local to the Display instance.
*/ public static synchronized void setUseEDT(final boolean onoff) { useEDT = onoff; } /** @see #setUseEDT(boolean) */ public static boolean useEDT() { return useEDT; } /** * Create a Display entity. *

* Native creation is lazily done at usage, ie. {@link Display#addReference()}. *

*

* An already existing display connection of the same name will be reused. *

* @param name the display connection name which is a technical platform specific detail, * see {@link AbstractGraphicsDevice#getConnection()}. Use null for default. * @return the new or reused Display instance */ public static Display createDisplay(final String name) { return createDisplay(name, true); } /** * Create a Display entity. *

* Native creation is lazily done at usage, ie. {@link Display#addReference()}. *

*

* An already existing display connection of the same name will be reused * if reuse is true, otherwise a new instance is being created. *

* @param name the display connection name which is a technical platform specific detail, * see {@link AbstractGraphicsDevice#getConnection()}. Use null for default. * @param reuse attempt to reuse an existing Display with same name if set true, otherwise create a new instance. * @return the new or reused Display instance */ public static Display createDisplay(final String name, final boolean reuse) { return DisplayImpl.create(NativeWindowFactory.getNativeWindowType(true), name, 0, reuse); } /** * Create a Display entity. *

* Native creation is lazily done at usage, ie. {@link Display#addReference()}. *

*

* An already existing display connection of the same name will be reused. *

* @param type explicit NativeWindow type eg. {@link NativeWindowFactory#TYPE_AWT} * @param name the display connection name which is a technical platform specific detail, * see {@link AbstractGraphicsDevice#getConnection()}. Use null for default. * @return the new or reused Display instance */ public static Display createDisplay(final String type, final String name) { return createDisplay(type, name, true); } /** * Create a Display entity. *

* Native creation is lazily done at usage, ie. {@link Display#addReference()}. *

*

* An already existing display connection of the same name will be reused * if reuse is true, otherwise a new instance is being created. *

* @param type explicit NativeWindow type eg. {@link NativeWindowFactory#TYPE_AWT} * @param name the display connection name which is a technical platform specific detail, * see {@link AbstractGraphicsDevice#getConnection()}. Use null for default. * @param reuse attempt to reuse an existing Display with same name if set true, otherwise create a new instance. * @return the new or reused Display instance */ public static Display createDisplay(final String type, final String name, final boolean reuse) { return DisplayImpl.create(type, name, 0, reuse); } /** * Create a Screen entity. *

* Native creation is lazily done at usage, ie. {@link Screen#addReference()}. *

*

* The lifecycle of this Screen's Display is handled via {@link Display#addReference()} * and {@link Display#removeReference()}. *

*/ public static Screen createScreen(final Display display, final int index) { return ScreenImpl.create(display, index); } /** * Create a top level Window entity on the default Display and default Screen. *

* Native creation is lazily done at usage, ie. {@link Window#setVisible(boolean)}. *

*

* An already existing default Display will be reused. *

*

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

*/ public static Window createWindow(final CapabilitiesImmutable caps) { return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), caps); } /** * Create a top level Window entity. *

* Native creation is lazily done at usage, ie. {@link Window#setVisible(boolean)}. *

*

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

*/ public static Window createWindow(final Screen screen, final CapabilitiesImmutable caps) { return WindowImpl.create(null, 0, screen, caps); } /** * Create a child Window entity attached to the given parent.
* The Screen and Display information is regenerated utilizing the parents information, * while reusing an existing Display.
*

* In case parentWindowObject is a {@link com.jogamp.newt.Window} instance,
* the new window is added to it's list of children.
* This assures proper handling of visibility, creation and destruction.
* {@link com.jogamp.newt.event.WindowEvent#EVENT_WINDOW_RESIZED} is not propagated to the child window for layout
, * you have to add an appropriate {@link com.jogamp.newt.event.WindowListener} for this use case.
* The parents visibility is passed to the new Window

*

* In case parentWindowObject is a different {@link javax.media.nativewindow.NativeWindow} implementation,
* you have to handle all events appropriate.

*

*

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

* * @param parentWindowObject either a NativeWindow instance */ public static Window createWindow(final NativeWindow parentWindow, final CapabilitiesImmutable caps) { final String type = NativeWindowFactory.getNativeWindowType(true); if( null == parentWindow ) { return createWindowImpl(type, caps); } Screen screen = null; Window newtParentWindow = null; if ( parentWindow instanceof Window ) { // use parent NEWT Windows Display/Screen newtParentWindow = (Window) parentWindow ; screen = newtParentWindow.getScreen(); } else { // create a Display/Screen compatible to the NativeWindow final AbstractGraphicsConfiguration parentConfig = parentWindow.getGraphicsConfiguration(); if(null!=parentConfig) { final AbstractGraphicsScreen parentScreen = parentConfig.getScreen(); final AbstractGraphicsDevice parentDevice = parentScreen.getDevice(); final Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true); screen = NewtFactory.createScreen(display, parentScreen.getIndex()); } else { final Display display = NewtFactory.createDisplay(type, null, true); // local display screen = NewtFactory.createScreen(display, 0); // screen 0 } } final Window win = WindowImpl.create(parentWindow, 0, screen, caps); win.setSize(parentWindow.getWidth(), parentWindow.getHeight()); if ( null != newtParentWindow ) { newtParentWindow.addChild(win); win.setVisible(newtParentWindow.isVisible()); } return win; } private static Window createWindowImpl(final String type, final CapabilitiesImmutable caps) { final Display display = NewtFactory.createDisplay(type, null, true); // local display final Screen screen = NewtFactory.createScreen(display, 0); // screen 0 return WindowImpl.create(null, 0, screen, caps); } /** * Create a child Window entity attached to the given parent, incl native creation
* * @param displayConnection the parent window's display connection * @param screenIdx the desired screen index * @param parentWindowHandle the native parent window handle * @param caps the desired capabilities * @return */ public static Window createWindow(final String displayConnection, final int screenIdx, final long parentWindowHandle, final CapabilitiesImmutable caps) { final String type = NativeWindowFactory.getNativeWindowType(true); final Display display = NewtFactory.createDisplay(type, displayConnection, true); final Screen screen = NewtFactory.createScreen(display, screenIdx); return WindowImpl.create(null, parentWindowHandle, screen, caps); } /** * Ability to try a Window type with a constructor argument, if supported ..

* Currently only valid is AWTWindow(Frame frame) , * to support an external created AWT Frame, ie the browsers embedded frame. * * @param undecorated only impacts if the window is in top-level state, while attached to a parent window it's rendered undecorated always */ public static Window createWindow(final Object[] cstrArguments, final Screen screen, final CapabilitiesImmutable caps) { return WindowImpl.create(cstrArguments, screen, caps); } /** * Instantiate a Display entity using the native handle. */ public static Display createDisplay(final String type, final long handle, final boolean reuse) { return DisplayImpl.create(type, null, handle, reuse); } public static boolean isScreenCompatible(final NativeWindow parent, final Screen childScreen) { // Get parent's NativeWindow details final AbstractGraphicsConfiguration parentConfig = parent.getGraphicsConfiguration(); final AbstractGraphicsScreen parentScreen = parentConfig.getScreen(); final AbstractGraphicsDevice parentDevice = parentScreen.getDevice(); final DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay(); final String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle()); final String childDisplayName = childDisplay.getName(); if( ! parentDisplayName.equals( childDisplayName ) ) { return false; } if( parentScreen.getIndex() != childScreen.getIndex() ) { return false; } return true; } public static Screen createCompatibleScreen(final NativeWindow parent) { return createCompatibleScreen(parent, null); } public static Screen createCompatibleScreen(final NativeWindow parent, final Screen childScreen) { // Get parent's NativeWindow details final AbstractGraphicsConfiguration parentConfig = parent.getGraphicsConfiguration(); final AbstractGraphicsScreen parentScreen = parentConfig.getScreen(); final AbstractGraphicsDevice parentDevice = parentScreen.getDevice(); if(null != childScreen) { // check if child Display/Screen is compatible already final DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay(); final String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle()); final String childDisplayName = childDisplay.getName(); final boolean displayEqual = parentDisplayName.equals( childDisplayName ); final boolean screenEqual = parentScreen.getIndex() == childScreen.getIndex(); if(DEBUG_IMPLEMENTATION) { System.err.println("NewtFactory.createCompatibleScreen: Display: "+ parentDisplayName+" =? "+childDisplayName+" : "+displayEqual+"; Screen: "+ parentScreen.getIndex()+" =? "+childScreen.getIndex()+" : "+screenEqual); } if( displayEqual && screenEqual ) { // match: display/screen return childScreen; } } // Prep NEWT's Display and Screen according to the parent final String type = NativeWindowFactory.getNativeWindowType(true); final Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true); return NewtFactory.createScreen(display, parentScreen.getIndex()); } }