1/*
2 * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#define _JNI_IMPLEMENTATION_
27
28#include "awt.h"
29#include "awt_DrawingSurface.h"
30#include "awt_Component.h"
31
32jclass jawtVImgClass;
33jclass jawtComponentClass;
34jfieldID jawtPDataID;
35jfieldID jawtSDataID;
36jfieldID jawtSMgrID;
37
38
39/* DSI */
40
41jint JAWTDrawingSurfaceInfo::Init(JAWTDrawingSurface* parent)
42{
43    TRY;
44
45    JNIEnv* env = parent->env;
46    jobject target = parent->target;
47    if (JNU_IsNull(env, target)) {
48        DTRACE_PRINTLN("NULL target");
49        return JAWT_LOCK_ERROR;
50    }
51    HWND newHwnd = AwtComponent::GetHWnd(env, target);
52    if (!::IsWindow(newHwnd)) {
53        DTRACE_PRINTLN("Bad HWND");
54        return JAWT_LOCK_ERROR;
55    }
56    jint retval = 0;
57    platformInfo = this;
58    ds = parent;
59    bounds.x = env->GetIntField(target, AwtComponent::xID);
60    bounds.y = env->GetIntField(target, AwtComponent::yID);
61    bounds.width = env->GetIntField(target, AwtComponent::widthID);
62    bounds.height = env->GetIntField(target, AwtComponent::heightID);
63    if (hwnd != newHwnd) {
64        if (hwnd != NULL) {
65            ::ReleaseDC(hwnd, hdc);
66            retval = JAWT_LOCK_SURFACE_CHANGED;
67        }
68        hwnd = newHwnd;
69        hdc = ::GetDCEx(hwnd, NULL, DCX_CACHE|DCX_CLIPCHILDREN|DCX_CLIPSIBLINGS);
70    }
71    clipSize = 1;
72    clip = &bounds;
73    int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd);
74    hpalette = AwtWin32GraphicsDevice::GetPalette(screen);
75
76    return retval;
77
78    CATCH_BAD_ALLOC_RET(JAWT_LOCK_ERROR);
79}
80
81jint JAWTOffscreenDrawingSurfaceInfo::Init(JAWTOffscreenDrawingSurface* parent)
82{
83    TRY;
84
85    return JAWT_LOCK_ERROR;
86
87    CATCH_BAD_ALLOC_RET(JAWT_LOCK_ERROR);
88}
89
90/* Drawing Surface */
91
92JAWTDrawingSurface::JAWTDrawingSurface(JNIEnv* pEnv, jobject rTarget)
93{
94    TRY_NO_VERIFY;
95
96    env = pEnv;
97    target = env->NewGlobalRef(rTarget);
98    Lock = LockSurface;
99    GetDrawingSurfaceInfo = GetDSI;
100    FreeDrawingSurfaceInfo = FreeDSI;
101    Unlock = UnlockSurface;
102    info.hwnd = NULL;
103    info.hdc = NULL;
104    info.hpalette = NULL;
105
106    CATCH_BAD_ALLOC;
107}
108
109JAWTDrawingSurface::~JAWTDrawingSurface()
110{
111    TRY_NO_VERIFY;
112
113    env->DeleteGlobalRef(target);
114
115    CATCH_BAD_ALLOC;
116}
117
118JAWT_DrawingSurfaceInfo* JNICALL JAWTDrawingSurface::GetDSI
119    (JAWT_DrawingSurface* ds)
120{
121    TRY;
122
123    if (ds == NULL) {
124        DTRACE_PRINTLN("Drawing Surface is NULL");
125        return NULL;
126    }
127    JAWTDrawingSurface* pds = static_cast<JAWTDrawingSurface*>(ds);
128    return &(pds->info);
129
130    CATCH_BAD_ALLOC_RET(NULL);
131}
132
133void JNICALL JAWTDrawingSurface::FreeDSI
134    (JAWT_DrawingSurfaceInfo* dsi)
135{
136    TRY_NO_VERIFY;
137
138    DASSERTMSG(dsi != NULL, "Drawing Surface Info is NULL\n");
139
140    JAWTDrawingSurfaceInfo* jdsi = static_cast<JAWTDrawingSurfaceInfo*>(dsi);
141
142    ::ReleaseDC(jdsi->hwnd, jdsi->hdc);
143
144    CATCH_BAD_ALLOC;
145}
146
147jint JNICALL JAWTDrawingSurface::LockSurface
148    (JAWT_DrawingSurface* ds)
149{
150    TRY;
151
152    if (ds == NULL) {
153        DTRACE_PRINTLN("Drawing Surface is NULL");
154        return JAWT_LOCK_ERROR;
155    }
156    JAWTDrawingSurface* pds = static_cast<JAWTDrawingSurface*>(ds);
157    jint val = pds->info.Init(pds);
158    if ((val & JAWT_LOCK_ERROR) != 0) {
159        return val;
160    }
161    val = AwtComponent::GetDrawState(pds->info.hwnd);
162    AwtComponent::SetDrawState(pds->info.hwnd, 0);
163    return val;
164
165    CATCH_BAD_ALLOC_RET(JAWT_LOCK_ERROR);
166}
167
168void JNICALL JAWTDrawingSurface::UnlockSurface
169    (JAWT_DrawingSurface* ds)
170{
171    TRY_NO_VERIFY;
172
173    if (ds == NULL) {
174        DTRACE_PRINTLN("Drawing Surface is NULL");
175        return;
176    }
177    JAWTDrawingSurface* pds = static_cast<JAWTDrawingSurface*>(ds);
178
179    CATCH_BAD_ALLOC;
180}
181
182JAWTOffscreenDrawingSurface::JAWTOffscreenDrawingSurface(JNIEnv* pEnv,
183                                                         jobject rTarget)
184{
185    TRY_NO_VERIFY;
186    env = pEnv;
187    target = env->NewGlobalRef(rTarget);
188    Lock = LockSurface;
189    GetDrawingSurfaceInfo = GetDSI;
190    FreeDrawingSurfaceInfo = FreeDSI;
191    Unlock = UnlockSurface;
192    info.dxSurface = NULL;
193    info.dx7Surface = NULL;
194
195    CATCH_BAD_ALLOC;
196}
197
198JAWTOffscreenDrawingSurface::~JAWTOffscreenDrawingSurface()
199{
200    env->DeleteGlobalRef(target);
201}
202
203JAWT_DrawingSurfaceInfo* JNICALL JAWTOffscreenDrawingSurface::GetDSI
204    (JAWT_DrawingSurface* ds)
205{
206    TRY;
207
208    if (ds == NULL) {
209        DTRACE_PRINTLN("Drawing Surface is NULL");
210        return NULL;
211    }
212    JAWTOffscreenDrawingSurface* pds =
213        static_cast<JAWTOffscreenDrawingSurface*>(ds);
214    return &(pds->info);
215
216    CATCH_BAD_ALLOC_RET(NULL);
217}
218
219void JNICALL JAWTOffscreenDrawingSurface::FreeDSI
220    (JAWT_DrawingSurfaceInfo* dsi)
221{
222}
223
224jint JNICALL JAWTOffscreenDrawingSurface::LockSurface
225    (JAWT_DrawingSurface* ds)
226{
227    return JAWT_LOCK_ERROR;
228}
229
230void JNICALL JAWTOffscreenDrawingSurface::UnlockSurface
231    (JAWT_DrawingSurface* ds)
232{
233}
234
235/* C exports */
236
237extern "C" JNIEXPORT JAWT_DrawingSurface* JNICALL DSGetDrawingSurface
238    (JNIEnv* env, jobject target)
239{
240    TRY;
241
242    // See if the target component is a java.awt.Component
243    if (env->IsInstanceOf(target, jawtComponentClass)) {
244        return new JAWTDrawingSurface(env, target);
245    }
246
247    DTRACE_PRINTLN("GetDrawingSurface target must be a Component");
248    return NULL;
249
250    CATCH_BAD_ALLOC_RET(NULL);
251}
252
253extern "C" JNIEXPORT void JNICALL DSFreeDrawingSurface
254    (JAWT_DrawingSurface* ds)
255{
256    TRY_NO_VERIFY;
257
258    if (ds == NULL) {
259        DTRACE_PRINTLN("Drawing Surface is NULL");
260    }
261    delete static_cast<JAWTDrawingSurface*>(ds);
262
263    CATCH_BAD_ALLOC;
264}
265
266extern "C" JNIEXPORT void JNICALL DSLockAWT(JNIEnv* env)
267{
268    // Do nothing on Windows
269}
270
271extern "C" JNIEXPORT void JNICALL DSUnlockAWT(JNIEnv* env)
272{
273    // Do nothing on Windows
274}
275
276// EmbeddedFrame support
277
278static char *const embeddedClassName = "sun/awt/windows/WEmbeddedFrame";
279
280JNIEXPORT jobject JNICALL awt_CreateEmbeddedFrame
281(JNIEnv* env, void* platformInfo)
282{
283    static jmethodID mid = NULL;
284    static jclass cls;
285    if (mid == NULL) {
286        cls = env->FindClass(embeddedClassName);
287        CHECK_NULL_RETURN(cls, NULL);
288        mid = env->GetMethodID(cls, "<init>", "(J)V");
289        CHECK_NULL_RETURN(mid, NULL);
290    }
291    return env->NewObject(cls, mid, platformInfo);
292}
293
294JNIEXPORT void JNICALL awt_SetBounds
295(JNIEnv *env, jobject embeddedFrame, jint x, jint y, jint w, jint h)
296{
297    static jmethodID mid = NULL;
298    if (mid == NULL) {
299        jclass cls = env->FindClass(embeddedClassName);
300        CHECK_NULL(cls);
301        mid = env->GetMethodID(cls, "setBoundsPrivate", "(IIII)V");
302        CHECK_NULL(mid);
303    }
304    env->CallVoidMethod(embeddedFrame, mid, x, y, w, h);
305}
306
307JNIEXPORT void JNICALL awt_SynthesizeWindowActivation
308(JNIEnv *env, jobject embeddedFrame, jboolean doActivate)
309{
310    static jmethodID mid = NULL;
311    if (mid == NULL) {
312        jclass cls = env->FindClass(embeddedClassName);
313        CHECK_NULL(cls);
314        mid = env->GetMethodID(cls, "synthesizeWindowActivation", "(Z)V");
315        CHECK_NULL(mid);
316    }
317    env->CallVoidMethod(embeddedFrame, mid, doActivate);
318}
319