1 /**
2  * Copyright 2010 JogAmp Community. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice, this list of
8  *       conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *       of conditions and the following disclaimer in the documentation and/or other materials
12  *       provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  * or implied, of JogAmp Community.
27  */
28 
29 package jogamp.nativewindow.windows;
30 
31 import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
32 import com.jogamp.nativewindow.AbstractGraphicsDevice;
33 import com.jogamp.nativewindow.NativeWindowException;
34 import com.jogamp.nativewindow.ProxySurface;
35 import com.jogamp.nativewindow.UpstreamSurfaceHook;
36 
37 import jogamp.nativewindow.ProxySurfaceImpl;
38 import jogamp.nativewindow.windows.GDI;
39 
40 
41 /**
42  * GDI Surface implementation which wraps an existing window handle
43  * allowing the use of HDC via lockSurface()/unlockSurface() protocol.
44  * The latter will get and release the HDC.
45  * The size via getWidth()/getHeight() is invalid.
46  *
47  * @see ProxySurface
48  */
49 public class GDISurface extends ProxySurfaceImpl {
50   private long windowHandle;
51   private long surfaceHandle;
52 
53   /**
54    * @param cfg the {@link AbstractGraphicsConfiguration} to be used
55    * @param windowHandle the wrapped pre-existing native window handle, maybe 0 if not yet determined
56    * @param upstream the {@link UpstreamSurfaceHook} to be used
57    * @param ownsDevice <code>true</code> if this {@link ProxySurface} instance
58    *                  owns the {@link AbstractGraphicsConfiguration}'s {@link AbstractGraphicsDevice},
59    *                  otherwise <code>false</code>. Owning the device implies closing it at {@link #destroyNotify()}.
60    */
GDISurface(final AbstractGraphicsConfiguration cfg, final long windowHandle, final UpstreamSurfaceHook upstream, final boolean ownsDevice)61   public GDISurface(final AbstractGraphicsConfiguration cfg, final long windowHandle, final UpstreamSurfaceHook upstream, final boolean ownsDevice) {
62     super(cfg, upstream, ownsDevice);
63     this.windowHandle=windowHandle;
64     this.surfaceHandle=0;
65   }
66 
67   @Override
invalidateImpl()68   protected void invalidateImpl() {
69     if(0 != surfaceHandle) {
70         throw new NativeWindowException("didn't release surface Handle: "+this);
71     }
72     windowHandle = 0;
73     // surfaceHandle = 0;
74   }
75 
76   /**
77    * {@inheritDoc}
78    * <p>
79    * Actually the window handle (HWND), since the surfaceHandle (HDC) is derived
80    * from it at {@link #lockSurface()}.
81    * </p>
82    */
83   @Override
setSurfaceHandle(final long surfaceHandle)84   public final void setSurfaceHandle(final long surfaceHandle) {
85       this.windowHandle = surfaceHandle;
86   }
87 
88   /**
89    * Sets the window handle (HWND).
90    */
setWindowHandle(final long windowHandle)91   public final void setWindowHandle(final long windowHandle) {
92       this.windowHandle = windowHandle;
93   }
94 
getWindowHandle()95   public final long getWindowHandle() {
96       return windowHandle;
97   }
98 
99   @Override
lockSurfaceImpl()100   final protected int lockSurfaceImpl() {
101     if (0 == windowHandle) {
102         throw new NativeWindowException("null window handle: "+this);
103     }
104     if (0 != surfaceHandle) {
105         throw new InternalError("surface not released");
106     }
107     surfaceHandle = GDI.GetDC(windowHandle);
108     /*
109     if(0 == surfaceHandle) {
110         System.err.println("****** DC Acquire: 0x"+Long.toHexString(windowHandle)+", isWindow "+GDI.IsWindow(windowHandle)+", isVisible "+GDI.IsWindowVisible(windowHandle)+", GDI LastError: "+GDI.GetLastError()+", 0x"+Long.toHexString(surfaceHandle)+", GDI LastError: "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
111         Thread.dumpStack();
112     }
113     */
114     return (0 != surfaceHandle) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
115   }
116 
117   @Override
unlockSurfaceImpl()118   final protected void unlockSurfaceImpl() {
119     if (0 != surfaceHandle) {
120         if(0 == GDI.ReleaseDC(windowHandle, surfaceHandle)) {
121             throw new NativeWindowException("DC not released: "+this+", isWindow "+GDI.IsWindow(windowHandle)+", werr "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
122         }
123         surfaceHandle=0;
124     }
125   }
126 
127   @Override
getSurfaceHandle()128   final public long getSurfaceHandle() {
129     return surfaceHandle;
130   }
131 
132   @Override
convertToWindowUnits(final int[] pixelUnitsAndResult)133   public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
134       return pixelUnitsAndResult; // no pixelScale factor
135   }
136 
137   @Override
convertToPixelUnits(final int[] windowUnitsAndResult)138   public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
139       return windowUnitsAndResult; // no pixelScale factor
140   }
141 
142 }
143