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 
  32 jclass jawtVImgClass;
  33 jclass jawtComponentClass;
  34 jfieldID jawtPDataID;
  35 jfieldID jawtSDataID;
  36 jfieldID jawtSMgrID;
  37 
  38 
  39 /* DSI */
  40 
  41 jint 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 
  81 jint 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 
  92 JAWTDrawingSurface::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 
 109 JAWTDrawingSurface::~JAWTDrawingSurface()
 110 {
 111     TRY_NO_VERIFY;
 112 
 113     env->DeleteGlobalRef(target);
 114 
 115     CATCH_BAD_ALLOC;
 116 }
 117 
 118 JAWT_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 
 133 void 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 
 147 jint 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 
 168 void 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 
 182 JAWTOffscreenDrawingSurface::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 
 198 JAWTOffscreenDrawingSurface::~JAWTOffscreenDrawingSurface()
 199 {
 200     env->DeleteGlobalRef(target);
 201 }
 202 
 203 JAWT_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 
 219 void JNICALL JAWTOffscreenDrawingSurface::FreeDSI
 220     (JAWT_DrawingSurfaceInfo* dsi)
 221 {
 222 }
 223 
 224 jint JNICALL JAWTOffscreenDrawingSurface::LockSurface
 225     (JAWT_DrawingSurface* ds)
 226 {
 227     return JAWT_LOCK_ERROR;
 228 }
 229 
 230 void JNICALL JAWTOffscreenDrawingSurface::UnlockSurface
 231     (JAWT_DrawingSurface* ds)
 232 {
 233 }
 234 
 235 /* C exports */
 236 
 237 extern "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 
 253 extern "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 
 266 extern "C" JNIEXPORT void JNICALL DSLockAWT(JNIEnv* env)
 267 {
 268     // Do nothing on Windows
 269 }
 270 
 271 extern "C" JNIEXPORT void JNICALL DSUnlockAWT(JNIEnv* env)
 272 {
 273     // Do nothing on Windows
 274 }
 275 
 276 // EmbeddedFrame support
 277 
 278 static char *const embeddedClassName = "sun/awt/windows/WEmbeddedFrame";
 279 
 280 JNIEXPORT 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 
 294 JNIEXPORT 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 
 307 JNIEXPORT 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 }