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