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
AwtCanvas()45 AwtCanvas::AwtCanvas() {
46 m_eraseBackground = JNI_TRUE;
47 m_eraseBackgroundOnResize = JNI_TRUE;
48 }
49
~AwtCanvas()50 AwtCanvas::~AwtCanvas() {
51 }
52
GetClassName()53 LPCTSTR AwtCanvas::GetClassName() {
54 return TEXT("SunAwtCanvas");
55 }
56
57 /*
58 * Create a new AwtCanvas object and window.
59 */
Create(jobject self,jobject hParent)60 AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent)
61 {
62 DASSERT(AwtToolkit::IsMainThread());
63 TRY;
64 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
65
66 jobject target = NULL;
67 jobject graphicsConfig = NULL;
68 jclass canvasClass = NULL;
69 jclass win32cls = NULL;
70
71 AwtCanvas *canvas = NULL;
72
73 try {
74 if (env->EnsureLocalCapacity(1) < 0) {
75 return NULL;
76 }
77
78 PDATA pData;
79 AwtComponent* parent;
80
81 JNI_CHECK_PEER_GOTO(hParent, done);
82 parent = (AwtCanvas*)pData;
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
WmEraseBkgnd(HDC hDC,BOOL & didErase)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 */
WmPaint(HDC)190 MsgRouting AwtCanvas::WmPaint(HDC)
191 {
192 PaintUpdateRgn(NULL);
193 return mrConsume;
194 }
195
HandleEvent(MSG * msg,BOOL synthetic)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
_SetEraseBackground(void * param)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
Java_sun_awt_windows_WCanvasPeer_create(JNIEnv * env,jobject self,jobject parent)234 Java_sun_awt_windows_WCanvasPeer_create(JNIEnv *env, jobject self,
235 jobject parent)
236 {
237 TRY;
238
239 AwtToolkit::CreateComponent(self, parent,
240 (AwtToolkit::ComponentFactory)
241 AwtCanvas::Create);
242
243 CATCH_BAD_ALLOC;
244 }
245
246 /*
247 * Class: sun_awt_windows_WCanvasPeer
248 * Method: setNativeBackgroundErase
249 * Signature: (Z)V
250 */
251 JNIEXPORT void JNICALL
Java_sun_awt_windows_WCanvasPeer_setNativeBackgroundErase(JNIEnv * env,jobject self,jboolean doErase,jboolean doEraseOnResize)252 Java_sun_awt_windows_WCanvasPeer_setNativeBackgroundErase(JNIEnv *env,
253 jobject self,
254 jboolean doErase,
255 jboolean doEraseOnResize)
256 {
257 TRY;
258
259 SetEraseBackgroundStruct *sebs = new SetEraseBackgroundStruct;
260 sebs->canvas = env->NewGlobalRef(self);
261 sebs->doErase = doErase;
262 sebs->doEraseOnResize = doEraseOnResize;
263
264 AwtToolkit::GetInstance().SyncCall(AwtCanvas::_SetEraseBackground, sebs);
265 // sebs and global ref are deleted in _SetEraseBackground()
266
267 CATCH_BAD_ALLOC;
268 }
269
270 } /* extern "C" */
271