| /* |
| * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "awt_Toolkit.h" |
| #include "awt_Canvas.h" |
| #include "awt_Win32GraphicsConfig.h" |
| #include "awt_Window.h" |
| |
| /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. |
| */ |
| |
| // Struct for _SetEraseBackground() method |
| struct SetEraseBackgroundStruct { |
| jobject canvas; |
| jboolean doErase; |
| jboolean doEraseOnResize; |
| }; |
| |
| /************************************************************************ |
| * AwtCanvas methods |
| */ |
| |
| AwtCanvas::AwtCanvas() { |
| m_eraseBackground = JNI_TRUE; |
| m_eraseBackgroundOnResize = JNI_TRUE; |
| } |
| |
| AwtCanvas::~AwtCanvas() { |
| } |
| |
| LPCTSTR AwtCanvas::GetClassName() { |
| return TEXT("SunAwtCanvas"); |
| } |
| |
| /* |
| * Create a new AwtCanvas object and window. |
| */ |
| AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent) |
| { |
| TRY; |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject target = NULL; |
| jobject graphicsConfig = NULL; |
| jclass canvasClass = NULL; |
| jclass win32cls = NULL; |
| |
| AwtCanvas *canvas = NULL; |
| |
| try { |
| if (env->EnsureLocalCapacity(1) < 0) { |
| return NULL; |
| } |
| |
| AwtComponent* parent; |
| |
| JNI_CHECK_NULL_GOTO(hParent, "null hParent", done); |
| |
| parent = (AwtComponent*)JNI_GET_PDATA(hParent); |
| JNI_CHECK_NULL_GOTO(parent, "null parent", done); |
| |
| target = env->GetObjectField(self, AwtObject::targetID); |
| JNI_CHECK_NULL_GOTO(target, "null target", done); |
| |
| canvas = new AwtCanvas(); |
| |
| { |
| jint x = env->GetIntField(target, AwtComponent::xID); |
| jint y = env->GetIntField(target, AwtComponent::yID); |
| jint width = env->GetIntField(target, AwtComponent::widthID); |
| jint height = env->GetIntField(target, AwtComponent::heightID); |
| |
| canvas->CreateHWnd(env, L"", |
| WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, |
| x, y, width, height, |
| parent->GetHWnd(), |
| NULL, |
| ::GetSysColor(COLOR_WINDOWTEXT), |
| ::GetSysColor(COLOR_WINDOW), |
| self); |
| |
| // Set the pixel format of the HWND if a GraphicsConfiguration |
| // was provided to the Canvas constructor. |
| |
| canvasClass = env->FindClass("java/awt/Canvas"); |
| DASSERT(canvasClass != NULL); |
| if (!canvasClass) { |
| throw std::bad_alloc(); |
| } |
| |
| if ( env->IsInstanceOf( target, canvasClass ) ) { |
| |
| // Get GraphicsConfig from our target |
| graphicsConfig = env->GetObjectField(target, |
| AwtComponent::graphicsConfigID); |
| if (graphicsConfig != NULL) { |
| |
| win32cls = env->FindClass("sun/awt/Win32GraphicsConfig"); |
| DASSERT (win32cls != NULL); |
| if (!win32cls) { |
| throw std::bad_alloc(); |
| } |
| |
| if ( env->IsInstanceOf( graphicsConfig, win32cls ) ) { |
| // Get the visual ID member from our GC |
| jint visual = env->GetIntField(graphicsConfig, |
| AwtWin32GraphicsConfig::win32GCVisualID); |
| if (visual > 0) { |
| HDC hdc = ::GetDC(canvas->m_hwnd); |
| // Set our pixel format |
| PIXELFORMATDESCRIPTOR pfd; |
| BOOL ret = ::SetPixelFormat(hdc, (int)visual, &pfd); |
| ::ReleaseDC(canvas->m_hwnd, hdc); |
| //Since a GraphicsConfiguration was specified, we should |
| //throw an exception if the PixelFormat couldn't be set. |
| if (ret == FALSE) { |
| DASSERT(!safe_ExceptionOccurred(env)); |
| jclass excCls = env->FindClass( |
| "java/lang/RuntimeException"); |
| DASSERT(excCls); |
| env->ExceptionClear(); |
| env->ThrowNew(excCls, |
| "\nUnable to set Pixel format on Canvas"); |
| env->DeleteLocalRef(excCls); |
| } |
| } |
| } |
| } |
| } |
| } |
| } catch (...) { |
| env->DeleteLocalRef(target); |
| env->DeleteLocalRef(graphicsConfig); |
| env->DeleteLocalRef(canvasClass); |
| env->DeleteLocalRef(win32cls); |
| |
| env->DeleteGlobalRef(self); |
| env->DeleteGlobalRef(hParent); |
| throw; |
| } |
| |
| done: |
| env->DeleteLocalRef(target); |
| env->DeleteLocalRef(graphicsConfig); |
| env->DeleteLocalRef(canvasClass); |
| env->DeleteLocalRef(win32cls); |
| return canvas; |
| CATCH_BAD_ALLOC_RET(0); |
| } |
| |
| MsgRouting AwtCanvas::WmEraseBkgnd(HDC hDC, BOOL& didErase) |
| { |
| if (m_eraseBackground || |
| (m_eraseBackgroundOnResize && AwtWindow::IsResizing())) |
| { |
| RECT rc; |
| ::GetClipBox(hDC, &rc); |
| ::FillRect(hDC, &rc, this->GetBackgroundBrush()); |
| } |
| |
| didErase = TRUE; |
| return mrConsume; |
| } |
| |
| /* |
| * This routine is duplicated in AwtWindow. |
| */ |
| MsgRouting AwtCanvas::WmPaint(HDC) |
| { |
| PaintUpdateRgn(NULL); |
| return mrConsume; |
| } |
| |
| MsgRouting AwtCanvas::HandleEvent(MSG *msg, BOOL synthetic) |
| { |
| if (IsFocusingMouseMessage(msg)) { |
| delete msg; |
| return mrConsume; |
| } |
| return AwtComponent::HandleEvent(msg, synthetic); |
| } |
| |
| void AwtCanvas::_SetEraseBackground(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SetEraseBackgroundStruct *sebs = (SetEraseBackgroundStruct *)param; |
| jobject canvas = sebs->canvas; |
| jboolean doErase = sebs->doErase; |
| jboolean doEraseOnResize = sebs->doEraseOnResize; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(canvas, ret); |
| |
| AwtCanvas *c = (AwtCanvas*)pData; |
| c->m_eraseBackground = doErase; |
| c->m_eraseBackgroundOnResize = doEraseOnResize; |
| |
| ret: |
| env->DeleteGlobalRef(canvas); |
| delete sebs; |
| } |
| |
| |
| /************************************************************************ |
| * WCanvasPeer native methods |
| */ |
| |
| extern "C" { |
| |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WCanvasPeer_create(JNIEnv *env, jobject self, |
| jobject parent) |
| { |
| TRY; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_RETURN(parent); |
| AwtToolkit::CreateComponent(self, parent, |
| (AwtToolkit::ComponentFactory) |
| AwtCanvas::Create); |
| JNI_CHECK_PEER_CREATION_RETURN(self); |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WCanvasPeer |
| * Method: setNativeBackgroundErase |
| * Signature: (Z)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WCanvasPeer_setNativeBackgroundErase(JNIEnv *env, |
| jobject self, |
| jboolean doErase, |
| jboolean doEraseOnResize) |
| { |
| TRY; |
| |
| SetEraseBackgroundStruct *sebs = new SetEraseBackgroundStruct; |
| sebs->canvas = env->NewGlobalRef(self); |
| sebs->doErase = doErase; |
| sebs->doEraseOnResize = doEraseOnResize; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtCanvas::_SetEraseBackground, sebs); |
| // sebs and global ref are deleted in _SetEraseBackground() |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| } /* extern "C" */ |