1 /* 2 * Copyright (c) 1996, 2014, 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 #include "awt_Toolkit.h" 27 #include "awt_Canvas.h" 28 #include "awt_Win32GraphicsConfig.h" 29 #include "awt_Window.h" 30 31 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 32 */ 33 34 // Struct for _SetEraseBackground() method 35 struct SetEraseBackgroundStruct { 36 jobject canvas; 37 jboolean doErase; 38 jboolean doEraseOnResize; 39 }; 40 41 /************************************************************************ 42 * AwtCanvas methods 43 */ 44 45 AwtCanvas::AwtCanvas() { 46 m_eraseBackground = JNI_TRUE; 47 m_eraseBackgroundOnResize = JNI_TRUE; 48 } 49 50 AwtCanvas::~AwtCanvas() { 51 } 52 53 LPCTSTR AwtCanvas::GetClassName() { 54 return TEXT("SunAwtCanvas"); 55 } 56 57 /* 58 * Create a new AwtCanvas object and window. 59 */ 60 AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent) 61 { 62 TRY; 63 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 64 65 jobject target = NULL; 66 jobject graphicsConfig = NULL; 67 jclass canvasClass = NULL; 68 jclass win32cls = NULL; 69 70 AwtCanvas *canvas = NULL; 71 72 try { 73 if (env->EnsureLocalCapacity(1) < 0) { 74 return NULL; 75 } 76 77 AwtComponent* parent; 78 79 JNI_CHECK_NULL_GOTO(hParent, "null hParent", done); 80 81 parent = (AwtComponent*)JNI_GET_PDATA(hParent); 82 JNI_CHECK_NULL_GOTO(parent, "null parent", done); 83 84 target = env->GetObjectField(self, AwtObject::targetID); 85 JNI_CHECK_NULL_GOTO(target, "null target", done); 86 87 canvas = new AwtCanvas(); 88 89 { 90 jint x = env->GetIntField(target, AwtComponent::xID); 91 jint y = env->GetIntField(target, AwtComponent::yID); 92 jint width = env->GetIntField(target, AwtComponent::widthID); 93 jint height = env->GetIntField(target, AwtComponent::heightID); 94 95 canvas->CreateHWnd(env, L"", 96 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 97 x, y, width, height, 98 parent->GetHWnd(), 99 NULL, 100 ::GetSysColor(COLOR_WINDOWTEXT), 101 ::GetSysColor(COLOR_WINDOW), 102 self); 103 104 // Set the pixel format of the HWND if a GraphicsConfiguration 105 // was provided to the Canvas constructor. 106 107 canvasClass = env->FindClass("java/awt/Canvas"); 108 DASSERT(canvasClass != NULL); 109 if (!canvasClass) { 110 throw std::bad_alloc(); 111 } 112 113 if ( env->IsInstanceOf( target, canvasClass ) ) { 114 115 // Get GraphicsConfig from our target 116 graphicsConfig = env->GetObjectField(target, 117 AwtComponent::graphicsConfigID); 118 if (graphicsConfig != NULL) { 119 120 win32cls = env->FindClass("sun/awt/Win32GraphicsConfig"); 121 DASSERT (win32cls != NULL); 122 if (!win32cls) { 123 throw std::bad_alloc(); 124 } 125 126 if ( env->IsInstanceOf( graphicsConfig, win32cls ) ) { 127 // Get the visual ID member from our GC 128 jint visual = env->GetIntField(graphicsConfig, 129 AwtWin32GraphicsConfig::win32GCVisualID); 130 if (visual > 0) { 131 HDC hdc = ::GetDC(canvas->m_hwnd); 132 // Set our pixel format 133 PIXELFORMATDESCRIPTOR pfd; 134 BOOL ret = ::SetPixelFormat(hdc, (int)visual, &pfd); 135 ::ReleaseDC(canvas->m_hwnd, hdc); 136 //Since a GraphicsConfiguration was specified, we should 137 //throw an exception if the PixelFormat couldn't be set. 138 if (ret == FALSE) { 139 DASSERT(!safe_ExceptionOccurred(env)); 140 jclass excCls = env->FindClass( 141 "java/lang/RuntimeException"); 142 DASSERT(excCls); 143 env->ExceptionClear(); 144 env->ThrowNew(excCls, 145 "\nUnable to set Pixel format on Canvas"); 146 env->DeleteLocalRef(excCls); 147 } 148 } 149 } 150 } 151 } 152 } 153 } catch (...) { 154 env->DeleteLocalRef(target); 155 env->DeleteLocalRef(graphicsConfig); 156 env->DeleteLocalRef(canvasClass); 157 env->DeleteLocalRef(win32cls); 158 159 env->DeleteGlobalRef(self); 160 env->DeleteGlobalRef(hParent); 161 throw; 162 } 163 164 done: 165 env->DeleteLocalRef(target); 166 env->DeleteLocalRef(graphicsConfig); 167 env->DeleteLocalRef(canvasClass); 168 env->DeleteLocalRef(win32cls); 169 return canvas; 170 CATCH_BAD_ALLOC_RET(0); 171 } 172 173 MsgRouting AwtCanvas::WmEraseBkgnd(HDC hDC, BOOL& didErase) 174 { 175 if (m_eraseBackground || 176 (m_eraseBackgroundOnResize && AwtWindow::IsResizing())) 177 { 178 RECT rc; 179 ::GetClipBox(hDC, &rc); 180 ::FillRect(hDC, &rc, this->GetBackgroundBrush()); 181 } 182 183 didErase = TRUE; 184 return mrConsume; 185 } 186 187 /* 188 * This routine is duplicated in AwtWindow. 189 */ 190 MsgRouting AwtCanvas::WmPaint(HDC) 191 { 192 PaintUpdateRgn(NULL); 193 return mrConsume; 194 } 195 196 MsgRouting AwtCanvas::HandleEvent(MSG *msg, BOOL synthetic) 197 { 198 if (IsFocusingMouseMessage(msg)) { 199 delete msg; 200 return mrConsume; 201 } 202 return AwtComponent::HandleEvent(msg, synthetic); 203 } 204 205 void AwtCanvas::_SetEraseBackground(void *param) 206 { 207 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 208 209 SetEraseBackgroundStruct *sebs = (SetEraseBackgroundStruct *)param; 210 jobject canvas = sebs->canvas; 211 jboolean doErase = sebs->doErase; 212 jboolean doEraseOnResize = sebs->doEraseOnResize; 213 214 PDATA pData; 215 JNI_CHECK_PEER_GOTO(canvas, ret); 216 217 AwtCanvas *c = (AwtCanvas*)pData; 218 c->m_eraseBackground = doErase; 219 c->m_eraseBackgroundOnResize = doEraseOnResize; 220 221 ret: 222 env->DeleteGlobalRef(canvas); 223 delete sebs; 224 } 225 226 227 /************************************************************************ 228 * WCanvasPeer native methods 229 */ 230 231 extern "C" { 232 233 JNIEXPORT void JNICALL 234 Java_sun_awt_windows_WCanvasPeer_create(JNIEnv *env, jobject self, 235 jobject parent) 236 { 237 TRY; 238 239 PDATA pData; 240 JNI_CHECK_PEER_RETURN(parent); 241 AwtToolkit::CreateComponent(self, parent, 242 (AwtToolkit::ComponentFactory) 243 AwtCanvas::Create); 244 JNI_CHECK_PEER_CREATION_RETURN(self); 245 246 CATCH_BAD_ALLOC; 247 } 248 249 /* 250 * Class: sun_awt_windows_WCanvasPeer 251 * Method: setNativeBackgroundErase 252 * Signature: (Z)V 253 */ 254 JNIEXPORT void JNICALL 255 Java_sun_awt_windows_WCanvasPeer_setNativeBackgroundErase(JNIEnv *env, 256 jobject self, 257 jboolean doErase, 258 jboolean doEraseOnResize) 259 { 260 TRY; 261 262 SetEraseBackgroundStruct *sebs = new SetEraseBackgroundStruct; 263 sebs->canvas = env->NewGlobalRef(self); 264 sebs->doErase = doErase; 265 sebs->doEraseOnResize = doEraseOnResize; 266 267 AwtToolkit::GetInstance().SyncCall(AwtCanvas::_SetEraseBackground, sebs); 268 // sebs and global ref are deleted in _SetEraseBackground() 269 270 CATCH_BAD_ALLOC; 271 } 272 273 } /* extern "C" */