1 /* 2 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. 3 * Copyright (c) 2010 JogAmp Community. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * - Redistribution of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistribution in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * Neither the name of Sun Microsystems, Inc. or the names of 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * This software is provided "AS IS," without a warranty of any kind. ALL 21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN 24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR 25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR 27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR 28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE 29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, 30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF 31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 32 */ 33 34 package com.jogamp.nativewindow; 35 36 import jogamp.nativewindow.NativeWindowFactoryImpl; 37 38 public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice { 39 private static final String separator = "_"; 40 private final String type; 41 protected final String connection; 42 protected final int unitID; 43 protected final String uniqueID; 44 protected long handle; 45 protected ToolkitLock toolkitLock; 46 47 /** 48 * Return the default display connection for the given windowing toolkit type 49 * gathered via {@link NativeWindowFactory#getDefaultDisplayConnection()}. 50 * @param type 51 */ getDefaultDisplayConnection()52 public static String getDefaultDisplayConnection() { 53 return NativeWindowFactory.getDefaultDisplayConnection(); 54 } 55 /** 56 * Return the default display connection for the given windowing toolkit type 57 * gathered via {@link NativeWindowFactory#getDefaultDisplayConnection(String)}. 58 * @param type 59 */ getDefaultDisplayConnection(final String type)60 public static String getDefaultDisplayConnection(final String type) { 61 return NativeWindowFactory.getDefaultDisplayConnection(type); 62 } 63 64 /** 65 * Create an instance with the system default {@link ToolkitLock}, 66 * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String)}. 67 * @param type 68 */ DefaultGraphicsDevice(final String type, final String connection, final int unitID)69 public DefaultGraphicsDevice(final String type, final String connection, final int unitID) { 70 this(type, connection, unitID, 0, NativeWindowFactory.getDefaultToolkitLock(type)); 71 } 72 73 /** 74 * Create an instance with the system default {@link ToolkitLock}. 75 * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}. 76 * @param type 77 * @param handle 78 */ DefaultGraphicsDevice(final String type, final String connection, final int unitID, final long handle)79 public DefaultGraphicsDevice(final String type, final String connection, final int unitID, final long handle) { 80 this(type, connection, unitID, handle, NativeWindowFactory.getDefaultToolkitLock(type, handle)); 81 } 82 83 /** 84 * Create an instance with the given {@link ToolkitLock} instance, or <i>null</i> {@link ToolkitLock} if null. 85 * @param type 86 * @param handle 87 * @param locker if null, a non blocking <i>null</i> lock is used. 88 */ DefaultGraphicsDevice(final String type, final String connection, final int unitID, final long handle, final ToolkitLock locker)89 public DefaultGraphicsDevice(final String type, final String connection, final int unitID, final long handle, final ToolkitLock locker) { 90 this.type = type; 91 this.connection = connection; 92 this.unitID = unitID; 93 this.uniqueID = getUniqueID(type, connection, unitID); 94 this.handle = handle; 95 this.toolkitLock = null != locker ? locker : NativeWindowFactoryImpl.getNullToolkitLock(); 96 } 97 98 @Override clone()99 public Object clone() { 100 try { 101 return super.clone(); 102 } catch (final CloneNotSupportedException e) { 103 throw new NativeWindowException(e); 104 } 105 } 106 107 @Override getType()108 public final String getType() { 109 return type; 110 } 111 112 @Override getConnection()113 public final String getConnection() { 114 return connection; 115 } 116 117 @Override getUnitID()118 public final int getUnitID() { 119 return unitID; 120 } 121 122 @Override getUniqueID()123 public final String getUniqueID() { 124 return uniqueID; 125 } 126 127 @Override getHandle()128 public final long getHandle() { 129 return handle; 130 } 131 132 /** 133 * {@inheritDoc} 134 * <p> 135 * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}. 136 * </p> 137 * 138 * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) 139 * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, com.jogamp.nativewindow.ToolkitLock) 140 */ 141 @Override lock()142 public final void lock() { 143 toolkitLock.lock(); 144 } 145 146 @Override validateLocked()147 public final void validateLocked() throws RuntimeException { 148 toolkitLock.validateLocked(); 149 } 150 151 /** 152 * {@inheritDoc} 153 * <p> 154 * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}. 155 * </p> 156 * 157 * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) 158 * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, com.jogamp.nativewindow.ToolkitLock) 159 */ 160 @Override unlock()161 public final void unlock() { 162 toolkitLock.unlock(); 163 } 164 165 @Override open()166 public boolean open() { 167 return false; 168 } 169 170 @Override close()171 public boolean close() { 172 toolkitLock.dispose(); 173 if(0 != handle) { 174 handle = 0; 175 return true; 176 } 177 return false; 178 } 179 180 @Override isHandleOwner()181 public boolean isHandleOwner() { 182 return false; 183 } 184 185 @Override clearHandleOwner()186 public void clearHandleOwner() { 187 } 188 189 @Override toString()190 public String toString() { 191 return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", owner "+isHandleOwner()+", "+toolkitLock+"]"; 192 } 193 194 /** 195 * Set the native handle of the underlying native device 196 * and return the previous one. 197 */ setHandle(final long newHandle)198 protected final long setHandle(final long newHandle) { 199 final long oldHandle = handle; 200 handle = newHandle; 201 return oldHandle; 202 } 203 getHandleOwnership()204 protected Object getHandleOwnership() { 205 return null; 206 } setHandleOwnership(final Object newOwnership)207 protected Object setHandleOwnership(final Object newOwnership) { 208 return null; 209 } 210 swapDeviceHandleAndOwnership(final DefaultGraphicsDevice aDevice1, final DefaultGraphicsDevice aDevice2)211 public static final void swapDeviceHandleAndOwnership(final DefaultGraphicsDevice aDevice1, final DefaultGraphicsDevice aDevice2) { 212 aDevice1.lock(); 213 try { 214 aDevice2.lock(); 215 try { 216 final long aDevice1Handle = aDevice1.getHandle(); 217 final long aDevice2Handle = aDevice2.setHandle(aDevice1Handle); 218 aDevice1.setHandle(aDevice2Handle); 219 final Object aOwnership1 = aDevice1.getHandleOwnership(); 220 final Object aOwnership2 = aDevice2.setHandleOwnership(aOwnership1); 221 aDevice1.setHandleOwnership(aOwnership2); 222 } finally { 223 aDevice2.unlock(); 224 } 225 } finally { 226 aDevice1.unlock(); 227 } 228 } 229 230 /** 231 * Set the internal ToolkitLock, which is used within the 232 * {@link #lock()} and {@link #unlock()} implementation. 233 * 234 * <p> 235 * The current ToolkitLock is being locked/unlocked while swapping the reference, 236 * ensuring no concurrent access can occur during the swap. 237 * </p> 238 * 239 * @param locker the ToolkitLock, if null, {@link jogamp.nativewindow.NullToolkitLock} is being used 240 * @return the previous ToolkitLock instance 241 */ setToolkitLock(final ToolkitLock locker)242 protected ToolkitLock setToolkitLock(final ToolkitLock locker) { 243 final ToolkitLock _toolkitLock = toolkitLock; 244 _toolkitLock.lock(); 245 try { 246 toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ; 247 } finally { 248 _toolkitLock.unlock(); 249 } 250 return _toolkitLock; 251 } 252 253 /** 254 * @return the used ToolkitLock 255 * 256 * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long) 257 * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, com.jogamp.nativewindow.ToolkitLock) 258 */ getToolkitLock()259 public final ToolkitLock getToolkitLock() { 260 return toolkitLock; 261 } 262 263 /** 264 * Returns a unique String object using {@link String#intern()} for the given arguments, 265 * which object reference itself can be used as a key. 266 */ getUniqueID(final String type, final String connection, final int unitID)267 private static String getUniqueID(final String type, final String connection, final int unitID) { 268 return (type + separator + connection + separator + unitID).intern(); 269 } 270 } 271