1 /*
2 * Copyright (c) 1996, 2017, 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.h"
27
28 #include <jlong.h>
29
30 #include "awt_Component.h"
31 #include "awt_Container.h"
32 #include "awt_Frame.h"
33 #include "awt_Dialog.h"
34 #include "awt_Insets.h"
35 #include "awt_Panel.h"
36 #include "awt_Toolkit.h"
37 #include "awt_Window.h"
38 #include "awt_Win32GraphicsDevice.h"
39 #include "awt_BitmapUtil.h"
40 #include "awt_IconCursor.h"
41 #include "ComCtl32Util.h"
42
43 #include "java_awt_Insets.h"
44 #include <java_awt_Container.h>
45 #include <java_awt_event_ComponentEvent.h>
46 #include "sun_awt_windows_WCanvasPeer.h"
47
48 #include <windowsx.h>
49 #include <math.h>
50 #if !defined(__int3264)
51 typedef __int32 LONG_PTR;
52 #endif // __int3264
53
54 #if defined(_MSC_VER) && _MSC_VER >= 1800
55 # define ROUND_TO_INT(num) ((int) round(num))
56 #else
57 # define ROUND_TO_INT(num) ((int) floor((num) + 0.5))
58 #endif
59 // Used for Swing's Menu/Tooltip animation Support
60 const int UNSPECIFIED = 0;
61 const int TOOLTIP = 1;
62 const int MENU = 2;
63 const int SUBMENU = 3;
64 const int POPUPMENU = 4;
65 const int COMBOBOX_POPUP = 5;
66 const int TYPES_COUNT = 6;
67 jint windowTYPES[TYPES_COUNT];
68
69
70 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
71 */
72
73 /***********************************************************************/
74 // struct for _SetAlwaysOnTop() method
75 struct SetAlwaysOnTopStruct {
76 jobject window;
77 jboolean value;
78 };
79 // struct for _SetTitle() method
80 struct SetTitleStruct {
81 jobject window;
82 jstring title;
83 };
84 // struct for _SetResizable() method
85 struct SetResizableStruct {
86 jobject window;
87 jboolean resizable;
88 };
89 // struct for _UpdateInsets() method
90 struct UpdateInsetsStruct {
91 jobject window;
92 jobject insets;
93 };
94 // struct for _ReshapeFrame() method
95 struct ReshapeFrameStruct {
96 jobject frame;
97 jint x, y;
98 jint w, h;
99 };
100 // struct for _SetIconImagesData
101 struct SetIconImagesDataStruct {
102 jobject window;
103 jintArray iconRaster;
104 jint w, h;
105 jintArray smallIconRaster;
106 jint smw, smh;
107 };
108 // struct for _SetMinSize() method
109 // and other methods setting sizes
110 struct SizeStruct {
111 jobject window;
112 jint w, h;
113 };
114 // struct for _SetFocusableWindow() method
115 struct SetFocusableWindowStruct {
116 jobject window;
117 jboolean isFocusableWindow;
118 };
119 // struct for _ModalDisable() method
120 struct ModalDisableStruct {
121 jobject window;
122 jlong blockerHWnd;
123 };
124 // struct for _SetOpacity() method
125 struct OpacityStruct {
126 jobject window;
127 jint iOpacity;
128 };
129 // struct for _SetOpaque() method
130 struct OpaqueStruct {
131 jobject window;
132 jboolean isOpaque;
133 };
134 // struct for _UpdateWindow() method
135 struct UpdateWindowStruct {
136 jobject window;
137 jintArray data;
138 HBITMAP hBitmap;
139 jint width, height;
140 };
141 // Struct for _RequestWindowFocus() method
142 struct RequestWindowFocusStruct {
143 jobject component;
144 jboolean isMouseEventCause;
145 };
146 // struct for _RepositionSecurityWarning() method
147 struct RepositionSecurityWarningStruct {
148 jobject window;
149 };
150
151 struct SetFullScreenExclusiveModeStateStruct {
152 jobject window;
153 jboolean isFSEMState;
154 };
155
156 // struct for _WindowDPIChange() method
157 struct ScaleStruct {
158 jobject window;
159 jint prevScreen;
160 jfloat prevScaleX;
161 jfloat prevScaleY;
162 jint screen;
163 jfloat scaleX;
164 jfloat scaleY;
165 };
166
167 struct OverrideHandle {
168 jobject frame;
169 HWND handle;
170 };
171
172 /************************************************************************
173 * AwtWindow fields
174 */
175
176 jfieldID AwtWindow::warningStringID;
177 jfieldID AwtWindow::locationByPlatformID;
178 jfieldID AwtWindow::autoRequestFocusID;
179 jfieldID AwtWindow::securityWarningWidthID;
180 jfieldID AwtWindow::securityWarningHeightID;
181
182 jfieldID AwtWindow::sysXID;
183 jfieldID AwtWindow::sysYID;
184 jfieldID AwtWindow::sysWID;
185 jfieldID AwtWindow::sysHID;
186 jfieldID AwtWindow::windowTypeID;
187
188 jmethodID AwtWindow::getWarningStringMID;
189 jmethodID AwtWindow::calculateSecurityWarningPositionMID;
190 jmethodID AwtWindow::windowTypeNameMID;
191
192 int AwtWindow::ms_instanceCounter = 0;
193 HHOOK AwtWindow::ms_hCBTFilter;
194 AwtWindow * AwtWindow::m_grabbedWindow = NULL;
195 BOOL AwtWindow::sm_resizing = FALSE;
196 UINT AwtWindow::untrustedWindowsCounter = 0;
197
198 /************************************************************************
199 * AwtWindow class methods
200 */
201
AwtWindow()202 AwtWindow::AwtWindow() {
203 m_sizePt.x = m_sizePt.y = 0;
204 m_owningFrameDialog = NULL;
205 m_isResizable = FALSE;//Default value is replaced after construction
206 m_minSize.x = m_minSize.y = 0;
207 m_hIcon = NULL;
208 m_hIconSm = NULL;
209 m_iconInherited = FALSE;
210 VERIFY(::SetRectEmpty(&m_insets));
211 VERIFY(::SetRectEmpty(&m_old_insets));
212 VERIFY(::SetRectEmpty(&m_warningRect));
213
214 // what's the best initial value?
215 m_screenNum = -1;
216 ms_instanceCounter++;
217 m_grabbed = FALSE;
218 m_isFocusableWindow = TRUE;
219 m_isRetainingHierarchyZOrder = FALSE;
220 m_filterFocusAndActivation = FALSE;
221
222 if (AwtWindow::ms_instanceCounter == 1) {
223 AwtWindow::ms_hCBTFilter =
224 ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtWindow::CBTFilter,
225 0, AwtToolkit::MainThread());
226 }
227
228 m_opaque = TRUE;
229 m_opacity = 0xff;
230
231
232 warningString = NULL;
233 warningWindow = NULL;
234 securityTooltipWindow = NULL;
235 securityWarningAnimationStage = 0;
236 currentWmSizeState = SIZE_RESTORED;
237
238 hContentBitmap = NULL;
239
240 ::InitializeCriticalSection(&contentBitmapCS);
241
242 m_windowType = NORMAL;
243 m_alwaysOnTop = false;
244
245 fullScreenExclusiveModeState = FALSE;
246 m_winSizeMove = FALSE;
247 prevScaleRec.screen = -1;
248 prevScaleRec.scaleX = -1.0f;
249 prevScaleRec.scaleY = -1.0f;
250 m_overriddenHwnd = NULL;
251 }
252
~AwtWindow()253 AwtWindow::~AwtWindow()
254 {
255 if (warningString != NULL) {
256 delete [] warningString;
257 }
258 DeleteContentBitmap();
259 ::DeleteCriticalSection(&contentBitmapCS);
260 }
261
Dispose()262 void AwtWindow::Dispose()
263 {
264 // Fix 4745575 GDI Resource Leak
265 // MSDN
266 // Before a window is destroyed (that is, before it returns from processing
267 // the WM_NCDESTROY message), an application must remove all entries it has
268 // added to the property list. The application must use the RemoveProp function
269 // to remove the entries.
270
271 if (--AwtWindow::ms_instanceCounter == 0) {
272 ::UnhookWindowsHookEx(AwtWindow::ms_hCBTFilter);
273 }
274
275 ::RemoveProp(GetHWnd(), ModalBlockerProp);
276
277 if (m_grabbedWindow == this) {
278 Ungrab();
279 }
280 if ((m_hIcon != NULL) && !m_iconInherited) {
281 ::DestroyIcon(m_hIcon);
282 }
283 if ((m_hIconSm != NULL) && !m_iconInherited) {
284 ::DestroyIcon(m_hIconSm);
285 }
286
287 AwtCanvas::Dispose();
288 }
289
290 void
Grab()291 AwtWindow::Grab() {
292 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
293 if (m_grabbedWindow != NULL) {
294 m_grabbedWindow->Ungrab();
295 }
296 m_grabbed = TRUE;
297 m_grabbedWindow = this;
298 if (AwtComponent::GetFocusedWindow() == NULL && IsFocusableWindow()) {
299 // we shouldn't perform grab in this case (see 4841881 & 6539458)
300 Ungrab();
301 } else if (GetHWnd() != AwtComponent::GetFocusedWindow()) {
302 _ToFront(env->NewGlobalRef(GetPeer(env)));
303 // Global ref was deleted in _ToFront
304 }
305 }
306
307 void
Ungrab(BOOL doPost)308 AwtWindow::Ungrab(BOOL doPost) {
309 if (m_grabbed && m_grabbedWindow == this) {
310 if (doPost) {
311 PostUngrabEvent();
312 }
313 m_grabbedWindow = NULL;
314 m_grabbed = FALSE;
315 }
316 }
317
318 void
Ungrab()319 AwtWindow::Ungrab() {
320 Ungrab(TRUE);
321 }
322
_Grab(void * param)323 void AwtWindow::_Grab(void * param) {
324 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
325
326 jobject self = (jobject)param;
327
328 if (env->EnsureLocalCapacity(1) < 0)
329 {
330 env->DeleteGlobalRef(self);
331 return;
332 }
333
334 AwtWindow *p = NULL;
335
336 PDATA pData;
337 JNI_CHECK_PEER_GOTO(self, ret);
338 p = (AwtWindow *)pData;
339 p->Grab();
340
341 ret:
342 env->DeleteGlobalRef(self);
343 }
344
_Ungrab(void * param)345 void AwtWindow::_Ungrab(void * param) {
346 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
347
348 jobject self = (jobject)param;
349
350 if (env->EnsureLocalCapacity(1) < 0)
351 {
352 env->DeleteGlobalRef(self);
353 return;
354 }
355
356 AwtWindow *p = NULL;
357
358 PDATA pData;
359 JNI_CHECK_PEER_GOTO(self, ret);
360 p = (AwtWindow *)pData;
361 p->Ungrab(FALSE);
362
363 ret:
364 env->DeleteGlobalRef(self);
365 }
366
WmNcMouseDown(WPARAM hitTest,int x,int y,int button)367 MsgRouting AwtWindow::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
368 if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
369 m_grabbedWindow->Ungrab();
370 }
371 return AwtCanvas::WmNcMouseDown(hitTest, x, y, button);
372 }
373
WmWindowPosChanging(LPARAM windowPos)374 MsgRouting AwtWindow::WmWindowPosChanging(LPARAM windowPos) {
375 return mrDoDefault;
376 }
377
RepositionSecurityWarning(JNIEnv * env)378 void AwtWindow::RepositionSecurityWarning(JNIEnv *env)
379 {
380 RECT rect;
381 CalculateWarningWindowBounds(env, &rect);
382
383 ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
384 rect.left, rect.top,
385 rect.right - rect.left, rect.bottom - rect.top,
386 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |
387 SWP_NOOWNERZORDER
388 );
389 }
390
WmWindowPosChanged(LPARAM windowPos)391 MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) {
392 WINDOWPOS * wp = (WINDOWPOS *)windowPos;
393
394 // Reposition the warning window
395 if (IsUntrusted() && warningWindow != NULL) {
396 if (wp->flags & SWP_HIDEWINDOW) {
397 UpdateSecurityWarningVisibility();
398 }
399
400 RepositionSecurityWarning((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));
401
402 if (wp->flags & SWP_SHOWWINDOW) {
403 UpdateSecurityWarningVisibility();
404 }
405 }
406
407 if (wp->flags & SWP_HIDEWINDOW) {
408 EnableTranslucency(FALSE);
409 }
410 if (wp->flags & SWP_SHOWWINDOW) {
411 EnableTranslucency(TRUE);
412 }
413
414 return mrDoDefault;
415 }
416
GetClassName()417 LPCTSTR AwtWindow::GetClassName() {
418 return TEXT("SunAwtWindow");
419 }
420
FillClassInfo(WNDCLASSEX * lpwc)421 void AwtWindow::FillClassInfo(WNDCLASSEX *lpwc)
422 {
423 AwtComponent::FillClassInfo(lpwc);
424 /*
425 * This line causes bug #4189244 (Swing Popup menu is not being refreshed (cleared) under a Dialog)
426 * so it's comment out (son@sparc.spb.su)
427 *
428 * lpwc->style |= CS_SAVEBITS; // improve pull-down menu performance
429 */
430 lpwc->cbWndExtra = DLGWINDOWEXTRA;
431 }
432
IsWarningWindow(HWND hWnd)433 bool AwtWindow::IsWarningWindow(HWND hWnd)
434 {
435 const UINT len = 128;
436 TCHAR windowClassName[len];
437
438 ::RealGetWindowClass(hWnd, windowClassName, len);
439 return 0 == _tcsncmp(windowClassName,
440 AwtWindow::GetWarningWindowClassName(), len);
441 }
442
CBTFilter(int nCode,WPARAM wParam,LPARAM lParam)443 LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam)
444 {
445 if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
446 HWND hWnd = (HWND)wParam;
447 AwtComponent *comp = AwtComponent::GetComponent(hWnd);
448
449 if (comp == NULL) {
450 // Check if it's a security warning icon
451 // See: 5091224, 6181725, 6732583
452 if (AwtWindow::IsWarningWindow(hWnd)) {
453 return 1;
454 }
455 } else {
456 if (comp->IsTopLevel()) {
457 AwtWindow* win = (AwtWindow*)comp;
458
459 if (!win->IsFocusableWindow() ||
460 win->m_filterFocusAndActivation)
461 {
462 return 1; // Don't change focus/activation.
463 }
464 }
465 }
466 }
467 return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
468 }
469
InitSecurityWarningSize(JNIEnv * env)470 void AwtWindow::InitSecurityWarningSize(JNIEnv *env)
471 {
472 warningWindowWidth = ::GetSystemMetrics(SM_CXSMICON);
473 warningWindowHeight = ::GetSystemMetrics(SM_CYSMICON);
474
475 jobject target = GetTarget(env);
476
477 env->SetIntField(target, AwtWindow::securityWarningWidthID,
478 warningWindowWidth);
479 env->SetIntField(target, AwtWindow::securityWarningHeightID,
480 warningWindowHeight);
481
482 env->DeleteLocalRef(target);
483 }
484
CreateHWnd(JNIEnv * env,LPCWSTR title,DWORD windowStyle,DWORD windowExStyle,int x,int y,int w,int h,HWND hWndParent,HMENU hMenu,COLORREF colorForeground,COLORREF colorBackground,jobject peer)485 void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title,
486 DWORD windowStyle,
487 DWORD windowExStyle,
488 int x, int y, int w, int h,
489 HWND hWndParent, HMENU hMenu,
490 COLORREF colorForeground,
491 COLORREF colorBackground,
492 jobject peer)
493 {
494 // Retrieve the warning string
495 // Note: we need to get it before CreateHWnd() happens because
496 // the isUntrusted() method may be invoked while the HWND
497 // is being created in response to some window messages.
498 jobject target = env->GetObjectField(peer, AwtObject::targetID);
499 jstring javaWarningString =
500 (jstring)env->CallObjectMethod(target, AwtWindow::getWarningStringMID);
501
502 if (javaWarningString != NULL) {
503 size_t length = env->GetStringLength(javaWarningString) + 1;
504 warningString = new WCHAR[length];
505 env->GetStringRegion(javaWarningString, 0,
506 static_cast<jsize>(length - 1), reinterpret_cast<jchar*>(warningString));
507 warningString[length-1] = L'\0';
508
509 env->DeleteLocalRef(javaWarningString);
510 }
511 env->DeleteLocalRef(target);
512
513 InitType(env, peer);
514 JNU_CHECK_EXCEPTION(env);
515
516 TweakStyle(windowStyle, windowExStyle);
517
518 AwtCanvas::CreateHWnd(env, title,
519 windowStyle,
520 windowExStyle,
521 x, y, w, h,
522 hWndParent, hMenu,
523 colorForeground,
524 colorBackground,
525 peer);
526
527 // Now we need to create the warning window.
528 CreateWarningWindow(env);
529 }
530
CreateWarningWindow(JNIEnv * env)531 void AwtWindow::CreateWarningWindow(JNIEnv *env)
532 {
533 if (!IsUntrusted()) {
534 return;
535 }
536
537 if (++AwtWindow::untrustedWindowsCounter == 1) {
538 AwtToolkit::GetInstance().InstallMouseLowLevelHook();
539 }
540
541 InitSecurityWarningSize(env);
542
543 RECT rect;
544 CalculateWarningWindowBounds(env, &rect);
545
546 RegisterWarningWindowClass();
547 warningWindow = ::CreateWindowEx(
548 WS_EX_NOACTIVATE,
549 GetWarningWindowClassName(),
550 warningString,
551 WS_POPUP,
552 rect.left, rect.top,
553 rect.right - rect.left, rect.bottom - rect.top,
554 GetHWnd(), // owner
555 NULL, // menu
556 AwtToolkit::GetInstance().GetModuleHandle(),
557 NULL // lParam
558 );
559 if (warningWindow == NULL) {
560 //XXX: actually this is bad... We didn't manage to create the window.
561 return;
562 }
563
564 HICON hIcon = GetSecurityWarningIcon();
565
566 ICONINFO ii;
567 ::GetIconInfo(hIcon, &ii);
568
569 //Note: we assume that every security icon has exactly the same shape.
570 HRGN rgn = BitmapUtil::BitmapToRgn(ii.hbmColor);
571 if (rgn) {
572 ::SetWindowRgn(warningWindow, rgn, TRUE);
573 }
574
575 // Now we need to create the tooltip control for this window.
576 if (!ComCtl32Util::GetInstance().IsToolTipControlInitialized()) {
577 return;
578 }
579
580 securityTooltipWindow = ::CreateWindowEx(
581 WS_EX_TOPMOST,
582 TOOLTIPS_CLASS,
583 NULL,
584 WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
585 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
586 warningWindow,
587 NULL,
588 AwtToolkit::GetInstance().GetModuleHandle(),
589 NULL
590 );
591
592 ::SetWindowPos(securityTooltipWindow,
593 HWND_TOPMOST, 0, 0, 0, 0,
594 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
595
596
597 // We currently don't expect changing the size of the window,
598 // hence we may not care of updating the TOOL position/size.
599 ::GetClientRect(warningWindow, &rect);
600
601 TOOLINFO ti;
602
603 ti.cbSize = sizeof(ti);
604 ti.uFlags = TTF_SUBCLASS;
605 ti.hwnd = warningWindow;
606 ti.hinst = AwtToolkit::GetInstance().GetModuleHandle();
607 ti.uId = 0;
608 ti.lpszText = warningString;
609 ti.rect.left = rect.left;
610 ti.rect.top = rect.top;
611 ti.rect.right = rect.right;
612 ti.rect.bottom = rect.bottom;
613
614 ::SendMessage(securityTooltipWindow, TTM_ADDTOOL,
615 0, (LPARAM) (LPTOOLINFO) &ti);
616 }
617
DestroyWarningWindow()618 void AwtWindow::DestroyWarningWindow()
619 {
620 if (!IsUntrusted()) {
621 return;
622 }
623 if (--AwtWindow::untrustedWindowsCounter == 0) {
624 AwtToolkit::GetInstance().UninstallMouseLowLevelHook();
625 }
626 if (warningWindow != NULL) {
627 // Note that the warningWindow is an owned window, and hence
628 // it would be destroyed automatically. However, the window
629 // class may only be unregistered if there's no any single
630 // window left using this class. Thus, we're destroying the
631 // warning window manually. Note that the tooltip window
632 // will be destroyed automatically because it's an owned
633 // window as well.
634 ::DestroyWindow(warningWindow);
635 warningWindow = NULL;
636 securityTooltipWindow = NULL;
637 UnregisterWarningWindowClass();
638 }
639 }
640
DestroyHWnd()641 void AwtWindow::DestroyHWnd()
642 {
643 DestroyWarningWindow();
644 AwtCanvas::DestroyHWnd();
645 }
646
GetWarningWindowClassName()647 LPCTSTR AwtWindow::GetWarningWindowClassName()
648 {
649 return TEXT("SunAwtWarningWindow");
650 }
651
FillWarningWindowClassInfo(WNDCLASS * lpwc)652 void AwtWindow::FillWarningWindowClassInfo(WNDCLASS *lpwc)
653 {
654 lpwc->style = 0L;
655 lpwc->lpfnWndProc = (WNDPROC)WarningWindowProc;
656 lpwc->cbClsExtra = 0;
657 lpwc->cbWndExtra = 0;
658 lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(),
659 lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon();
660 lpwc->hCursor = ::LoadCursor(NULL, IDC_ARROW);
661 lpwc->hbrBackground = NULL;
662 lpwc->lpszMenuName = NULL;
663 lpwc->lpszClassName = AwtWindow::GetWarningWindowClassName();
664 }
665
RegisterWarningWindowClass()666 void AwtWindow::RegisterWarningWindowClass()
667 {
668 WNDCLASS wc;
669
670 ::ZeroMemory(&wc, sizeof(wc));
671
672 if (!::GetClassInfo(AwtToolkit::GetInstance().GetModuleHandle(),
673 AwtWindow::GetWarningWindowClassName(), &wc))
674 {
675 AwtWindow::FillWarningWindowClassInfo(&wc);
676 ATOM atom = ::RegisterClass(&wc);
677 DASSERT(atom != 0);
678 }
679 }
680
UnregisterWarningWindowClass()681 void AwtWindow::UnregisterWarningWindowClass()
682 {
683 ::UnregisterClass(AwtWindow::GetWarningWindowClassName(), AwtToolkit::GetInstance().GetModuleHandle());
684 }
685
GetSecurityWarningIcon()686 HICON AwtWindow::GetSecurityWarningIcon()
687 {
688 // It is assumed that the icon at index 0 is gray
689 const UINT index = securityAnimationKind == akShow ?
690 securityWarningAnimationStage : 0;
691 HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(index,
692 warningWindowWidth, warningWindowHeight);
693 return ico;
694 }
695
696 // This function calculates the bounds of the warning window and stores them
697 // into the RECT structure pointed by the argument rect.
CalculateWarningWindowBounds(JNIEnv * env,LPRECT rect)698 void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect)
699 {
700 RECT windowBounds;
701 AwtToolkit::GetWindowRect(GetHWnd(), &windowBounds);
702
703 jobject target = GetTarget(env);
704 jobject point2D = env->CallObjectMethod(target,
705 calculateSecurityWarningPositionMID,
706 (jdouble)windowBounds.left, (jdouble)windowBounds.top,
707 (jdouble)(windowBounds.right - windowBounds.left),
708 (jdouble)(windowBounds.bottom - windowBounds.top));
709 env->DeleteLocalRef(target);
710
711 static jclass point2DClassID = NULL;
712 static jmethodID point2DGetXMID = NULL;
713 static jmethodID point2DGetYMID = NULL;
714
715 if (point2DClassID == NULL) {
716 jclass point2DClassIDLocal = env->FindClass("java/awt/geom/Point2D");
717 if (point2DClassIDLocal == NULL) {
718 env->DeleteLocalRef(point2D);
719 return;
720 }
721 point2DClassID = (jclass)env->NewGlobalRef(point2DClassIDLocal);
722 env->DeleteLocalRef(point2DClassIDLocal);
723 }
724
725 if (point2DGetXMID == NULL) {
726 point2DGetXMID = env->GetMethodID(point2DClassID, "getX", "()D");
727 if (point2DGetXMID == NULL) {
728 env->DeleteLocalRef(point2D);
729 return;
730 }
731 }
732 if (point2DGetYMID == NULL) {
733 point2DGetYMID = env->GetMethodID(point2DClassID, "getY", "()D");
734 if (point2DGetYMID == NULL) {
735 env->DeleteLocalRef(point2D);
736 return;
737 }
738 }
739
740
741 int x = (int)env->CallDoubleMethod(point2D, point2DGetXMID);
742 int y = (int)env->CallDoubleMethod(point2D, point2DGetYMID);
743
744 env->DeleteLocalRef(point2D);
745
746 rect->left = x;
747 rect->top = y;
748 rect->right = rect->left + warningWindowWidth;
749 rect->bottom = rect->top + warningWindowHeight;
750 }
751
WarningWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)752 LRESULT CALLBACK AwtWindow::WarningWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
753 {
754 switch (uMsg) {
755 case WM_PAINT:
756 PaintWarningWindow(hwnd);
757 return 0;
758
759 case WM_MOUSEACTIVATE:
760 {
761 // Retrive the owner of the warning window.
762 HWND javaWindow = ::GetParent(hwnd);
763 if (javaWindow) {
764 // If the window is blocked by a modal dialog, substitute
765 // its handle with the topmost blocker.
766 HWND topmostBlocker = GetTopmostModalBlocker(javaWindow);
767 if (::IsWindow(topmostBlocker)) {
768 javaWindow = topmostBlocker;
769 }
770
771 ::BringWindowToTop(javaWindow);
772
773 AwtWindow * window =
774 (AwtWindow*)AwtComponent::GetComponent(javaWindow);
775 if (window == NULL) {
776 // Quite unlikely to go into here, but it's way better
777 // than getting a crash.
778 ::SetForegroundWindow(javaWindow);
779 } else {
780 // Activate the window if it is focusable and inactive
781 if (window->IsFocusableWindow() &&
782 javaWindow != ::GetActiveWindow()) {
783 ::SetForegroundWindow(javaWindow);
784 } else {
785 // ...otherwise just start the animation.
786 window->StartSecurityAnimation(akShow);
787 }
788 }
789
790 // In every case if there's a top-most blocker, we need to
791 // enable modal animation.
792 if (::IsWindow(topmostBlocker)) {
793 AwtDialog::AnimateModalBlocker(topmostBlocker);
794 }
795 }
796 return MA_NOACTIVATEANDEAT;
797 }
798 }
799 return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
800 }
801
PaintWarningWindow(HWND warningWindow)802 void AwtWindow::PaintWarningWindow(HWND warningWindow)
803 {
804 RECT updateRect;
805
806 if (!::GetUpdateRect(warningWindow, &updateRect, FALSE)) {
807 // got nothing to update
808 return;
809 }
810
811 PAINTSTRUCT ps;
812 HDC hdc = ::BeginPaint(warningWindow, &ps);
813 if (hdc == NULL) {
814 // indicates an error
815 return;
816 }
817
818 PaintWarningWindow(warningWindow, hdc);
819
820 ::EndPaint(warningWindow, &ps);
821 }
822
PaintWarningWindow(HWND warningWindow,HDC hdc)823 void AwtWindow::PaintWarningWindow(HWND warningWindow, HDC hdc)
824 {
825 HWND javaWindow = ::GetParent(warningWindow);
826
827 AwtWindow * window = (AwtWindow*)AwtComponent::GetComponent(javaWindow);
828 if (window == NULL) {
829 return;
830 }
831
832 ::DrawIconEx(hdc, 0, 0, window->GetSecurityWarningIcon(),
833 window->warningWindowWidth, window->warningWindowHeight,
834 0, NULL, DI_NORMAL);
835 }
836
837 static const UINT_PTR IDT_AWT_SECURITYANIMATION = 0x102;
838
839 // Approximately 6 times a second. 0.75 seconds total.
840 static const UINT securityAnimationTimerElapse = 150;
841 static const UINT securityAnimationMaxIterations = 5;
842
RepaintWarningWindow()843 void AwtWindow::RepaintWarningWindow()
844 {
845 HDC hdc = ::GetDC(warningWindow);
846 PaintWarningWindow(warningWindow, hdc);
847 ::ReleaseDC(warningWindow, hdc);
848 }
849
SetLayered(HWND window,bool layered)850 void AwtWindow::SetLayered(HWND window, bool layered)
851 {
852 const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE);
853 ::SetWindowLong(window, GWL_EXSTYLE, layered ?
854 ex_style | WS_EX_LAYERED : ex_style & ~WS_EX_LAYERED);
855 }
856
IsLayered(HWND window)857 bool AwtWindow::IsLayered(HWND window)
858 {
859 const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE);
860 return ex_style & WS_EX_LAYERED;
861 }
862
StartSecurityAnimation(AnimationKind kind)863 void AwtWindow::StartSecurityAnimation(AnimationKind kind)
864 {
865 if (!IsUntrusted()) {
866 return;
867 }
868 if (warningWindow == NULL) {
869 return;
870 }
871
872 securityAnimationKind = kind;
873
874 securityWarningAnimationStage = 1;
875 ::SetTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION,
876 securityAnimationTimerElapse, NULL);
877
878 if (securityAnimationKind == akShow) {
879 ::SetWindowPos(warningWindow,
880 IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
881 0, 0, 0, 0,
882 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
883 SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
884
885 ::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0),
886 0xFF, LWA_ALPHA);
887 AwtWindow::SetLayered(warningWindow, false);
888 ::RedrawWindow(warningWindow, NULL, NULL,
889 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
890 } else if (securityAnimationKind == akPreHide) {
891 // Pre-hiding means fading-out. We have to make the window layered.
892 // Note: Some VNC clients do not support layered windows, hence
893 // we dynamically turn it on and off. See 6805231.
894 AwtWindow::SetLayered(warningWindow, true);
895 }
896 }
897
StopSecurityAnimation()898 void AwtWindow::StopSecurityAnimation()
899 {
900 if (!IsUntrusted()) {
901 return;
902 }
903 if (warningWindow == NULL) {
904 return;
905 }
906
907 securityWarningAnimationStage = 0;
908 ::KillTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION);
909
910 switch (securityAnimationKind) {
911 case akHide:
912 case akPreHide:
913 ::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0,
914 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
915 SWP_HIDEWINDOW | SWP_NOOWNERZORDER);
916 break;
917 case akShow:
918 RepaintWarningWindow();
919 break;
920 }
921
922 securityAnimationKind = akNone;
923 }
924
WmTimer(UINT_PTR timerID)925 MsgRouting AwtWindow::WmTimer(UINT_PTR timerID)
926 {
927 if (timerID != IDT_AWT_SECURITYANIMATION) {
928 return mrPassAlong;
929 }
930
931 if (securityWarningAnimationStage == 0) {
932 return mrConsume;
933 }
934
935 securityWarningAnimationStage++;
936 if (securityWarningAnimationStage >= securityAnimationMaxIterations) {
937 if (securityAnimationKind == akPreHide) {
938 // chain real hiding
939 StartSecurityAnimation(akHide);
940 } else {
941 StopSecurityAnimation();
942 }
943 } else {
944 switch (securityAnimationKind) {
945 case akHide:
946 {
947 BYTE opacity = ((int)0xFF *
948 (securityAnimationMaxIterations -
949 securityWarningAnimationStage)) /
950 securityAnimationMaxIterations;
951 ::SetLayeredWindowAttributes(warningWindow,
952 RGB(0, 0, 0), opacity, LWA_ALPHA);
953 }
954 break;
955 case akShow:
956 case akNone: // quite unlikely, but quite safe
957 RepaintWarningWindow();
958 break;
959 }
960 }
961
962 return mrConsume;
963 }
964
965 // The security warning is visible if:
966 // 1. The window has the keyboard window focus, OR
967 // 2. The mouse pointer is located within the window bounds,
968 // or within the security warning icon.
UpdateSecurityWarningVisibility()969 void AwtWindow::UpdateSecurityWarningVisibility()
970 {
971 if (!IsUntrusted()) {
972 return;
973 }
974 if (warningWindow == NULL) {
975 return;
976 }
977
978 bool show = false;
979
980 if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
981 !isFullScreenExclusiveMode())
982 {
983 if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
984 show = true;
985 }
986
987 HWND hwnd = AwtToolkit::GetInstance().GetWindowUnderMouse();
988 if (hwnd == GetHWnd()) {
989 show = true;
990 }
991 if (hwnd == warningWindow) {
992 show = true;
993 }
994 }
995
996 if (show && (!::IsWindowVisible(warningWindow) ||
997 securityAnimationKind == akHide ||
998 securityAnimationKind == akPreHide)) {
999 StartSecurityAnimation(akShow);
1000 }
1001 if (!show && ::IsWindowVisible(warningWindow)) {
1002 StartSecurityAnimation(akPreHide);
1003 }
1004 }
1005
FocusedWindowChanged(HWND from,HWND to)1006 void AwtWindow::FocusedWindowChanged(HWND from, HWND to)
1007 {
1008 AwtWindow * fw = (AwtWindow *)AwtComponent::GetComponent(from);
1009 AwtWindow * tw = (AwtWindow *)AwtComponent::GetComponent(to);
1010
1011 if (fw != NULL) {
1012 fw->UpdateSecurityWarningVisibility();
1013 }
1014 if (tw != NULL) {
1015 tw->UpdateSecurityWarningVisibility();
1016
1017 // Flash on receiving the keyboard focus even if the warning
1018 // has already been shown (e.g. by hovering with the mouse)
1019 tw->StartSecurityAnimation(akShow);
1020 }
1021 }
1022
_RepositionSecurityWarning(void * param)1023 void AwtWindow::_RepositionSecurityWarning(void* param)
1024 {
1025 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1026
1027 RepositionSecurityWarningStruct *rsws =
1028 (RepositionSecurityWarningStruct *)param;
1029 jobject self = rsws->window;
1030
1031 PDATA pData;
1032 JNI_CHECK_PEER_GOTO(self, ret);
1033 AwtWindow *window = (AwtWindow *)pData;
1034
1035 window->RepositionSecurityWarning(env);
1036
1037 ret:
1038 env->DeleteGlobalRef(self);
1039 delete rsws;
1040 }
1041
InitType(JNIEnv * env,jobject peer)1042 void AwtWindow::InitType(JNIEnv *env, jobject peer)
1043 {
1044 jobject type = env->GetObjectField(peer, windowTypeID);
1045 if (type == NULL) {
1046 return;
1047 }
1048
1049 jstring value = (jstring)env->CallObjectMethod(type, windowTypeNameMID);
1050 if (value == NULL) {
1051 env->DeleteLocalRef(type);
1052 return;
1053 }
1054
1055 const char* valueNative = env->GetStringUTFChars(value, 0);
1056 if (valueNative == NULL) {
1057 env->DeleteLocalRef(value);
1058 env->DeleteLocalRef(type);
1059 return;
1060 }
1061
1062 if (strcmp(valueNative, "UTILITY") == 0) {
1063 m_windowType = UTILITY;
1064 } else if (strcmp(valueNative, "POPUP") == 0) {
1065 m_windowType = POPUP;
1066 }
1067
1068 env->ReleaseStringUTFChars(value, valueNative);
1069 env->DeleteLocalRef(value);
1070 env->DeleteLocalRef(type);
1071 }
1072
TweakStyle(DWORD & style,DWORD & exStyle)1073 void AwtWindow::TweakStyle(DWORD & style, DWORD & exStyle)
1074 {
1075 switch (GetType()) {
1076 case UTILITY:
1077 exStyle |= WS_EX_TOOLWINDOW;
1078 break;
1079 case POPUP:
1080 style &= ~WS_OVERLAPPED;
1081 style |= WS_POPUP;
1082 break;
1083 }
1084 }
1085
1086 /* Create a new AwtWindow object and window. */
Create(jobject self,jobject parent)1087 AwtWindow* AwtWindow::Create(jobject self, jobject parent)
1088 {
1089 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1090
1091 jobject target = NULL;
1092 AwtWindow* window = NULL;
1093
1094 try {
1095 if (env->EnsureLocalCapacity(1) < 0) {
1096 return NULL;
1097 }
1098
1099 AwtWindow* awtParent = NULL;
1100
1101 PDATA pData;
1102 if (parent != NULL) {
1103 JNI_CHECK_PEER_GOTO(parent, done);
1104 awtParent = (AwtWindow *)pData;
1105 }
1106
1107 target = env->GetObjectField(self, AwtObject::targetID);
1108 JNI_CHECK_NULL_GOTO(target, "null target", done);
1109
1110 window = new AwtWindow();
1111
1112 {
1113 if (JNU_IsInstanceOfByName(env, target, "javax/swing/Popup$HeavyWeightWindow") > 0) {
1114 window->m_isRetainingHierarchyZOrder = TRUE;
1115 }
1116 if (env->ExceptionCheck()) goto done;
1117 DWORD style = WS_CLIPCHILDREN | WS_POPUP;
1118 DWORD exStyle = WS_EX_NOACTIVATE;
1119 if (GetRTL()) {
1120 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
1121 if (GetRTLReadingOrder())
1122 exStyle |= WS_EX_RTLREADING;
1123 }
1124 if (awtParent != NULL) {
1125 window->InitOwner(awtParent);
1126 } else {
1127 // specify WS_EX_TOOLWINDOW to remove parentless windows from taskbar
1128 exStyle |= WS_EX_TOOLWINDOW;
1129 }
1130 window->CreateHWnd(env, L"",
1131 style, exStyle,
1132 0, 0, 0, 0,
1133 (awtParent != NULL) ? awtParent->GetHWnd() : NULL,
1134 NULL,
1135 ::GetSysColor(COLOR_WINDOWTEXT),
1136 ::GetSysColor(COLOR_WINDOW),
1137 self);
1138
1139 jint x = env->GetIntField(target, AwtComponent::xID);
1140 jint y = env->GetIntField(target, AwtComponent::yID);
1141 jint width = env->GetIntField(target, AwtComponent::widthID);
1142 jint height = env->GetIntField(target, AwtComponent::heightID);
1143
1144 /*
1145 * Initialize icon as inherited from parent if it exists
1146 */
1147 if (parent != NULL) {
1148 window->m_hIcon = awtParent->GetHIcon();
1149 window->m_hIconSm = awtParent->GetHIconSm();
1150 window->m_iconInherited = TRUE;
1151 }
1152 window->DoUpdateIcon();
1153
1154
1155 /*
1156 * Reshape here instead of during create, so that a WM_NCCALCSIZE
1157 * is sent.
1158 */
1159 window->Reshape(x, y, width, height);
1160 }
1161 } catch (...) {
1162 env->DeleteLocalRef(target);
1163 throw;
1164 }
1165
1166 done:
1167 env->DeleteLocalRef(target);
1168 return window;
1169 }
1170
IsOneOfOwnersOf(AwtWindow * wnd)1171 BOOL AwtWindow::IsOneOfOwnersOf(AwtWindow * wnd) {
1172 while (wnd != NULL) {
1173 if (wnd == this || wnd->GetOwningFrameOrDialog() == this) return TRUE;
1174 wnd = (AwtWindow*)GetComponent(::GetWindow(wnd->GetHWnd(), GW_OWNER));
1175 }
1176 return FALSE;
1177 }
1178
InitOwner(AwtWindow * owner)1179 void AwtWindow::InitOwner(AwtWindow *owner)
1180 {
1181 DASSERT(owner != NULL);
1182 AwtWindow *initialOwner = owner;
1183 while (owner != NULL && owner->IsSimpleWindow()) {
1184
1185 HWND ownerOwnerHWND = ::GetWindow(owner->GetHWnd(), GW_OWNER);
1186 if (ownerOwnerHWND == NULL) {
1187 owner = NULL;
1188 break;
1189 }
1190 owner = (AwtWindow *)AwtComponent::GetComponent(ownerOwnerHWND);
1191 }
1192 if (!owner) {
1193 owner = initialOwner->GetOwningFrameOrDialog();
1194 }
1195 m_owningFrameDialog = (AwtFrame *)owner;
1196 }
1197
moveToDefaultLocation()1198 void AwtWindow::moveToDefaultLocation() {
1199 HWND boggy = ::CreateWindow(GetClassName(), L"BOGGY", WS_OVERLAPPED, CW_USEDEFAULT, 0 ,0, 0,
1200 NULL, NULL, NULL, NULL);
1201 RECT defLoc;
1202
1203 // Fixed 6477497: Windows drawn off-screen on Win98, even when java.awt.Window.locationByPlatform is set
1204 // Win9x does not position a window until the window is shown.
1205 // The behavior is slightly opposite to the WinNT (and up), where
1206 // Windows will position the window upon creation of the window.
1207 // That's why we have to manually set the left & top values of
1208 // the defLoc to 0 if the GetWindowRect function returns FALSE.
1209 BOOL result = ::GetWindowRect(boggy, &defLoc);
1210 if (!result) {
1211 defLoc.left = defLoc.top = 0;
1212 }
1213 VERIFY(::DestroyWindow(boggy));
1214 VERIFY(::SetWindowPos(GetHWnd(), NULL, defLoc.left, defLoc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER));
1215 }
1216
Show()1217 void AwtWindow::Show()
1218 {
1219 m_visible = true;
1220 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1221 BOOL done = false;
1222 HWND hWnd = GetHWnd();
1223
1224 if (env->EnsureLocalCapacity(2) < 0) {
1225 return;
1226 }
1227 jobject target = GetTarget(env);
1228 INT nCmdShow;
1229
1230 AwtFrame* owningFrame = GetOwningFrameOrDialog();
1231 if (IsFocusableWindow() && IsAutoRequestFocus() && owningFrame != NULL &&
1232 ::GetForegroundWindow() == owningFrame->GetHWnd())
1233 {
1234 nCmdShow = SW_SHOW;
1235 } else {
1236 nCmdShow = SW_SHOWNA;
1237 }
1238
1239 BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID);
1240
1241 if (locationByPlatform) {
1242 moveToDefaultLocation();
1243 }
1244
1245 EnableTranslucency(TRUE);
1246
1247 // The following block exists to support Menu/Tooltip animation for
1248 // Swing programs in a way which avoids introducing any new public api into
1249 // AWT or Swing.
1250 // This code should eventually be replaced by a better longterm solution
1251 // which might involve tagging java.awt.Window instances with a semantic
1252 // property so platforms can animate/decorate/etc accordingly.
1253 //
1254 if (JNU_IsInstanceOfByName(env, target, "com/sun/java/swing/plaf/windows/WindowsPopupWindow") > 0)
1255 {
1256 // need this global ref to make the class unloadable (see 6500204)
1257 static jclass windowsPopupWindowCls;
1258 static jfieldID windowTypeFID = NULL;
1259 jint windowType = 0;
1260 BOOL animateflag = FALSE;
1261 BOOL fadeflag = FALSE;
1262 DWORD animateStyle = 0;
1263
1264 if (windowTypeFID == NULL) {
1265 // Initialize Window type constants ONCE...
1266
1267 jfieldID windowTYPESFID[TYPES_COUNT];
1268 jclass cls = env->GetObjectClass(target);
1269 windowTypeFID = env->GetFieldID(cls, "windowType", "I");
1270
1271 windowTYPESFID[UNSPECIFIED] = env->GetStaticFieldID(cls, "UNDEFINED_WINDOW_TYPE", "I");
1272 windowTYPESFID[TOOLTIP] = env->GetStaticFieldID(cls, "TOOLTIP_WINDOW_TYPE", "I");
1273 windowTYPESFID[MENU] = env->GetStaticFieldID(cls, "MENU_WINDOW_TYPE", "I");
1274 windowTYPESFID[SUBMENU] = env->GetStaticFieldID(cls, "SUBMENU_WINDOW_TYPE", "I");
1275 windowTYPESFID[POPUPMENU] = env->GetStaticFieldID(cls, "POPUPMENU_WINDOW_TYPE", "I");
1276 windowTYPESFID[COMBOBOX_POPUP] = env->GetStaticFieldID(cls, "COMBOBOX_POPUP_WINDOW_TYPE", "I");
1277
1278 for (int i=0; i < 6; i++) {
1279 windowTYPES[i] = env->GetStaticIntField(cls, windowTYPESFID[i]);
1280 }
1281 windowsPopupWindowCls = (jclass) env->NewGlobalRef(cls);
1282 env->DeleteLocalRef(cls);
1283 }
1284 windowType = env->GetIntField(target, windowTypeFID);
1285
1286 if (windowType == windowTYPES[TOOLTIP]) {
1287 SystemParametersInfo(SPI_GETTOOLTIPANIMATION, 0, &animateflag, 0);
1288 SystemParametersInfo(SPI_GETTOOLTIPFADE, 0, &fadeflag, 0);
1289 if (animateflag) {
1290 // AW_BLEND currently produces runtime parameter error
1291 // animateStyle = fadeflag? AW_BLEND : AW_SLIDE | AW_VER_POSITIVE;
1292 animateStyle = fadeflag? 0 : AW_SLIDE | AW_VER_POSITIVE;
1293 }
1294 } else if (windowType == windowTYPES[MENU] || windowType == windowTYPES[SUBMENU] ||
1295 windowType == windowTYPES[POPUPMENU]) {
1296 SystemParametersInfo(SPI_GETMENUANIMATION, 0, &animateflag, 0);
1297 if (animateflag) {
1298 SystemParametersInfo(SPI_GETMENUFADE, 0, &fadeflag, 0);
1299 if (fadeflag) {
1300 // AW_BLEND currently produces runtime parameter error
1301 //animateStyle = AW_BLEND;
1302 }
1303 if (animateStyle == 0 && !fadeflag) {
1304 animateStyle = AW_SLIDE;
1305 if (windowType == windowTYPES[MENU]) {
1306 animateStyle |= AW_VER_POSITIVE;
1307 } else if (windowType == windowTYPES[SUBMENU]) {
1308 animateStyle |= AW_HOR_POSITIVE;
1309 } else { /* POPUPMENU */
1310 animateStyle |= (AW_VER_POSITIVE | AW_HOR_POSITIVE);
1311 }
1312 }
1313 }
1314 } else if (windowType == windowTYPES[COMBOBOX_POPUP]) {
1315 SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animateflag, 0);
1316 if (animateflag) {
1317 animateStyle = AW_SLIDE | AW_VER_POSITIVE;
1318 }
1319 }
1320
1321 if (animateStyle != 0) {
1322 BOOL result = ::AnimateWindow(hWnd, (DWORD)200, animateStyle);
1323 if (!result) {
1324 // TODO: log message
1325 } else {
1326 // WM_PAINT is not automatically sent when invoking AnimateWindow,
1327 // so force an expose event
1328 RECT rect;
1329 ::GetWindowRect(hWnd,&rect);
1330 ::ScreenToClient(hWnd, (LPPOINT)&rect);
1331 ::InvalidateRect(hWnd, &rect, TRUE);
1332 ::UpdateWindow(hWnd);
1333 done = TRUE;
1334 }
1335 }
1336 }
1337 if (!done) {
1338 // transient windows shouldn't change the owner window's position in the z-order
1339 if (IsRetainingHierarchyZOrder()){
1340 UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER;
1341 if (nCmdShow == SW_SHOWNA) {
1342 flags |= SWP_NOACTIVATE;
1343 }
1344 ::SetWindowPos(GetHWnd(), HWND_TOPMOST, 0, 0, 0, 0, flags);
1345 } else {
1346 ::ShowWindow(GetHWnd(), nCmdShow);
1347 }
1348 }
1349 env->DeleteLocalRef(target);
1350 }
1351
1352 /*
1353 * Get and return the insets for this window (container, really).
1354 * Calculate & cache them while we're at it, for use by AwtGraphics
1355 */
UpdateInsets(jobject insets)1356 BOOL AwtWindow::UpdateInsets(jobject insets)
1357 {
1358 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1359 DASSERT(GetPeer(env) != NULL);
1360 if (env->EnsureLocalCapacity(2) < 0) {
1361 return FALSE;
1362 }
1363
1364 // fix 4167248 : don't update insets when frame is iconified
1365 // to avoid bizarre window/client rectangles
1366 if (::IsIconic(GetHWnd())) {
1367 return FALSE;
1368 }
1369
1370 /*
1371 * Code to calculate insets. Stores results in frame's data
1372 * members, and in the peer's Inset object.
1373 */
1374 RECT outside;
1375 RECT inside;
1376 int extraBottomInsets = 0;
1377
1378 ::GetClientRect(GetHWnd(), &inside);
1379 ::GetWindowRect(GetHWnd(), &outside);
1380
1381 /* Update our inset member */
1382 if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
1383 ::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&inside, 2);
1384 m_insets.top = inside.top - outside.top;
1385 m_insets.bottom = outside.bottom - inside.bottom + extraBottomInsets;
1386 m_insets.left = inside.left - outside.left;
1387 m_insets.right = outside.right - inside.right;
1388 } else {
1389 m_insets.top = -1;
1390 }
1391 if (m_insets.left < 0 || m_insets.top < 0 ||
1392 m_insets.right < 0 || m_insets.bottom < 0)
1393 {
1394 /* This window hasn't been sized yet -- use system metrics. */
1395 jobject target = GetTarget(env);
1396 if (IsUndecorated() == FALSE) {
1397 /* Get outer frame sizes. */
1398 LONG style = GetStyle();
1399 if (style & WS_THICKFRAME) {
1400 m_insets.left = m_insets.right =
1401 ::GetSystemMetrics(SM_CXSIZEFRAME);
1402 m_insets.top = m_insets.bottom =
1403 ::GetSystemMetrics(SM_CYSIZEFRAME);
1404 } else {
1405 m_insets.left = m_insets.right =
1406 ::GetSystemMetrics(SM_CXDLGFRAME);
1407 m_insets.top = m_insets.bottom =
1408 ::GetSystemMetrics(SM_CYDLGFRAME);
1409 }
1410
1411
1412 /* Add in title. */
1413 m_insets.top += ::GetSystemMetrics(SM_CYCAPTION);
1414 }
1415 else {
1416 /* fix for 4418125: Undecorated frames are off by one */
1417 /* undo the -1 set above */
1418 /* Additional fix for 5059656 */
1419 /* Also, 5089312: Window insets should be 0. */
1420 ::memset(&m_insets, 0, sizeof(m_insets));
1421 }
1422
1423 /* Add in menuBar, if any. */
1424 if (JNU_IsInstanceOfByName(env, target, "java/awt/Frame") > 0 &&
1425 ((AwtFrame*)this)->GetMenuBar()) {
1426 m_insets.top += ::GetSystemMetrics(SM_CYMENU);
1427 }
1428 if (env->ExceptionCheck()) {
1429 env->DeleteLocalRef(target);
1430 return FALSE;
1431 }
1432 m_insets.bottom += extraBottomInsets;
1433 env->DeleteLocalRef(target);
1434 }
1435
1436 BOOL insetsChanged = FALSE;
1437
1438 jobject peer = GetPeer(env);
1439 /* Get insets into our peer directly */
1440 jobject peerInsets = (env)->GetObjectField(peer, AwtPanel::insets_ID);
1441 DASSERT(!safe_ExceptionOccurred(env));
1442
1443 if (peerInsets != NULL) { // may have been called during creation
1444 (env)->SetIntField(peerInsets, AwtInsets::topID, ScaleDownY(m_insets.top));
1445 (env)->SetIntField(peerInsets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
1446 (env)->SetIntField(peerInsets, AwtInsets::leftID, ScaleDownX(m_insets.left));
1447 (env)->SetIntField(peerInsets, AwtInsets::rightID, ScaleDownX(m_insets.right));
1448 }
1449 /* Get insets into the Inset object (if any) that was passed */
1450 if (insets != NULL) {
1451 (env)->SetIntField(insets, AwtInsets::topID, ScaleDownY(m_insets.top));
1452 (env)->SetIntField(insets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
1453 (env)->SetIntField(insets, AwtInsets::leftID, ScaleDownX(m_insets.left));
1454 (env)->SetIntField(insets, AwtInsets::rightID, ScaleDownX(m_insets.right));
1455 }
1456 env->DeleteLocalRef(peerInsets);
1457
1458 insetsChanged = !::EqualRect( &m_old_insets, &m_insets );
1459 ::CopyRect( &m_old_insets, &m_insets );
1460
1461 if (insetsChanged) {
1462 // Since insets are changed we need to update the surfaceData object
1463 // to reflect that change
1464 env->CallVoidMethod(peer, AwtComponent::replaceSurfaceDataLaterMID);
1465 }
1466
1467 return insetsChanged;
1468 }
1469
1470 /**
1471 * Sometimes we need the hWnd that actually owns this Window's hWnd (if
1472 * there is an owner).
1473 */
GetTopLevelHWnd()1474 HWND AwtWindow::GetTopLevelHWnd()
1475 {
1476 return m_owningFrameDialog ? m_owningFrameDialog->GetHWnd() :
1477 GetHWnd();
1478 }
1479
1480 /*
1481 * Although this function sends ComponentEvents, it needs to be defined
1482 * here because only top-level windows need to have move and resize
1483 * events fired from native code. All contained windows have these events
1484 * fired from common Java code.
1485 */
SendComponentEvent(jint eventId)1486 void AwtWindow::SendComponentEvent(jint eventId)
1487 {
1488 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1489
1490 static jclass classEvent = NULL;
1491 if (classEvent == NULL) {
1492 if (env->PushLocalFrame(1) < 0)
1493 return;
1494 classEvent = env->FindClass("java/awt/event/ComponentEvent");
1495 if (classEvent != NULL) {
1496 classEvent = (jclass)env->NewGlobalRef(classEvent);
1497 }
1498 env->PopLocalFrame(0);
1499 CHECK_NULL(classEvent);
1500 }
1501 static jmethodID eventInitMID = NULL;
1502 if (eventInitMID == NULL) {
1503 eventInitMID = env->GetMethodID(classEvent, "<init>",
1504 "(Ljava/awt/Component;I)V");
1505 CHECK_NULL(eventInitMID);
1506 }
1507 if (env->EnsureLocalCapacity(2) < 0) {
1508 return;
1509 }
1510 jobject target = GetTarget(env);
1511 jobject event = env->NewObject(classEvent, eventInitMID,
1512 target, eventId);
1513 DASSERT(!safe_ExceptionOccurred(env));
1514 DASSERT(event != NULL);
1515 if (event == NULL) {
1516 env->DeleteLocalRef(target);
1517 return;
1518 }
1519 SendEvent(event);
1520
1521 env->DeleteLocalRef(target);
1522 env->DeleteLocalRef(event);
1523 }
1524
SendWindowEvent(jint id,HWND opposite,jint oldState,jint newState)1525 void AwtWindow::SendWindowEvent(jint id, HWND opposite,
1526 jint oldState, jint newState)
1527 {
1528 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1529
1530 static jclass wClassEvent;
1531 if (wClassEvent == NULL) {
1532 if (env->PushLocalFrame(1) < 0)
1533 return;
1534 wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
1535 if (wClassEvent != NULL) {
1536 wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
1537 }
1538 env->PopLocalFrame(0);
1539 if (wClassEvent == NULL) {
1540 return;
1541 }
1542 }
1543
1544 static jmethodID wEventInitMID;
1545 if (wEventInitMID == NULL) {
1546 wEventInitMID =
1547 env->GetMethodID(wClassEvent, "<init>",
1548 "(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
1549 DASSERT(wEventInitMID);
1550 if (wEventInitMID == NULL) {
1551 return;
1552 }
1553 }
1554
1555 static jclass sequencedEventCls;
1556 if (sequencedEventCls == NULL) {
1557 jclass sequencedEventClsLocal
1558 = env->FindClass("java/awt/SequencedEvent");
1559 DASSERT(sequencedEventClsLocal);
1560 CHECK_NULL(sequencedEventClsLocal);
1561 sequencedEventCls =
1562 (jclass)env->NewGlobalRef(sequencedEventClsLocal);
1563 env->DeleteLocalRef(sequencedEventClsLocal);
1564 }
1565
1566 static jmethodID sequencedEventConst;
1567 if (sequencedEventConst == NULL) {
1568 sequencedEventConst =
1569 env->GetMethodID(sequencedEventCls, "<init>",
1570 "(Ljava/awt/AWTEvent;)V");
1571 CHECK_NULL(sequencedEventConst);
1572 }
1573
1574 static jclass windowCls = NULL;
1575 if (windowCls == NULL) {
1576 jclass windowClsLocal = env->FindClass("java/awt/Window");
1577 CHECK_NULL(windowClsLocal);
1578 windowCls = (jclass)env->NewGlobalRef(windowClsLocal);
1579 env->DeleteLocalRef(windowClsLocal);
1580 CHECK_NULL(windowCls);
1581 }
1582
1583 if (env->EnsureLocalCapacity(3) < 0) {
1584 return;
1585 }
1586
1587 jobject target = GetTarget(env);
1588 jobject jOpposite = NULL;
1589 if (opposite != NULL) {
1590 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
1591 if (awtOpposite != NULL) {
1592 jOpposite = awtOpposite->GetTarget(env);
1593 if ((jOpposite != NULL) &&
1594 !env->IsInstanceOf(jOpposite, windowCls)) {
1595 env->DeleteLocalRef(jOpposite);
1596 jOpposite = NULL;
1597
1598 HWND parent = AwtComponent::GetTopLevelParentForWindow(opposite);
1599 if ((parent != NULL) && (parent != opposite)) {
1600 if (parent == GetHWnd()) {
1601 jOpposite = env->NewLocalRef(target);
1602 } else {
1603 AwtComponent* awtParent = AwtComponent::GetComponent(parent);
1604 if (awtParent != NULL) {
1605 jOpposite = awtParent->GetTarget(env);
1606 if ((jOpposite != NULL) &&
1607 !env->IsInstanceOf(jOpposite, windowCls)) {
1608 env->DeleteLocalRef(jOpposite);
1609 jOpposite = NULL;
1610 }
1611 }
1612 }
1613 }
1614 }
1615 }
1616 }
1617 jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
1618 jOpposite, oldState, newState, ::JVM_CurrentTimeMillis(NULL, 0));
1619 DASSERT(!safe_ExceptionOccurred(env));
1620 DASSERT(event != NULL);
1621 if (jOpposite != NULL) {
1622 env->DeleteLocalRef(jOpposite); jOpposite = NULL;
1623 }
1624 env->DeleteLocalRef(target); target = NULL;
1625 CHECK_NULL(event);
1626
1627 if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
1628 id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS)
1629 {
1630 jobject sequencedEvent = env->NewObject(sequencedEventCls,
1631 sequencedEventConst,
1632 event);
1633 DASSERT(!safe_ExceptionOccurred(env));
1634 DASSERT(sequencedEvent != NULL);
1635 env->DeleteLocalRef(event);
1636 event = sequencedEvent;
1637 }
1638
1639 SendEvent(event);
1640
1641 env->DeleteLocalRef(event);
1642 }
1643
AwtSetActiveWindow(BOOL isMouseEventCause,UINT hittest)1644 BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
1645 {
1646 // We used to reject non mouse window activation if our app wasn't active.
1647 // This code since has been removed as the fix for 7185280
1648
1649 HWND proxyContainerHWnd = GetProxyToplevelContainer();
1650 HWND proxyHWnd = GetProxyFocusOwner();
1651
1652 if (proxyContainerHWnd == NULL || proxyHWnd == NULL) {
1653 return FALSE;
1654 }
1655
1656 // Activate the proxy toplevel container
1657 if (::GetActiveWindow() != proxyContainerHWnd) {
1658 sm_suppressFocusAndActivation = TRUE;
1659 ::BringWindowToTop(proxyContainerHWnd);
1660 ::SetForegroundWindow(proxyContainerHWnd);
1661 sm_suppressFocusAndActivation = FALSE;
1662
1663 if (::GetActiveWindow() != proxyContainerHWnd) {
1664 return FALSE; // activation has been rejected
1665 }
1666 }
1667
1668 // Focus the proxy itself
1669 if (::GetFocus() != proxyHWnd) {
1670 sm_suppressFocusAndActivation = TRUE;
1671 ::SetFocus(proxyHWnd);
1672 sm_suppressFocusAndActivation = FALSE;
1673
1674 if (::GetFocus() != proxyHWnd) {
1675 return FALSE; // focus has been rejected (that is unlikely)
1676 }
1677 }
1678
1679 const HWND focusedWindow = AwtComponent::GetFocusedWindow();
1680 if (focusedWindow != GetHWnd()) {
1681 if (focusedWindow != NULL) {
1682 // Deactivate the old focused window
1683 AwtWindow::SynthesizeWmActivate(FALSE, focusedWindow, GetHWnd());
1684 }
1685 // Activate the new focused window.
1686 AwtWindow::SynthesizeWmActivate(TRUE, GetHWnd(), focusedWindow);
1687 }
1688 return TRUE;
1689 }
1690
WmActivate(UINT nState,BOOL fMinimized,HWND opposite)1691 MsgRouting AwtWindow::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
1692 {
1693 jint type;
1694
1695 if (nState != WA_INACTIVE) {
1696 type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
1697 AwtComponent::SetFocusedWindow(GetHWnd());
1698 } else {
1699 // The owner is not necassarily getting WM_ACTIVATE(WA_INACTIVE).
1700 // So, initiate retaining the actualFocusedWindow.
1701 AwtFrame *owner = GetOwningFrameOrDialog();
1702 if (owner) {
1703 owner->CheckRetainActualFocusedWindow(opposite);
1704 }
1705
1706 if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
1707 m_grabbedWindow->Ungrab();
1708 }
1709 type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
1710 AwtComponent::SetFocusedWindow(NULL);
1711 sm_focusOwner = NULL;
1712 }
1713
1714 SendWindowEvent(type, opposite);
1715 return mrConsume;
1716 }
1717
WmCreate()1718 MsgRouting AwtWindow::WmCreate()
1719 {
1720 return mrDoDefault;
1721 }
1722
WmClose()1723 MsgRouting AwtWindow::WmClose()
1724 {
1725 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSING);
1726
1727 /* Rely on above notification to handle quitting as needed */
1728 return mrConsume;
1729 }
1730
WmDestroy()1731 MsgRouting AwtWindow::WmDestroy()
1732 {
1733 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSED);
1734 return AwtComponent::WmDestroy();
1735 }
1736
WmShowWindow(BOOL show,UINT status)1737 MsgRouting AwtWindow::WmShowWindow(BOOL show, UINT status)
1738 {
1739 /*
1740 * Original fix for 4810575. Modified for 6386592.
1741 * If a simple window gets disposed we should synthesize
1742 * WM_ACTIVATE for its nearest owner. This is not performed by default because
1743 * the owner frame/dialog is natively active.
1744 */
1745 HWND hwndSelf = GetHWnd();
1746 HWND hwndOwner = ::GetParent(hwndSelf);
1747
1748 if (!show && IsSimpleWindow() && hwndSelf == AwtComponent::GetFocusedWindow() &&
1749 hwndOwner != NULL && ::IsWindowVisible(hwndOwner))
1750 {
1751 AwtFrame *owner = (AwtFrame*)AwtComponent::GetComponent(hwndOwner);
1752 if (owner != NULL) {
1753 owner->AwtSetActiveWindow();
1754 }
1755 }
1756
1757 //Fixed 4842599: REGRESSION: JPopupMenu not Hidden Properly After Iconified and Deiconified
1758 if (show && (status == SW_PARENTOPENING)) {
1759 if (!IsVisible()) {
1760 return mrConsume;
1761 }
1762 }
1763 return AwtCanvas::WmShowWindow(show, status);
1764 }
1765
1766 /*
1767 * Override AwtComponent's move handling to first update the
1768 * java AWT target's position fields directly, since Windows
1769 * and below can be resized from outside of java (by user)
1770 */
WmMove(int x,int y)1771 MsgRouting AwtWindow::WmMove(int x, int y)
1772 {
1773 if ( ::IsIconic(GetHWnd()) ) {
1774 // fixes 4065534 (robi.khan@eng)
1775 // if a window is iconified we don't want to update
1776 // it's target's position since minimized Win32 windows
1777 // move to -32000, -32000 for whatever reason
1778 // NOTE: See also AwtWindow::Reshape
1779 return mrDoDefault;
1780 }
1781
1782 if (m_screenNum == -1) {
1783 // Set initial value
1784 m_screenNum = GetScreenImOn();
1785 }
1786 else {
1787 CheckIfOnNewScreen();
1788 }
1789
1790 /* Update the java AWT target component's fields directly */
1791 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1792 if (env->EnsureLocalCapacity(1) < 0) {
1793 return mrConsume;
1794 }
1795 jobject peer = GetPeer(env);
1796 jobject target = env->GetObjectField(peer, AwtObject::targetID);
1797
1798 RECT rect;
1799 ::GetWindowRect(GetHWnd(), &rect);
1800
1801 (env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left));
1802 (env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top));
1803 (env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left));
1804 (env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top));
1805 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
1806
1807 env->DeleteLocalRef(target);
1808 return AwtComponent::WmMove(x, y);
1809 }
1810
WmGetMinMaxInfo(LPMINMAXINFO lpmmi)1811 MsgRouting AwtWindow::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
1812 {
1813 MsgRouting r = AwtCanvas::WmGetMinMaxInfo(lpmmi);
1814 if ((m_minSize.x == 0) && (m_minSize.y == 0)) {
1815 return r;
1816 }
1817 lpmmi->ptMinTrackSize.x = m_minSize.x;
1818 lpmmi->ptMinTrackSize.y = m_minSize.y;
1819 return mrConsume;
1820 }
1821
WmSizing()1822 MsgRouting AwtWindow::WmSizing()
1823 {
1824 if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) {
1825 return mrDoDefault;
1826 }
1827
1828 DTRACE_PRINTLN("AwtWindow::WmSizing fullWindowDragEnabled");
1829
1830 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED);
1831
1832 HWND thisHwnd = GetHWnd();
1833 if (thisHwnd == NULL) {
1834 return mrDoDefault;
1835 }
1836
1837 // Call WComponentPeer::dynamicallyLayoutContainer()
1838 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1839 jobject peer = GetPeer(env);
1840 JNU_CallMethodByName(env, NULL, peer, "dynamicallyLayoutContainer", "()V");
1841 DASSERT(!safe_ExceptionOccurred(env));
1842
1843 return mrDoDefault;
1844 }
1845
WmEnterSizeMove()1846 MsgRouting AwtWindow::WmEnterSizeMove()
1847 {
1848 m_winSizeMove = TRUE;
1849 return mrDoDefault;
1850 }
1851
WmExitSizeMove()1852 MsgRouting AwtWindow::WmExitSizeMove()
1853 {
1854 m_winSizeMove = FALSE;
1855 CheckWindowDPIChange();
1856 return mrDoDefault;
1857 }
1858
1859 /*
1860 * Override AwtComponent's size handling to first update the
1861 * java AWT target's dimension fields directly, since Windows
1862 * and below can be resized from outside of java (by user)
1863 */
WmSize(UINT type,int w,int h)1864 MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
1865 {
1866 currentWmSizeState = type;
1867
1868 if (type == SIZE_MINIMIZED) {
1869 UpdateSecurityWarningVisibility();
1870 return mrDoDefault;
1871 }
1872
1873 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1874 if (env->EnsureLocalCapacity(1) < 0)
1875 return mrDoDefault;
1876 jobject target = GetTarget(env);
1877 // fix 4167248 : ensure the insets are up-to-date before using
1878 BOOL insetsChanged = UpdateInsets(NULL);
1879 int newWidth = w + m_insets.left + m_insets.right;
1880 int newHeight = h + m_insets.top + m_insets.bottom;
1881
1882 (env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth));
1883 (env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight));
1884
1885 jobject peer = GetPeer(env);
1886 (env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth));
1887 (env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight));
1888
1889 if (!AwtWindow::IsResizing()) {
1890 WindowResized();
1891 }
1892
1893 env->DeleteLocalRef(target);
1894 return AwtComponent::WmSize(type, w, h);
1895 }
1896
WmPaint(HDC)1897 MsgRouting AwtWindow::WmPaint(HDC)
1898 {
1899 PaintUpdateRgn(&m_insets);
1900 return mrConsume;
1901 }
1902
WmSettingChange(UINT wFlag,LPCTSTR pszSection)1903 MsgRouting AwtWindow::WmSettingChange(UINT wFlag, LPCTSTR pszSection)
1904 {
1905 if (wFlag == SPI_SETNONCLIENTMETRICS) {
1906 // user changed window metrics in
1907 // Control Panel->Display->Appearance
1908 // which may cause window insets to change
1909 UpdateInsets(NULL);
1910
1911 // [rray] fix for 4407329 - Changing Active Window Border width in display
1912 // settings causes problems
1913 WindowResized();
1914 Invalidate(NULL);
1915
1916 return mrConsume;
1917 }
1918 return mrDoDefault;
1919 }
1920
WmNcCalcSize(BOOL fCalcValidRects,LPNCCALCSIZE_PARAMS lpncsp,LRESULT & retVal)1921 MsgRouting AwtWindow::WmNcCalcSize(BOOL fCalcValidRects,
1922 LPNCCALCSIZE_PARAMS lpncsp, LRESULT& retVal)
1923 {
1924 MsgRouting mrRetVal = mrDoDefault;
1925
1926 if (fCalcValidRects == FALSE) {
1927 return mrDoDefault;
1928 }
1929 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1930 if (env->EnsureLocalCapacity(2) < 0) {
1931 return mrConsume;
1932 }
1933 // WM_NCCALCSIZE is usually in response to a resize, but
1934 // also can be triggered by SetWindowPos(SWP_FRAMECHANGED),
1935 // which means the insets will have changed - rnk 4/7/1998
1936 retVal = static_cast<UINT>(DefWindowProc(
1937 WM_NCCALCSIZE, fCalcValidRects, reinterpret_cast<LPARAM>(lpncsp)));
1938 if (HasValidRect()) {
1939 UpdateInsets(NULL);
1940 }
1941 mrRetVal = mrConsume;
1942 return mrRetVal;
1943 }
1944
WmNcHitTest(UINT x,UINT y,LRESULT & retVal)1945 MsgRouting AwtWindow::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
1946 {
1947 // If this window is blocked by modal dialog, return HTCLIENT for any point of it.
1948 // That prevents it to be moved or resized using the mouse. Disabling these
1949 // actions to be launched from sysmenu is implemented by ignoring WM_SYSCOMMAND
1950 if (::IsWindow(GetModalBlocker(GetHWnd()))) {
1951 retVal = HTCLIENT;
1952 } else {
1953 retVal = DefWindowProc(WM_NCHITTEST, 0, MAKELPARAM(x, y));
1954 }
1955 return mrConsume;
1956 }
1957
WmGetIcon(WPARAM iconType,LRESULT & retValue)1958 MsgRouting AwtWindow::WmGetIcon(WPARAM iconType, LRESULT& retValue)
1959 {
1960 return mrDoDefault;
1961 }
1962
WindowProc(UINT message,WPARAM wParam,LPARAM lParam)1963 LRESULT AwtWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
1964 {
1965 MsgRouting mr = mrDoDefault;
1966 LRESULT retValue = 0L;
1967
1968 switch(message) {
1969 case WM_GETICON:
1970 mr = WmGetIcon(wParam, retValue);
1971 break;
1972 case WM_SYSCOMMAND:
1973 //Fixed 6355340: Contents of frame are not layed out properly on maximize
1974 if ((wParam & 0xFFF0) == SC_SIZE) {
1975 AwtWindow::sm_resizing = TRUE;
1976 mr = WmSysCommand(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
1977 if (mr != mrConsume) {
1978 // Perform size-move loop here
1979 AwtWindow::DefWindowProc(message, wParam, lParam);
1980 }
1981 AwtWindow::sm_resizing = FALSE;
1982 if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) {
1983 WindowResized();
1984 } else {
1985 /*
1986 * 8016356: check whether window snapping occurred after
1987 * resizing, i.e. GetWindowRect() returns the real
1988 * (snapped) window rectangle, e.g. (179, 0)-(483, 1040),
1989 * but GetWindowPlacement() returns the rectangle of
1990 * normal window position, e.g. (179, 189)-(483, 445) and
1991 * they are different. If so, send ComponentResized event.
1992 */
1993 WINDOWPLACEMENT wp;
1994 ::GetWindowPlacement(GetHWnd(), &wp);
1995 RECT rc;
1996 ::GetWindowRect(GetHWnd(), &rc);
1997 if (!::EqualRect(&rc, &wp.rcNormalPosition)) {
1998 WindowResized();
1999 }
2000 }
2001 mr = mrConsume;
2002 }
2003 break;
2004 }
2005
2006 if (mr != mrConsume) {
2007 retValue = AwtCanvas::WindowProc(message, wParam, lParam);
2008 }
2009 return retValue;
2010 }
2011
2012 /*
2013 * Fix for BugTraq ID 4041703: keyDown not being invoked.
2014 * This method overrides AwtCanvas::HandleEvent() since
2015 * an empty Window always receives the focus on the activation
2016 * so we don't have to modify the behavior.
2017 */
HandleEvent(MSG * msg,BOOL synthetic)2018 MsgRouting AwtWindow::HandleEvent(MSG *msg, BOOL synthetic)
2019 {
2020 return AwtComponent::HandleEvent(msg, synthetic);
2021 }
2022
WindowResized()2023 void AwtWindow::WindowResized()
2024 {
2025 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED);
2026 // Need to replace surfaceData on resize to catch changes to
2027 // various component-related values, such as insets
2028 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2029 env->CallVoidMethod(m_peerObject, AwtComponent::replaceSurfaceDataLaterMID);
2030 }
2031
InvalidateChildRect(HWND hWnd,LPARAM)2032 BOOL CALLBACK InvalidateChildRect(HWND hWnd, LPARAM)
2033 {
2034 TRY;
2035
2036 ::InvalidateRect(hWnd, NULL, TRUE);
2037 return TRUE;
2038
2039 CATCH_BAD_ALLOC_RET(FALSE);
2040 }
2041
Invalidate(RECT * r)2042 void AwtWindow::Invalidate(RECT* r)
2043 {
2044 ::InvalidateRect(GetHWnd(), NULL, TRUE);
2045 ::EnumChildWindows(GetHWnd(), (WNDENUMPROC)InvalidateChildRect, 0);
2046 }
2047
IsResizable()2048 BOOL AwtWindow::IsResizable() {
2049 return m_isResizable;
2050 }
2051
SetResizable(BOOL isResizable)2052 void AwtWindow::SetResizable(BOOL isResizable)
2053 {
2054 m_isResizable = isResizable;
2055 if (IsEmbeddedFrame()) {
2056 return;
2057 }
2058 LONG style = GetStyle();
2059 LONG resizeStyle = WS_MAXIMIZEBOX;
2060
2061 if (IsUndecorated() == FALSE) {
2062 resizeStyle |= WS_THICKFRAME;
2063 }
2064
2065 if (isResizable) {
2066 style |= resizeStyle;
2067 } else {
2068 style &= ~resizeStyle;
2069 }
2070 SetStyle(style);
2071 RedrawNonClient();
2072 }
2073
2074 // SetWindowPos flags to cause frame edge to be recalculated
2075 static const UINT SwpFrameChangeFlags =
2076 SWP_FRAMECHANGED | /* causes WM_NCCALCSIZE to be called */
2077 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
2078 SWP_NOACTIVATE | SWP_NOCOPYBITS |
2079 SWP_NOREPOSITION | SWP_NOSENDCHANGING;
2080
2081 //
2082 // Forces WM_NCCALCSIZE to be called to recalculate
2083 // window border (updates insets) without redrawing it
2084 //
RecalcNonClient()2085 void AwtWindow::RecalcNonClient()
2086 {
2087 ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_NOREDRAW);
2088 }
2089
2090 //
2091 // Forces WM_NCCALCSIZE to be called to recalculate
2092 // window border (updates insets) and redraws border to match
2093 //
RedrawNonClient()2094 void AwtWindow::RedrawNonClient()
2095 {
2096 ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_ASYNCWINDOWPOS);
2097 }
2098
GetScreenImOn()2099 int AwtWindow::GetScreenImOn() {
2100 HMONITOR hmon;
2101 int scrnNum;
2102
2103 hmon = ::MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY);
2104 DASSERT(hmon != NULL);
2105
2106 scrnNum = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hmon);
2107 DASSERT(scrnNum > -1);
2108
2109 return scrnNum;
2110 }
2111
2112 /* Check to see if we've been moved onto another screen.
2113 * If so, update internal data, surfaces, etc.
2114 */
2115
CheckIfOnNewScreen()2116 void AwtWindow::CheckIfOnNewScreen() {
2117 int curScrn = GetScreenImOn();
2118
2119 if (curScrn != m_screenNum) { // we've been moved
2120 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2121
2122 jclass peerCls = env->GetObjectClass(m_peerObject);
2123 DASSERT(peerCls);
2124 CHECK_NULL(peerCls);
2125
2126 jmethodID draggedID = env->GetMethodID(peerCls, "draggedToNewScreen",
2127 "()V");
2128 DASSERT(draggedID);
2129 if (draggedID == NULL) {
2130 env->DeleteLocalRef(peerCls);
2131 return;
2132 }
2133
2134 env->CallVoidMethod(m_peerObject, draggedID);
2135 m_screenNum = curScrn;
2136
2137 env->DeleteLocalRef(peerCls);
2138 }
2139 }
2140
CheckWindowDPIChange()2141 void AwtWindow::CheckWindowDPIChange() {
2142
2143 if (prevScaleRec.screen != -1 ) {
2144 float prevScaleX = prevScaleRec.scaleX;
2145 float prevScaleY = prevScaleRec.scaleY;
2146
2147 if (prevScaleX >= 1 && prevScaleY >= 1) {
2148 Devices::InstanceAccess devices;
2149 AwtWin32GraphicsDevice* device = devices->GetDevice(m_screenNum);
2150 if (device) {
2151 float scaleX = device->GetScaleX();
2152 float scaleY = device->GetScaleY();
2153 if (prevScaleX != scaleX || prevScaleY != scaleY) {
2154 WindowDPIChange(prevScaleRec.screen, prevScaleX, prevScaleY,
2155 m_screenNum, scaleX, scaleY);
2156 }
2157 }
2158 }
2159 prevScaleRec.screen = -1;
2160 }
2161 }
2162
WindowDPIChange(int prevScreen,float prevScaleX,float prevScaleY,int screen,float scaleX,float scaleY)2163 void AwtWindow::WindowDPIChange(int prevScreen,
2164 float prevScaleX, float prevScaleY,
2165 int screen, float scaleX,
2166 float scaleY)
2167 {
2168 int x;
2169 int y;
2170 int w;
2171 int h;
2172 RECT rect;
2173
2174 if (prevScaleX == scaleX && prevScaleY == scaleY) {
2175 return;
2176 }
2177
2178 ::GetWindowRect(GetHWnd(), &rect);
2179 x = rect.left;
2180 y = rect.top;
2181 w = (rect.right - rect.left) * scaleX / prevScaleX;
2182 h = (rect.bottom - rect.top) * scaleY / prevScaleY;
2183
2184 if (prevScreen != screen) {
2185 Devices::InstanceAccess devices;
2186 AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
2187 if (device) {
2188 RECT bounds;
2189 if (MonitorBounds(device->GetMonitor(), &bounds)) {
2190 x = x < bounds.left ? bounds.left : x;
2191 y = y < bounds.top ? bounds.top : y;
2192
2193 x = (x + w > bounds.right) ? bounds.right - w : x;
2194 y = (y + h > bounds.bottom) ? bounds.bottom - h : y;
2195 }
2196 }
2197 }
2198
2199 ReshapeNoScale(x, y, w, h);
2200 }
2201
IsFocusableWindow()2202 BOOL AwtWindow::IsFocusableWindow() {
2203 /*
2204 * For Window/Frame/Dialog to accept focus it should:
2205 * - be focusable;
2206 * - be not blocked by any modal blocker.
2207 */
2208 BOOL focusable = m_isFocusableWindow && !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
2209 AwtFrame *owner = GetOwningFrameOrDialog(); // NULL for Frame and Dialog
2210
2211 if (owner != NULL) {
2212 /*
2213 * Also for Window (not Frame/Dialog) to accept focus:
2214 * - its decorated parent should accept focus;
2215 */
2216 focusable = focusable && owner->IsFocusableWindow();
2217 }
2218 return focusable;
2219 }
2220
SetModalBlocker(HWND window,HWND blocker)2221 void AwtWindow::SetModalBlocker(HWND window, HWND blocker) {
2222 if (!::IsWindow(window)) {
2223 return;
2224 }
2225
2226 if (::IsWindow(blocker)) {
2227 ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
2228 ::EnableWindow(window, FALSE);
2229 } else {
2230 ::RemoveProp(window, ModalBlockerProp);
2231 AwtComponent *comp = AwtComponent::GetComponent(window);
2232 // we don't expect to be called with non-java HWNDs
2233 DASSERT(comp && comp->IsTopLevel());
2234 // we should not unblock disabled toplevels
2235 ::EnableWindow(window, comp->isEnabled());
2236 }
2237 }
2238
SetAndActivateModalBlocker(HWND window,HWND blocker)2239 void AwtWindow::SetAndActivateModalBlocker(HWND window, HWND blocker) {
2240 if (!::IsWindow(window)) {
2241 return;
2242 }
2243 AwtWindow::SetModalBlocker(window, blocker);
2244 if (::IsWindow(blocker)) {
2245 // We must check for visibility. Otherwise invisible dialog will receive WM_ACTIVATE.
2246 if (::IsWindowVisible(blocker)) {
2247 ::BringWindowToTop(blocker);
2248 ::SetForegroundWindow(blocker);
2249 }
2250 }
2251 }
2252
GetTopmostModalBlocker(HWND window)2253 HWND AwtWindow::GetTopmostModalBlocker(HWND window)
2254 {
2255 HWND ret, blocker = NULL;
2256
2257 do {
2258 ret = blocker;
2259 blocker = AwtWindow::GetModalBlocker(window);
2260 window = blocker;
2261 } while (::IsWindow(blocker));
2262
2263 return ret;
2264 }
2265
FlashWindowEx(HWND hWnd,UINT count,DWORD timeout,DWORD flags)2266 void AwtWindow::FlashWindowEx(HWND hWnd, UINT count, DWORD timeout, DWORD flags) {
2267 FLASHWINFO fi;
2268 fi.cbSize = sizeof(fi);
2269 fi.hwnd = hWnd;
2270 fi.dwFlags = flags;
2271 fi.uCount = count;
2272 fi.dwTimeout = timeout;
2273 ::FlashWindowEx(&fi);
2274 }
2275
2276 jboolean
_RequestWindowFocus(void * param)2277 AwtWindow::_RequestWindowFocus(void *param)
2278 {
2279 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2280
2281 RequestWindowFocusStruct *rfs = (RequestWindowFocusStruct *)param;
2282 jobject self = rfs->component;
2283 jboolean isMouseEventCause = rfs->isMouseEventCause;
2284
2285 jboolean result = JNI_FALSE;
2286 AwtWindow *window = NULL;
2287
2288 PDATA pData;
2289 JNI_CHECK_NULL_GOTO(self, "peer", ret);
2290 pData = JNI_GET_PDATA(self);
2291 if (pData == NULL) {
2292 // do nothing just return false
2293 goto ret;
2294 }
2295
2296 window = (AwtWindow *)pData;
2297 if (::IsWindow(window->GetHWnd())) {
2298 result = (jboolean)window->SendMessage(WM_AWT_WINDOW_SETACTIVE, (WPARAM)isMouseEventCause, 0);
2299 }
2300 ret:
2301 env->DeleteGlobalRef(self);
2302
2303 delete rfs;
2304
2305 return result;
2306 }
2307
_ToFront(void * param)2308 void AwtWindow::_ToFront(void *param)
2309 {
2310 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2311
2312 jobject self = (jobject)param;
2313
2314 AwtWindow *w = NULL;
2315
2316 PDATA pData;
2317 JNI_CHECK_PEER_GOTO(self, ret);
2318 w = (AwtWindow *)pData;
2319 if (::IsWindow(w->GetHWnd()))
2320 {
2321 UINT flags = SWP_NOMOVE|SWP_NOSIZE;
2322 BOOL focusable = w->IsFocusableWindow();
2323 BOOL autoRequestFocus = w->IsAutoRequestFocus();
2324
2325 if (!focusable || !autoRequestFocus)
2326 {
2327 flags = flags|SWP_NOACTIVATE;
2328 }
2329 ::SetWindowPos(w->GetHWnd(), HWND_TOP, 0, 0, 0, 0, flags);
2330 if (focusable && autoRequestFocus)
2331 {
2332 ::SetForegroundWindow(w->GetHWnd());
2333 }
2334 }
2335 ret:
2336 env->DeleteGlobalRef(self);
2337 }
2338
_ToBack(void * param)2339 void AwtWindow::_ToBack(void *param)
2340 {
2341 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2342
2343 jobject self = (jobject)param;
2344
2345 AwtWindow *w = NULL;
2346
2347 PDATA pData;
2348 JNI_CHECK_PEER_GOTO(self, ret);
2349 w = (AwtWindow *)pData;
2350 if (::IsWindow(w->GetHWnd()))
2351 {
2352 HWND hwnd = w->GetHWnd();
2353 // if (AwtComponent::GetComponent(hwnd) == NULL) {
2354 // // Window was disposed. Don't bother.
2355 // return;
2356 // }
2357
2358 ::SetWindowPos(hwnd, HWND_BOTTOM, 0, 0 ,0, 0,
2359 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
2360
2361 // If hwnd is the foreground window or if *any* of its owners are, then
2362 // we have to reset the foreground window. The reason is that when we send
2363 // hwnd to back, all of its owners are sent to back as well. If any one of
2364 // them is the foreground window, then it's possible that we could end up
2365 // with a foreground window behind a window of another application.
2366 HWND foregroundWindow = ::GetForegroundWindow();
2367 BOOL adjustForegroundWindow;
2368 HWND toTest = hwnd;
2369 do
2370 {
2371 adjustForegroundWindow = (toTest == foregroundWindow);
2372 if (adjustForegroundWindow)
2373 {
2374 break;
2375 }
2376 toTest = ::GetWindow(toTest, GW_OWNER);
2377 }
2378 while (toTest != NULL);
2379
2380 if (adjustForegroundWindow)
2381 {
2382 HWND foregroundSearch = hwnd, newForegroundWindow = NULL;
2383 while (1)
2384 {
2385 foregroundSearch = ::GetNextWindow(foregroundSearch, GW_HWNDPREV);
2386 if (foregroundSearch == NULL)
2387 {
2388 break;
2389 }
2390 LONG style = static_cast<LONG>(::GetWindowLongPtr(foregroundSearch, GWL_STYLE));
2391 if ((style & WS_CHILD) || !(style & WS_VISIBLE))
2392 {
2393 continue;
2394 }
2395
2396 AwtComponent *c = AwtComponent::GetComponent(foregroundSearch);
2397 if ((c != NULL) && !::IsWindow(AwtWindow::GetModalBlocker(c->GetHWnd())))
2398 {
2399 newForegroundWindow = foregroundSearch;
2400 }
2401 }
2402 if (newForegroundWindow != NULL)
2403 {
2404 ::SetWindowPos(newForegroundWindow, HWND_TOP, 0, 0, 0, 0,
2405 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
2406 if (((AwtWindow*)AwtComponent::GetComponent(newForegroundWindow))->IsFocusableWindow())
2407 {
2408 ::SetForegroundWindow(newForegroundWindow);
2409 }
2410 }
2411 else
2412 {
2413 // We *have* to set the active HWND to something new. We simply
2414 // cannot risk having an active Java HWND which is behind an HWND
2415 // of a native application. This really violates the Windows user
2416 // experience.
2417 //
2418 // Windows won't allow us to set the foreground window to NULL,
2419 // so we use the desktop window instead. To the user, it appears
2420 // that there is no foreground window system-wide.
2421 ::SetForegroundWindow(::GetDesktopWindow());
2422 }
2423 }
2424 }
2425 ret:
2426 env->DeleteGlobalRef(self);
2427 }
2428
_SetAlwaysOnTop(void * param)2429 void AwtWindow::_SetAlwaysOnTop(void *param)
2430 {
2431 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2432
2433 SetAlwaysOnTopStruct *sas = (SetAlwaysOnTopStruct *)param;
2434 jobject self = sas->window;
2435 jboolean value = sas->value;
2436
2437 AwtWindow *w = NULL;
2438
2439 PDATA pData;
2440 JNI_CHECK_PEER_GOTO(self, ret);
2441 w = (AwtWindow *)pData;
2442 if (::IsWindow(w->GetHWnd()))
2443 {
2444 w->SendMessage(WM_AWT_SETALWAYSONTOP, (WPARAM)value, (LPARAM)w);
2445 w->m_alwaysOnTop = (bool)value;
2446 }
2447 ret:
2448 env->DeleteGlobalRef(self);
2449
2450 delete sas;
2451 }
2452
_SetTitle(void * param)2453 void AwtWindow::_SetTitle(void *param)
2454 {
2455 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2456
2457 SetTitleStruct *sts = (SetTitleStruct *)param;
2458 jobject self = sts->window;
2459 jstring title = sts->title;
2460
2461 AwtWindow *w = NULL;
2462
2463 PDATA pData;
2464 JNI_CHECK_PEER_GOTO(self, ret);
2465 JNI_CHECK_NULL_GOTO(title, "null title", ret);
2466
2467 w = (AwtWindow *)pData;
2468 if (::IsWindow(w->GetHWnd()))
2469 {
2470 int length = env->GetStringLength(title);
2471 TCHAR *buffer = new TCHAR[length + 1];
2472 env->GetStringRegion(title, 0, length, reinterpret_cast<jchar*>(buffer));
2473 buffer[length] = L'\0';
2474 VERIFY(::SetWindowText(w->GetHWnd(), buffer));
2475 delete[] buffer;
2476 }
2477 ret:
2478 env->DeleteGlobalRef(self);
2479 if (title != NULL) {
2480 env->DeleteGlobalRef(title);
2481 }
2482
2483 delete sts;
2484 }
2485
_SetResizable(void * param)2486 void AwtWindow::_SetResizable(void *param)
2487 {
2488 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2489
2490 SetResizableStruct *srs = (SetResizableStruct *)param;
2491 jobject self = srs->window;
2492 jboolean resizable = srs->resizable;
2493
2494 AwtWindow *w = NULL;
2495
2496 PDATA pData;
2497 JNI_CHECK_PEER_GOTO(self, ret);
2498 w = (AwtWindow *)pData;
2499 if (::IsWindow(w->GetHWnd()))
2500 {
2501 DASSERT(!IsBadReadPtr(w, sizeof(AwtWindow)));
2502 w->SetResizable(resizable != 0);
2503 }
2504 ret:
2505 env->DeleteGlobalRef(self);
2506
2507 delete srs;
2508 }
2509
_UpdateInsets(void * param)2510 void AwtWindow::_UpdateInsets(void *param)
2511 {
2512 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2513
2514 UpdateInsetsStruct *uis = (UpdateInsetsStruct *)param;
2515 jobject self = uis->window;
2516 jobject insets = uis->insets;
2517
2518 AwtWindow *w = NULL;
2519
2520 PDATA pData;
2521 JNI_CHECK_PEER_GOTO(self, ret);
2522 JNI_CHECK_NULL_GOTO(insets, "null insets", ret);
2523 w = (AwtWindow *)pData;
2524 if (::IsWindow(w->GetHWnd()))
2525 {
2526 w->UpdateInsets(insets);
2527 }
2528 ret:
2529 env->DeleteGlobalRef(self);
2530 env->DeleteGlobalRef(insets);
2531
2532 delete uis;
2533 }
2534
_ReshapeFrame(void * param)2535 void AwtWindow::_ReshapeFrame(void *param)
2536 {
2537 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2538
2539 ReshapeFrameStruct *rfs = (ReshapeFrameStruct *)param;
2540 jobject self = rfs->frame;
2541 jint x = rfs->x;
2542 jint y = rfs->y;
2543 jint w = rfs->w;
2544 jint h = rfs->h;
2545
2546 if (env->EnsureLocalCapacity(1) < 0)
2547 {
2548 env->DeleteGlobalRef(self);
2549 delete rfs;
2550 return;
2551 }
2552
2553 AwtFrame *p = NULL;
2554
2555 PDATA pData;
2556 JNI_CHECK_PEER_GOTO(self, ret);
2557 p = (AwtFrame *)pData;
2558 if (::IsWindow(p->GetHWnd()))
2559 {
2560 jobject target = env->GetObjectField(self, AwtObject::targetID);
2561 if (target != NULL)
2562 {
2563 // enforce tresholds before sending the event
2564 // Fix for 4459064 : do not enforce thresholds for embedded frames
2565 if (!p->IsEmbeddedFrame())
2566 {
2567 jobject peer = p->GetPeer(env);
2568 int minWidth = ::GetSystemMetrics(SM_CXMIN);
2569 int minHeight = ::GetSystemMetrics(SM_CYMIN);
2570 if (w < minWidth)
2571 {
2572 env->SetIntField(target, AwtComponent::widthID,
2573 w = minWidth);
2574 env->SetIntField(peer, AwtWindow::sysWID,
2575 w);
2576 }
2577 if (h < minHeight)
2578 {
2579 env->SetIntField(target, AwtComponent::heightID,
2580 h = minHeight);
2581 env->SetIntField(peer, AwtWindow::sysHID,
2582 h);
2583 }
2584 }
2585 env->DeleteLocalRef(target);
2586
2587 RECT *r = new RECT;
2588 ::SetRect(r, x, y, x + w, y + h);
2589 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, 0, (LPARAM)r);
2590 // r is deleted in message handler
2591
2592 // After the input method window shown, the dimension & position may not
2593 // be valid until this method is called. So we need to adjust the
2594 // IME candidate window position for the same reason as commented on
2595 // awt_Frame.cpp Show() method.
2596 if (p->isInputMethodWindow() && ::IsWindowVisible(p->GetHWnd())) {
2597 p->AdjustCandidateWindowPos();
2598 }
2599 }
2600 else
2601 {
2602 JNU_ThrowNullPointerException(env, "null target");
2603 }
2604 }
2605 ret:
2606 env->DeleteGlobalRef(self);
2607
2608 delete rfs;
2609 }
2610
_OverrideHandle(void * param)2611 void AwtWindow::_OverrideHandle(void *param)
2612 {
2613 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2614
2615 OverrideHandle* oh = (OverrideHandle *) param;
2616 jobject self = oh->frame;
2617 AwtWindow *f = NULL;
2618
2619 PDATA pData;
2620 JNI_CHECK_PEER_GOTO(self, ret);
2621 f = (AwtWindow *)pData;
2622 f->OverrideHWnd(oh->handle);
2623 ret:
2624 env->DeleteGlobalRef(self);
2625
2626 delete oh;
2627 }
2628
2629 /*
2630 * This is AwtWindow-specific function that is not intended for reusing
2631 */
CreateIconFromRaster(JNIEnv * env,jintArray iconRaster,jint w,jint h)2632 HICON CreateIconFromRaster(JNIEnv* env, jintArray iconRaster, jint w, jint h)
2633 {
2634 HBITMAP mask = NULL;
2635 HBITMAP image = NULL;
2636 HICON icon = NULL;
2637 if (iconRaster != NULL) {
2638 int* iconRasterBuffer = NULL;
2639 try {
2640 iconRasterBuffer = (int *)env->GetPrimitiveArrayCritical(iconRaster, 0);
2641
2642 JNI_CHECK_NULL_GOTO(iconRasterBuffer, "iconRaster data", done);
2643
2644 mask = BitmapUtil::CreateTransparencyMaskFromARGB(w, h, iconRasterBuffer);
2645 image = BitmapUtil::CreateV4BitmapFromARGB(w, h, iconRasterBuffer);
2646 } catch (...) {
2647 if (iconRasterBuffer != NULL) {
2648 env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0);
2649 }
2650 throw;
2651 }
2652 if (iconRasterBuffer != NULL) {
2653 env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0);
2654 }
2655 }
2656 if (mask && image) {
2657 ICONINFO icnInfo;
2658 memset(&icnInfo, 0, sizeof(ICONINFO));
2659 icnInfo.hbmMask = mask;
2660 icnInfo.hbmColor = image;
2661 icnInfo.fIcon = TRUE;
2662 icon = ::CreateIconIndirect(&icnInfo);
2663 }
2664 if (image) {
2665 destroy_BMP(image);
2666 }
2667 if (mask) {
2668 destroy_BMP(mask);
2669 }
2670 done:
2671 return icon;
2672 }
2673
SetIconData(JNIEnv * env,jintArray iconRaster,jint w,jint h,jintArray smallIconRaster,jint smw,jint smh)2674 void AwtWindow::SetIconData(JNIEnv* env, jintArray iconRaster, jint w, jint h,
2675 jintArray smallIconRaster, jint smw, jint smh)
2676 {
2677 HICON hOldIcon = NULL;
2678 HICON hOldIconSm = NULL;
2679 //Destroy previous icon if it isn't inherited
2680 if ((m_hIcon != NULL) && !m_iconInherited) {
2681 hOldIcon = m_hIcon;
2682 }
2683 m_hIcon = NULL;
2684 if ((m_hIconSm != NULL) && !m_iconInherited) {
2685 hOldIconSm = m_hIconSm;
2686 }
2687 m_hIconSm = NULL;
2688 m_hIcon = CreateIconFromRaster(env, iconRaster, w, h);
2689 JNU_CHECK_EXCEPTION(env);
2690 m_hIconSm = CreateIconFromRaster(env, smallIconRaster, smw, smh);
2691
2692 m_iconInherited = (m_hIcon == NULL);
2693 if (m_iconInherited) {
2694 HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER);
2695 AwtWindow* owner = (AwtWindow *)AwtComponent::GetComponent(hOwner);
2696 if (owner != NULL) {
2697 m_hIcon = owner->GetHIcon();
2698 m_hIconSm = owner->GetHIconSm();
2699 } else {
2700 m_iconInherited = FALSE;
2701 }
2702 }
2703 DoUpdateIcon();
2704 EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)this);
2705 if (hOldIcon != NULL) {
2706 DestroyIcon(hOldIcon);
2707 }
2708 if (hOldIconSm != NULL) {
2709 DestroyIcon(hOldIconSm);
2710 }
2711 }
2712
UpdateOwnedIconCallback(HWND hWndOwned,LPARAM lParam)2713 BOOL AwtWindow::UpdateOwnedIconCallback(HWND hWndOwned, LPARAM lParam)
2714 {
2715 HWND hWndOwner = ::GetWindow(hWndOwned, GW_OWNER);
2716 AwtWindow* owner = (AwtWindow*)lParam;
2717 if (hWndOwner == owner->GetHWnd()) {
2718 AwtComponent* comp = AwtComponent::GetComponent(hWndOwned);
2719 if (comp != NULL && comp->IsTopLevel()) {
2720 AwtWindow* owned = (AwtWindow *)comp;
2721 if (owned->m_iconInherited) {
2722 owned->m_hIcon = owner->m_hIcon;
2723 owned->m_hIconSm = owner->m_hIconSm;
2724 owned->DoUpdateIcon();
2725 EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)owned);
2726 }
2727 }
2728 }
2729 return TRUE;
2730 }
2731
DoUpdateIcon()2732 void AwtWindow::DoUpdateIcon()
2733 {
2734 //Does nothing for windows, is overriden for frames and dialogs
2735 }
2736
RedrawWindow()2737 void AwtWindow::RedrawWindow()
2738 {
2739 if (isOpaque()) {
2740 ::RedrawWindow(GetHWnd(), NULL, NULL,
2741 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
2742 } else {
2743 ::EnterCriticalSection(&contentBitmapCS);
2744 if (hContentBitmap != NULL) {
2745 UpdateWindowImpl(contentWidth, contentHeight, hContentBitmap);
2746 }
2747 ::LeaveCriticalSection(&contentBitmapCS);
2748 }
2749 }
2750
2751 // Deletes the hContentBitmap if it is non-null
DeleteContentBitmap()2752 void AwtWindow::DeleteContentBitmap()
2753 {
2754 ::EnterCriticalSection(&contentBitmapCS);
2755 if (hContentBitmap != NULL) {
2756 ::DeleteObject(hContentBitmap);
2757 hContentBitmap = NULL;
2758 }
2759 ::LeaveCriticalSection(&contentBitmapCS);
2760 }
2761
2762 // The effects are enabled only upon showing the window.
2763 // See 6780496 for details.
EnableTranslucency(BOOL enable)2764 void AwtWindow::EnableTranslucency(BOOL enable)
2765 {
2766 if (enable) {
2767 SetTranslucency(getOpacity(), isOpaque(), FALSE, TRUE);
2768 } else {
2769 SetTranslucency(0xFF, TRUE, FALSE);
2770 }
2771 }
2772
2773 /**
2774 * Sets the translucency effects.
2775 *
2776 * This method is used to:
2777 *
2778 * 1. Apply the translucency effects upon showing the window
2779 * (setValues == FALSE, useDefaultForOldValues == TRUE);
2780 * 2. Turn off the effects upon hiding the window
2781 * (setValues == FALSE, useDefaultForOldValues == FALSE);
2782 * 3. Set the effects per user's request
2783 * (setValues == TRUE, useDefaultForOldValues == FALSE);
2784 *
2785 * In case #3 the effects may or may not be applied immediately depending on
2786 * the current visibility status of the window.
2787 *
2788 * The setValues argument indicates if we need to preserve the passed values
2789 * in local fields for further use.
2790 * The useDefaultForOldValues argument indicates whether we should consider
2791 * the window as if it has not any effects applied at the moment.
2792 */
SetTranslucency(BYTE opacity,BOOL opaque,BOOL setValues,BOOL useDefaultForOldValues)2793 void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque, BOOL setValues,
2794 BOOL useDefaultForOldValues)
2795 {
2796 BYTE old_opacity = useDefaultForOldValues ? 0xFF : getOpacity();
2797 BOOL old_opaque = useDefaultForOldValues ? TRUE : isOpaque();
2798
2799 if (opacity == old_opacity && opaque == old_opaque) {
2800 return;
2801 }
2802
2803 if (setValues) {
2804 m_opacity = opacity;
2805 m_opaque = opaque;
2806 }
2807
2808 // If we're invisible and are storing the values, return
2809 // Otherwise, apply the effects immediately
2810 if (!IsVisible() && setValues) {
2811 return;
2812 }
2813
2814 HWND hwnd = GetHWnd();
2815
2816 if (opaque != old_opaque) {
2817 DeleteContentBitmap();
2818 }
2819
2820 if (opaque && opacity == 0xff) {
2821 // Turn off all the effects
2822 AwtWindow::SetLayered(hwnd, false);
2823
2824 // Ask the window to repaint itself and all the children
2825 RedrawWindow();
2826 } else {
2827 // We're going to enable some effects
2828 if (!AwtWindow::IsLayered(hwnd)) {
2829 AwtWindow::SetLayered(hwnd, true);
2830 } else {
2831 if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) {
2832 // _One_ of the modes uses the SetLayeredWindowAttributes.
2833 // Need to reset the style in this case.
2834 // If both modes are simple (i.e. just changing the opacity level),
2835 // no need to reset the style.
2836 AwtWindow::SetLayered(hwnd, false);
2837 AwtWindow::SetLayered(hwnd, true);
2838 }
2839 }
2840
2841 if (opaque) {
2842 // Simple opacity mode
2843 ::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), opacity, LWA_ALPHA);
2844 }
2845 }
2846 }
2847
CreateBitmapFromRaster(JNIEnv * env,jintArray raster,jint w,jint h)2848 static HBITMAP CreateBitmapFromRaster(JNIEnv* env, jintArray raster, jint w, jint h)
2849 {
2850 HBITMAP image = NULL;
2851 if (raster != NULL) {
2852 int* rasterBuffer = NULL;
2853 try {
2854 rasterBuffer = (int *)env->GetPrimitiveArrayCritical(raster, 0);
2855 JNI_CHECK_NULL_GOTO(rasterBuffer, "raster data", done);
2856 image = BitmapUtil::CreateBitmapFromARGBPre(w, h, w*4, rasterBuffer);
2857 } catch (...) {
2858 if (rasterBuffer != NULL) {
2859 env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
2860 }
2861 throw;
2862 }
2863 if (rasterBuffer != NULL) {
2864 env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
2865 }
2866 }
2867 done:
2868 return image;
2869 }
2870
UpdateWindowImpl(int width,int height,HBITMAP hBitmap)2871 void AwtWindow::UpdateWindowImpl(int width, int height, HBITMAP hBitmap)
2872 {
2873 if (isOpaque()) {
2874 return;
2875 }
2876
2877 HWND hWnd = GetHWnd();
2878 HDC hdcDst = ::GetDC(NULL);
2879 HDC hdcSrc = ::CreateCompatibleDC(NULL);
2880 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcSrc, hBitmap);
2881
2882 //XXX: this code doesn't paint the children (say, the java.awt.Button)!
2883 //So, if we ever want to support HWs here, we need to repaint them
2884 //in some other way...
2885 //::SendMessage(hWnd, WM_PRINT, (WPARAM)hdcSrc, /*PRF_CHECKVISIBLE |*/
2886 // PRF_CHILDREN /*| PRF_CLIENT | PRF_NONCLIENT*/);
2887
2888 POINT ptSrc;
2889 ptSrc.x = ptSrc.y = 0;
2890
2891 RECT rect;
2892 POINT ptDst;
2893 SIZE size;
2894
2895 ::GetWindowRect(hWnd, &rect);
2896 ptDst.x = rect.left;
2897 ptDst.y = rect.top;
2898 size.cx = width;
2899 size.cy = height;
2900
2901 BLENDFUNCTION bf;
2902
2903 bf.SourceConstantAlpha = getOpacity();
2904 bf.AlphaFormat = AC_SRC_ALPHA;
2905 bf.BlendOp = AC_SRC_OVER;
2906 bf.BlendFlags = 0;
2907
2908 ::UpdateLayeredWindow(hWnd, hdcDst, &ptDst, &size, hdcSrc, &ptSrc,
2909 RGB(0, 0, 0), &bf, ULW_ALPHA);
2910
2911 ::ReleaseDC(NULL, hdcDst);
2912 ::SelectObject(hdcSrc, hOldBitmap);
2913 ::DeleteDC(hdcSrc);
2914 }
2915
UpdateWindow(JNIEnv * env,jintArray data,int width,int height,HBITMAP hNewBitmap)2916 void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
2917 HBITMAP hNewBitmap)
2918 {
2919 if (isOpaque()) {
2920 return;
2921 }
2922
2923 HBITMAP hBitmap;
2924 if (hNewBitmap == NULL) {
2925 if (data == NULL) {
2926 return;
2927 }
2928 hBitmap = CreateBitmapFromRaster(env, data, width, height);
2929 if (hBitmap == NULL) {
2930 return;
2931 }
2932 } else {
2933 hBitmap = hNewBitmap;
2934 }
2935
2936 ::EnterCriticalSection(&contentBitmapCS);
2937 DeleteContentBitmap();
2938 hContentBitmap = hBitmap;
2939 contentWidth = width;
2940 contentHeight = height;
2941 UpdateWindowImpl(width, height, hBitmap);
2942 ::LeaveCriticalSection(&contentBitmapCS);
2943 }
2944
2945 /*
2946 * Fixed 6353381: it's improved fix for 4792958
2947 * which was backed-out to avoid 5059656
2948 */
HasValidRect()2949 BOOL AwtWindow::HasValidRect()
2950 {
2951 RECT inside;
2952 RECT outside;
2953
2954 if (::IsIconic(GetHWnd())) {
2955 return FALSE;
2956 }
2957
2958 ::GetClientRect(GetHWnd(), &inside);
2959 ::GetWindowRect(GetHWnd(), &outside);
2960
2961 BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0);
2962 BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
2963 (outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
2964 (outside.left == 3000 && outside.top == 3000)); // Win95 && Win98
2965
2966 // the bounds correspond to iconic state
2967 if (isZeroClientArea && isInvalidLocation)
2968 {
2969 return FALSE;
2970 }
2971
2972 return TRUE;
2973 }
2974
2975
_SetIconImagesData(void * param)2976 void AwtWindow::_SetIconImagesData(void * param)
2977 {
2978 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
2979
2980 SetIconImagesDataStruct* s = (SetIconImagesDataStruct*)param;
2981 jobject self = s->window;
2982
2983 jintArray iconRaster = s->iconRaster;
2984 jintArray smallIconRaster = s->smallIconRaster;
2985
2986 AwtWindow *window = NULL;
2987
2988 PDATA pData;
2989 JNI_CHECK_PEER_GOTO(self, ret);
2990 // ok to pass null raster: default AWT icon
2991
2992 window = (AwtWindow*)pData;
2993 if (::IsWindow(window->GetHWnd()))
2994 {
2995 window->SetIconData(env, iconRaster, s->w, s->h, smallIconRaster, s->smw, s->smh);
2996
2997 }
2998
2999 ret:
3000 env->DeleteGlobalRef(self);
3001 env->DeleteGlobalRef(iconRaster);
3002 env->DeleteGlobalRef(smallIconRaster);
3003 delete s;
3004 }
3005
_SetMinSize(void * param)3006 void AwtWindow::_SetMinSize(void* param)
3007 {
3008 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3009
3010 SizeStruct *ss = (SizeStruct *)param;
3011 jobject self = ss->window;
3012 jint w = ss->w;
3013 jint h = ss->h;
3014 //Perform size setting
3015 AwtWindow *window = NULL;
3016
3017 PDATA pData;
3018 JNI_CHECK_PEER_GOTO(self, ret);
3019 window = (AwtWindow *)pData;
3020 window->m_minSize.x = w;
3021 window->m_minSize.y = h;
3022 ret:
3023 env->DeleteGlobalRef(self);
3024 delete ss;
3025 }
3026
_GetScreenImOn(void * param)3027 jint AwtWindow::_GetScreenImOn(void *param)
3028 {
3029 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3030
3031 jobject self = (jobject)param;
3032
3033 // It's entirely possible that our native resources have been destroyed
3034 // before our java peer - if we're dispose()d, for instance.
3035 // Alert caller w/ IllegalComponentStateException.
3036 if (self == NULL) {
3037 JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
3038 "Peer null in JNI");
3039 return 0;
3040 }
3041 PDATA pData = JNI_GET_PDATA(self);
3042 if (pData == NULL) {
3043 JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
3044 "Native resources unavailable");
3045 env->DeleteGlobalRef(self);
3046 return 0;
3047 }
3048
3049 jint result = 0;
3050 AwtWindow *w = (AwtWindow *)pData;
3051 if (::IsWindow(w->GetHWnd()))
3052 {
3053 result = (jint)w->GetScreenImOn();
3054 }
3055
3056 env->DeleteGlobalRef(self);
3057
3058 return result;
3059 }
3060
_SetFocusableWindow(void * param)3061 void AwtWindow::_SetFocusableWindow(void *param)
3062 {
3063 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3064
3065 SetFocusableWindowStruct *sfws = (SetFocusableWindowStruct *)param;
3066 jobject self = sfws->window;
3067 jboolean isFocusableWindow = sfws->isFocusableWindow;
3068
3069 AwtWindow *window = NULL;
3070
3071 PDATA pData;
3072 JNI_CHECK_PEER_GOTO(self, ret);
3073 window = (AwtWindow *)pData;
3074
3075 window->m_isFocusableWindow = isFocusableWindow;
3076
3077 // A simple window is permanently set to WS_EX_NOACTIVATE
3078 if (!window->IsSimpleWindow()) {
3079 if (!window->m_isFocusableWindow) {
3080 LONG isPopup = window->GetStyle() & WS_POPUP;
3081 window->SetStyleEx(window->GetStyleEx() | (isPopup ? 0 : WS_EX_APPWINDOW) | WS_EX_NOACTIVATE);
3082 } else {
3083 window->SetStyleEx(window->GetStyleEx() & ~WS_EX_APPWINDOW & ~WS_EX_NOACTIVATE);
3084 }
3085 }
3086
3087 ret:
3088 env->DeleteGlobalRef(self);
3089 delete sfws;
3090 }
3091
_ModalDisable(void * param)3092 void AwtWindow::_ModalDisable(void *param)
3093 {
3094 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3095
3096 ModalDisableStruct *mds = (ModalDisableStruct *)param;
3097 jobject self = mds->window;
3098 HWND blockerHWnd = (HWND)mds->blockerHWnd;
3099
3100 AwtWindow *window = NULL;
3101 HWND windowHWnd = 0;
3102
3103 JNI_CHECK_NULL_GOTO(self, "peer", ret);
3104 PDATA pData = JNI_GET_PDATA(self);
3105 if (pData == NULL) {
3106 env->DeleteGlobalRef(self);
3107 delete mds;
3108 return;
3109 }
3110
3111 window = (AwtWindow *)pData;
3112 windowHWnd = window->GetHWnd();
3113 if (::IsWindow(windowHWnd)) {
3114 AwtWindow::SetAndActivateModalBlocker(windowHWnd, blockerHWnd);
3115 }
3116
3117 ret:
3118 env->DeleteGlobalRef(self);
3119
3120 delete mds;
3121 }
3122
_ModalEnable(void * param)3123 void AwtWindow::_ModalEnable(void *param)
3124 {
3125 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3126
3127 jobject self = (jobject)param;
3128
3129 AwtWindow *window = NULL;
3130 HWND windowHWnd = 0;
3131
3132 JNI_CHECK_NULL_GOTO(self, "peer", ret);
3133 PDATA pData = JNI_GET_PDATA(self);
3134 if (pData == NULL) {
3135 env->DeleteGlobalRef(self);
3136 return;
3137 }
3138
3139 window = (AwtWindow *)pData;
3140 windowHWnd = window->GetHWnd();
3141 if (::IsWindow(windowHWnd)) {
3142 AwtWindow::SetModalBlocker(windowHWnd, NULL);
3143 }
3144
3145 ret:
3146 env->DeleteGlobalRef(self);
3147 }
3148
_SetOpacity(void * param)3149 void AwtWindow::_SetOpacity(void* param)
3150 {
3151 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3152
3153 OpacityStruct *os = (OpacityStruct *)param;
3154 jobject self = os->window;
3155 BYTE iOpacity = (BYTE)os->iOpacity;
3156
3157 PDATA pData;
3158 JNI_CHECK_PEER_GOTO(self, ret);
3159 AwtWindow *window = (AwtWindow *)pData;
3160
3161 window->SetTranslucency(iOpacity, window->isOpaque());
3162
3163 ret:
3164 env->DeleteGlobalRef(self);
3165 delete os;
3166 }
3167
_SetOpaque(void * param)3168 void AwtWindow::_SetOpaque(void* param)
3169 {
3170 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3171
3172 OpaqueStruct *os = (OpaqueStruct *)param;
3173 jobject self = os->window;
3174 BOOL isOpaque = (BOOL)os->isOpaque;
3175
3176 PDATA pData;
3177 JNI_CHECK_PEER_GOTO(self, ret);
3178 AwtWindow *window = (AwtWindow *)pData;
3179
3180 window->SetTranslucency(window->getOpacity(), isOpaque);
3181
3182 ret:
3183 env->DeleteGlobalRef(self);
3184 delete os;
3185 }
3186
_UpdateWindow(void * param)3187 void AwtWindow::_UpdateWindow(void* param)
3188 {
3189 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3190
3191 UpdateWindowStruct *uws = (UpdateWindowStruct *)param;
3192 jobject self = uws->window;
3193 jintArray data = uws->data;
3194
3195 PDATA pData;
3196 JNI_CHECK_PEER_GOTO(self, ret);
3197 AwtWindow *window = (AwtWindow *)pData;
3198
3199 window->UpdateWindow(env, data, (int)uws->width, (int)uws->height,
3200 uws->hBitmap);
3201
3202 ret:
3203 env->DeleteGlobalRef(self);
3204 if (data != NULL) {
3205 env->DeleteGlobalRef(data);
3206 }
3207 delete uws;
3208 }
3209
_SetFullScreenExclusiveModeState(void * param)3210 void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
3211 {
3212 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3213
3214 SetFullScreenExclusiveModeStateStruct * data =
3215 (SetFullScreenExclusiveModeStateStruct*)param;
3216 jobject self = data->window;
3217 jboolean state = data->isFSEMState;
3218
3219 PDATA pData;
3220 JNI_CHECK_PEER_GOTO(self, ret);
3221 AwtWindow *window = (AwtWindow *)pData;
3222
3223 window->setFullScreenExclusiveModeState(state != 0);
3224
3225 ret:
3226 env->DeleteGlobalRef(self);
3227 delete data;
3228 }
3229
_GetNativeWindowSize(void * param)3230 void AwtWindow::_GetNativeWindowSize(void* param) {
3231
3232 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3233
3234 SizeStruct *ss = (SizeStruct *)param;
3235 jobject self = ss->window;
3236 AwtWindow *window = NULL;
3237 PDATA pData;
3238 JNI_CHECK_PEER_RETURN(self);
3239 window = (AwtWindow *)pData;
3240
3241 RECT rc;
3242 ::GetWindowRect(window->GetHWnd(), &rc);
3243 ss->w = rc.right - rc.left;
3244 ss->h = rc.bottom - rc.top;
3245
3246 env->DeleteGlobalRef(self);
3247 }
3248
_WindowDPIChange(void * param)3249 void AwtWindow::_WindowDPIChange(void* param)
3250 {
3251 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
3252
3253 ScaleStruct *ss = (ScaleStruct *)param;
3254 jobject self = ss->window;
3255 jint prevScreen = ss->prevScreen;
3256 jfloat prevScaleX = ss->prevScaleX;
3257 jfloat prevScaleY = ss->prevScaleY;
3258 jint screen = ss->screen;
3259 jfloat scaleX = ss->scaleX;
3260 jfloat scaleY = ss->scaleY;
3261
3262 PDATA pData;
3263 JNI_CHECK_PEER_GOTO(self, ret);
3264 AwtWindow *window = (AwtWindow *)pData;
3265
3266 if (window->m_winSizeMove) {
3267 if (window->prevScaleRec.screen == -1) {
3268 window->prevScaleRec.screen = prevScreen;
3269 window->prevScaleRec.scaleX = prevScaleX;
3270 window->prevScaleRec.scaleY = prevScaleY;
3271 }
3272 }
3273 else {
3274 window->WindowDPIChange(prevScreen, prevScaleX, prevScaleY,
3275 screen, scaleX, scaleY);
3276 }
3277
3278 ret:
3279 env->DeleteGlobalRef(self);
3280 delete ss;
3281 }
3282
3283 extern "C" int getSystemMetricValue(int msgType);
3284 extern "C" {
3285
3286 /*
3287 * Class: java_awt_Window
3288 * Method: initIDs
3289 * Signature: ()V
3290 */
3291 JNIEXPORT void JNICALL
Java_java_awt_Window_initIDs(JNIEnv * env,jclass cls)3292 Java_java_awt_Window_initIDs(JNIEnv *env, jclass cls)
3293 {
3294 TRY;
3295
3296 CHECK_NULL(AwtWindow::warningStringID =
3297 env->GetFieldID(cls, "warningString", "Ljava/lang/String;"));
3298 CHECK_NULL(AwtWindow::locationByPlatformID =
3299 env->GetFieldID(cls, "locationByPlatform", "Z"));
3300 CHECK_NULL(AwtWindow::securityWarningWidthID =
3301 env->GetFieldID(cls, "securityWarningWidth", "I"));
3302 CHECK_NULL(AwtWindow::securityWarningHeightID =
3303 env->GetFieldID(cls, "securityWarningHeight", "I"));
3304 CHECK_NULL(AwtWindow::getWarningStringMID =
3305 env->GetMethodID(cls, "getWarningString", "()Ljava/lang/String;"));
3306 CHECK_NULL(AwtWindow::autoRequestFocusID =
3307 env->GetFieldID(cls, "autoRequestFocus", "Z"));
3308 CHECK_NULL(AwtWindow::calculateSecurityWarningPositionMID =
3309 env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;"));
3310
3311 jclass windowTypeClass = env->FindClass("java/awt/Window$Type");
3312 CHECK_NULL(windowTypeClass);
3313 AwtWindow::windowTypeNameMID =
3314 env->GetMethodID(windowTypeClass, "name", "()Ljava/lang/String;");
3315 env->DeleteLocalRef(windowTypeClass);
3316
3317 CATCH_BAD_ALLOC;
3318 }
3319
3320 } /* extern "C" */
3321
3322
3323 /************************************************************************
3324 * WindowPeer native methods
3325 */
3326
3327 extern "C" {
3328
3329 /*
3330 * Class: sun_awt_windows_WWindowPeer
3331 * Method: initIDs
3332 * Signature: ()V
3333 */
3334 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv * env,jclass cls)3335 Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
3336 {
3337 TRY;
3338
3339 CHECK_NULL(AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I"));
3340 CHECK_NULL(AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I"));
3341 CHECK_NULL(AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"));
3342 CHECK_NULL(AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"));
3343
3344 AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType",
3345 "Ljava/awt/Window$Type;");
3346
3347 CATCH_BAD_ALLOC;
3348 }
3349
3350 /*
3351 * Class: sun_awt_windows_WWindowPeer
3352 * Method: toFront
3353 * Signature: ()V
3354 */
3355 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1toFront(JNIEnv * env,jobject self)3356 Java_sun_awt_windows_WWindowPeer__1toFront(JNIEnv *env, jobject self)
3357 {
3358 TRY;
3359
3360 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToFront,
3361 env->NewGlobalRef(self));
3362 // global ref is deleted in _ToFront()
3363
3364 CATCH_BAD_ALLOC;
3365 }
3366
3367 /*
3368 * Class: sun_awt_windows_WWindowPeer
3369 * Method: toBack
3370 * Signature: ()V
3371 */
3372 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_toBack(JNIEnv * env,jobject self)3373 Java_sun_awt_windows_WWindowPeer_toBack(JNIEnv *env, jobject self)
3374 {
3375 TRY;
3376
3377 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToBack,
3378 env->NewGlobalRef(self));
3379 // global ref is deleted in _ToBack()
3380
3381 CATCH_BAD_ALLOC;
3382 }
3383
3384 /*
3385 * Class: sun_awt_windows_WWindowPeer
3386 * Method: setAlwaysOnTop
3387 * Signature: (Z)V
3388 */
3389 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setAlwaysOnTopNative(JNIEnv * env,jobject self,jboolean value)3390 Java_sun_awt_windows_WWindowPeer_setAlwaysOnTopNative(JNIEnv *env, jobject self,
3391 jboolean value)
3392 {
3393 TRY;
3394
3395 SetAlwaysOnTopStruct *sas = new SetAlwaysOnTopStruct;
3396 sas->window = env->NewGlobalRef(self);
3397 sas->value = value;
3398
3399 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetAlwaysOnTop, sas);
3400 // global ref and sas are deleted in _SetAlwaysOnTop
3401
3402 CATCH_BAD_ALLOC;
3403 }
3404
3405 /*
3406 * Class: sun_awt_windows_WWindowPeer
3407 * Method: _setTitle
3408 * Signature: (Ljava/lang/String;)V
3409 */
3410 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1setTitle(JNIEnv * env,jobject self,jstring title)3411 Java_sun_awt_windows_WWindowPeer__1setTitle(JNIEnv *env, jobject self,
3412 jstring title)
3413 {
3414 TRY;
3415
3416 SetTitleStruct *sts = new SetTitleStruct;
3417 sts->window = env->NewGlobalRef(self);
3418 sts->title = (jstring)env->NewGlobalRef(title);
3419
3420 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetTitle, sts);
3421 /// global refs and sts are deleted in _SetTitle()
3422
3423 CATCH_BAD_ALLOC;
3424 }
3425
3426 /*
3427 * Class: sun_awt_windows_WWindowPeer
3428 * Method: _setResizable
3429 * Signature: (Z)V
3430 */
3431 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1setResizable(JNIEnv * env,jobject self,jboolean resizable)3432 Java_sun_awt_windows_WWindowPeer__1setResizable(JNIEnv *env, jobject self,
3433 jboolean resizable)
3434 {
3435 TRY;
3436
3437 SetResizableStruct *srs = new SetResizableStruct;
3438 srs->window = env->NewGlobalRef(self);
3439 srs->resizable = resizable;
3440
3441 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetResizable, srs);
3442 // global ref and srs are deleted in _SetResizable
3443
3444 CATCH_BAD_ALLOC;
3445 }
3446
3447 /*
3448 * Class: sun_awt_windows_WWindowPeer
3449 * Method: create
3450 * Signature: (Lsun/awt/windows/WComponentPeer;)V
3451 */
3452 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_createAwtWindow(JNIEnv * env,jobject self,jobject parent)3453 Java_sun_awt_windows_WWindowPeer_createAwtWindow(JNIEnv *env, jobject self,
3454 jobject parent)
3455 {
3456 TRY;
3457
3458 AwtToolkit::CreateComponent(self, parent,
3459 (AwtToolkit::ComponentFactory)
3460 AwtWindow::Create);
3461
3462 CATCH_BAD_ALLOC;
3463 }
3464
3465 /*
3466 * Class: sun_awt_windows_WWindowPeer
3467 * Method: updateInsets
3468 * Signature: (Ljava/awt/Insets;)V
3469 */
3470 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateInsets(JNIEnv * env,jobject self,jobject insets)3471 Java_sun_awt_windows_WWindowPeer_updateInsets(JNIEnv *env, jobject self,
3472 jobject insets)
3473 {
3474 TRY;
3475
3476 UpdateInsetsStruct *uis = new UpdateInsetsStruct;
3477 uis->window = env->NewGlobalRef(self);
3478 uis->insets = env->NewGlobalRef(insets);
3479
3480 AwtToolkit::GetInstance().SyncCall(AwtWindow::_UpdateInsets, uis);
3481 // global refs and uis are deleted in _UpdateInsets()
3482
3483 CATCH_BAD_ALLOC;
3484 }
3485
3486 /*
3487 * Class: sun_awt_windows_WWindowPeer
3488 * Method: reshapeFrame
3489 * Signature: (IIII)V
3490 */
3491 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_reshapeFrame(JNIEnv * env,jobject self,jint x,jint y,jint w,jint h)3492 Java_sun_awt_windows_WWindowPeer_reshapeFrame(JNIEnv *env, jobject self,
3493 jint x, jint y, jint w, jint h)
3494 {
3495 TRY;
3496
3497 ReshapeFrameStruct *rfs = new ReshapeFrameStruct;
3498 rfs->frame = env->NewGlobalRef(self);
3499 rfs->x = x;
3500 rfs->y = y;
3501 rfs->w = w;
3502 rfs->h = h;
3503
3504 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ReshapeFrame, rfs);
3505 // global ref and rfs are deleted in _ReshapeFrame()
3506
3507 CATCH_BAD_ALLOC;
3508 }
3509
3510 /*
3511 * Class: sun_awt_windows_WWindowPeer
3512 * Method: getNativeWindowSize
3513 * Signature: ()Ljava/awt/Dimension;
3514 */
Java_sun_awt_windows_WWindowPeer_getNativeWindowSize(JNIEnv * env,jobject self)3515 JNIEXPORT jobject JNICALL Java_sun_awt_windows_WWindowPeer_getNativeWindowSize
3516 (JNIEnv *env, jobject self) {
3517
3518 jobject res = NULL;
3519 TRY;
3520 SizeStruct *ss = new SizeStruct;
3521 ss->window = env->NewGlobalRef(self);
3522
3523 AwtToolkit::GetInstance().SyncCall(AwtWindow::_GetNativeWindowSize, ss);
3524
3525 int w = ss->w;
3526 int h = ss->h;
3527
3528 delete ss;
3529 // global ref is deleted in _GetNativeWindowSize()
3530
3531 static jmethodID dimMID = NULL;
3532 static jclass dimClassID = NULL;
3533 if (dimClassID == NULL) {
3534 jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
3535 CHECK_NULL_RETURN(dimClassIDLocal, NULL);
3536 dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
3537 env->DeleteLocalRef(dimClassIDLocal);
3538 }
3539
3540 if (dimMID == NULL) {
3541 dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
3542 CHECK_NULL_RETURN(dimMID, NULL);
3543 }
3544
3545 return env->NewObject(dimClassID, dimMID, w, h);
3546
3547 CATCH_BAD_ALLOC_RET(NULL);
3548 }
3549
3550 /*
3551 * Class: sun_awt_windows_WWindowPeer
3552 * Method: getSysMinWidth
3553 * Signature: ()I
3554 */
3555 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysMinWidth(JNIEnv * env,jclass self)3556 Java_sun_awt_windows_WWindowPeer_getSysMinWidth(JNIEnv *env, jclass self)
3557 {
3558 TRY;
3559
3560 return ::GetSystemMetrics(SM_CXMIN);
3561
3562 CATCH_BAD_ALLOC_RET(0);
3563 }
3564
3565 /*
3566 * Class: sun_awt_windows_WWindowPeer
3567 * Method: getSysMinHeight
3568 * Signature: ()I
3569 */
3570 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysMinHeight(JNIEnv * env,jclass self)3571 Java_sun_awt_windows_WWindowPeer_getSysMinHeight(JNIEnv *env, jclass self)
3572 {
3573 TRY;
3574
3575 return ::GetSystemMetrics(SM_CYMIN);
3576
3577 CATCH_BAD_ALLOC_RET(0);
3578 }
3579
3580 /*
3581 * Class: sun_awt_windows_WWindowPeer
3582 * Method: getSysIconHeight
3583 * Signature: ()I
3584 */
3585 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysIconHeight(JNIEnv * env,jclass self)3586 Java_sun_awt_windows_WWindowPeer_getSysIconHeight(JNIEnv *env, jclass self)
3587 {
3588 TRY;
3589
3590 return getSystemMetricValue(SM_CYICON);
3591
3592 CATCH_BAD_ALLOC_RET(0);
3593 }
3594
3595 /*
3596 * Class: sun_awt_windows_WWindowPeer
3597 * Method: getSysIconWidth
3598 * Signature: ()I
3599 */
3600 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysIconWidth(JNIEnv * env,jclass self)3601 Java_sun_awt_windows_WWindowPeer_getSysIconWidth(JNIEnv *env, jclass self)
3602 {
3603 TRY;
3604
3605 return getSystemMetricValue(SM_CXICON);
3606
3607 CATCH_BAD_ALLOC_RET(0);
3608 }
3609
3610 /*
3611 * Class: sun_awt_windows_WWindowPeer
3612 * Method: getSysSmIconHeight
3613 * Signature: ()I
3614 */
3615 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysSmIconHeight(JNIEnv * env,jclass self)3616 Java_sun_awt_windows_WWindowPeer_getSysSmIconHeight(JNIEnv *env, jclass self)
3617 {
3618 TRY;
3619
3620 return getSystemMetricValue(SM_CYSMICON);
3621
3622 CATCH_BAD_ALLOC_RET(0);
3623 }
3624
3625 /*
3626 * Class: sun_awt_windows_WWindowPeer
3627 * Method: getSysSmIconWidth
3628 * Signature: ()I
3629 */
3630 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysSmIconWidth(JNIEnv * env,jclass self)3631 Java_sun_awt_windows_WWindowPeer_getSysSmIconWidth(JNIEnv *env, jclass self)
3632 {
3633 TRY;
3634
3635 return getSystemMetricValue(SM_CXSMICON);
3636
3637 CATCH_BAD_ALLOC_RET(0);
3638 }
3639
getSystemMetricValue(int msgType)3640 int getSystemMetricValue(int msgType) {
3641 int value = 1;
3642 int logPixels = LOGPIXELSX;
3643 switch (msgType) {
3644 case SM_CXICON:
3645 value = ::GetSystemMetrics(SM_CXICON);
3646 break;
3647 case SM_CYICON:
3648 value = ::GetSystemMetrics(SM_CYICON);
3649 logPixels = LOGPIXELSY;
3650 break;
3651 case SM_CXSMICON:
3652 value = ::GetSystemMetrics(SM_CXSMICON);
3653 break;
3654 case SM_CYSMICON:
3655 value = ::GetSystemMetrics(SM_CYSMICON);
3656 logPixels = LOGPIXELSY;
3657 break;
3658 }
3659 static int dpi = -1;
3660 if (dpi == -1) {
3661 HWND hWnd = ::GetDesktopWindow();
3662 HDC hDC = ::GetDC(hWnd);
3663 dpi = GetDeviceCaps(hDC, logPixels);
3664 ::ReleaseDC(hWnd, hDC);
3665 }
3666 if(dpi != 0 && dpi != 96) {
3667 float invScaleX = 96.0f / dpi;
3668 value = (int) ROUND_TO_INT(value * invScaleX);
3669 }
3670 return value;
3671 }
3672
3673 /*
3674 * Class: sun_awt_windows_WWindowPeer
3675 * Method: setIconImagesData
3676 * Signature: ([I)V
3677 */
3678 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setIconImagesData(JNIEnv * env,jobject self,jintArray iconRaster,jint w,jint h,jintArray smallIconRaster,jint smw,jint smh)3679 Java_sun_awt_windows_WWindowPeer_setIconImagesData(JNIEnv *env, jobject self,
3680 jintArray iconRaster, jint w, jint h,
3681 jintArray smallIconRaster, jint smw, jint smh)
3682 {
3683 TRY;
3684
3685 SetIconImagesDataStruct *sims = new SetIconImagesDataStruct;
3686
3687 sims->window = env->NewGlobalRef(self);
3688 sims->iconRaster = (jintArray)env->NewGlobalRef(iconRaster);
3689 sims->w = w;
3690 sims->h = h;
3691 sims->smallIconRaster = (jintArray)env->NewGlobalRef(smallIconRaster);
3692 sims->smw = smw;
3693 sims->smh = smh;
3694
3695 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetIconImagesData, sims);
3696 // global refs and sims are deleted in _SetIconImagesData()
3697
3698 CATCH_BAD_ALLOC;
3699 }
3700
3701 /*
3702 * Class: sun_awt_windows_WWindowPeer
3703 * Method: setMinSize
3704 * Signature: (Lsun/awt/windows/WWindowPeer;)V
3705 */
3706 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setMinSize(JNIEnv * env,jobject self,jint w,jint h)3707 Java_sun_awt_windows_WWindowPeer_setMinSize(JNIEnv *env, jobject self,
3708 jint w, jint h)
3709 {
3710 TRY;
3711
3712 SizeStruct *ss = new SizeStruct;
3713 ss->window = env->NewGlobalRef(self);
3714 ss->w = w;
3715 ss->h = h;
3716
3717 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetMinSize, ss);
3718 // global refs and mds are deleted in _SetMinSize
3719
3720 CATCH_BAD_ALLOC;
3721 }
3722
3723 /*
3724 * Class: sun_awt_windows_WWindowPeer
3725 * Method: getScreenImOn
3726 * Signature: ()I
3727 */
3728 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv * env,jobject self)3729 Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self)
3730 {
3731 TRY;
3732
3733 return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall(
3734 (void *(*)(void *))AwtWindow::_GetScreenImOn,
3735 env->NewGlobalRef(self))));
3736 // global ref is deleted in _GetScreenImOn()
3737
3738 CATCH_BAD_ALLOC_RET(-1);
3739 }
3740
3741 /*
3742 * Class: sun_awt_windows_WWindowPeer
3743 * Method: setFullScreenExclusiveModeState
3744 * Signature: (Z)V
3745 */
3746 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv * env,jobject self,jboolean state)3747 Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env,
3748 jobject self, jboolean state)
3749 {
3750 TRY;
3751
3752 SetFullScreenExclusiveModeStateStruct *data =
3753 new SetFullScreenExclusiveModeStateStruct;
3754 data->window = env->NewGlobalRef(self);
3755 data->isFSEMState = state;
3756
3757 AwtToolkit::GetInstance().SyncCall(
3758 AwtWindow::_SetFullScreenExclusiveModeState, data);
3759 // global ref and data are deleted in the invoked method
3760
3761 CATCH_BAD_ALLOC;
3762 }
3763
3764 /*
3765 * Class: sun_awt_windows_WWindowPeer
3766 * Method: modalDisable
3767 * Signature: (J)V
3768 */
3769 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_modalDisable(JNIEnv * env,jobject self,jobject blocker,jlong blockerHWnd)3770 Java_sun_awt_windows_WWindowPeer_modalDisable(JNIEnv *env, jobject self,
3771 jobject blocker, jlong blockerHWnd)
3772 {
3773 TRY;
3774
3775 ModalDisableStruct *mds = new ModalDisableStruct;
3776 mds->window = env->NewGlobalRef(self);
3777 mds->blockerHWnd = blockerHWnd;
3778
3779 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalDisable, mds);
3780 // global ref and mds are deleted in _ModalDisable
3781
3782 CATCH_BAD_ALLOC;
3783 }
3784
3785 /*
3786 * Class: sun_awt_windows_WWindowPeer
3787 * Method: modalEnable
3788 * Signature: ()V
3789 */
3790 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_modalEnable(JNIEnv * env,jobject self,jobject blocker)3791 Java_sun_awt_windows_WWindowPeer_modalEnable(JNIEnv *env, jobject self, jobject blocker)
3792 {
3793 TRY;
3794
3795 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalEnable,
3796 env->NewGlobalRef(self));
3797 // global ref is deleted in _ModalEnable
3798
3799 CATCH_BAD_ALLOC;
3800 }
3801
3802 /*
3803 * Class: sun_awt_windows_WWindowPeer
3804 * Method: setFocusableWindow
3805 * Signature: (Z)V
3806 */
3807 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setFocusableWindow(JNIEnv * env,jobject self,jboolean isFocusableWindow)3808 Java_sun_awt_windows_WWindowPeer_setFocusableWindow(JNIEnv *env, jobject self, jboolean isFocusableWindow)
3809 {
3810 TRY;
3811
3812 SetFocusableWindowStruct *sfws = new SetFocusableWindowStruct;
3813 sfws->window = env->NewGlobalRef(self);
3814 sfws->isFocusableWindow = isFocusableWindow;
3815
3816 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetFocusableWindow, sfws);
3817 // global ref and sfws are deleted in _SetFocusableWindow()
3818
3819 CATCH_BAD_ALLOC;
3820 }
3821
3822 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_nativeGrab(JNIEnv * env,jobject self)3823 Java_sun_awt_windows_WWindowPeer_nativeGrab(JNIEnv *env, jobject self)
3824 {
3825 TRY;
3826
3827 AwtToolkit::GetInstance().SyncCall(AwtWindow::_Grab, env->NewGlobalRef(self));
3828 // global ref is deleted in _Grab()
3829
3830 CATCH_BAD_ALLOC;
3831 }
3832
3833 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv * env,jobject self)3834 Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self)
3835 {
3836 TRY;
3837
3838 AwtToolkit::GetInstance().SyncCall(AwtWindow::_Ungrab, env->NewGlobalRef(self));
3839 // global ref is deleted in _Ungrab()
3840
3841 CATCH_BAD_ALLOC;
3842 }
3843
3844 /*
3845 * Class: sun_awt_windows_WWindowPeer
3846 * Method: setOpacity
3847 * Signature: (I)V
3848 */
3849 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv * env,jobject self,jint iOpacity)3850 Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv *env, jobject self,
3851 jint iOpacity)
3852 {
3853 TRY;
3854
3855 OpacityStruct *os = new OpacityStruct;
3856 os->window = env->NewGlobalRef(self);
3857 os->iOpacity = iOpacity;
3858
3859 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os);
3860 // global refs and mds are deleted in _SetMinSize
3861
3862 CATCH_BAD_ALLOC;
3863 }
3864
3865 /*
3866 * Class: sun_awt_windows_WWindowPeer
3867 * Method: setOpaqueImpl
3868 * Signature: (Z)V
3869 */
3870 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv * env,jobject self,jboolean isOpaque)3871 Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv *env, jobject self,
3872 jboolean isOpaque)
3873 {
3874 TRY;
3875
3876 OpaqueStruct *os = new OpaqueStruct;
3877 os->window = env->NewGlobalRef(self);
3878 os->isOpaque = isOpaque;
3879
3880 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os);
3881 // global refs and mds are deleted in _SetMinSize
3882
3883 CATCH_BAD_ALLOC;
3884 }
3885
3886 /*
3887 * Class: sun_awt_windows_WWindowPeer
3888 * Method: updateWindowImpl
3889 * Signature: ([III)V
3890 */
3891 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv * env,jobject self,jintArray data,jint width,jint height)3892 Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv *env, jobject self,
3893 jintArray data,
3894 jint width, jint height)
3895 {
3896 TRY;
3897
3898 UpdateWindowStruct *uws = new UpdateWindowStruct;
3899 uws->window = env->NewGlobalRef(self);
3900 uws->data = (jintArray)env->NewGlobalRef(data);
3901 uws->hBitmap = NULL;
3902 uws->width = width;
3903 uws->height = height;
3904
3905 AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
3906 // global refs and mds are deleted in _UpdateWindow
3907
3908 CATCH_BAD_ALLOC;
3909 }
3910
3911 /**
3912 * This method is called from the WGL pipeline when it needs to update
3913 * the layered window WindowPeer's C++ level object.
3914 */
AwtWindow_UpdateWindow(JNIEnv * env,jobject peer,jint width,jint height,HBITMAP hBitmap)3915 void AwtWindow_UpdateWindow(JNIEnv *env, jobject peer,
3916 jint width, jint height, HBITMAP hBitmap)
3917 {
3918 TRY;
3919
3920 UpdateWindowStruct *uws = new UpdateWindowStruct;
3921 uws->window = env->NewGlobalRef(peer);
3922 uws->data = NULL;
3923 uws->hBitmap = hBitmap;
3924 uws->width = width;
3925 uws->height = height;
3926
3927 AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
3928 // global refs and mds are deleted in _UpdateWindow
3929
3930 CATCH_BAD_ALLOC;
3931 }
3932
3933 /*
3934 * Class: sun_awt_windows_WComponentPeer
3935 * Method: requestFocus
3936 * Signature: (Z)Z
3937 */
Java_sun_awt_windows_WWindowPeer_requestWindowFocus(JNIEnv * env,jobject self,jboolean isMouseEventCause)3938 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WWindowPeer_requestWindowFocus
3939 (JNIEnv *env, jobject self, jboolean isMouseEventCause)
3940 {
3941 TRY;
3942
3943 jobject selfGlobalRef = env->NewGlobalRef(self);
3944
3945 RequestWindowFocusStruct *rfs = new RequestWindowFocusStruct;
3946 rfs->component = selfGlobalRef;
3947 rfs->isMouseEventCause = isMouseEventCause;
3948
3949 return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
3950 (void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs));
3951 // global refs and rfs are deleted in _RequestWindowFocus
3952
3953 CATCH_BAD_ALLOC_RET(JNI_FALSE);
3954 }
3955
3956 /*
3957 * Class: sun_awt_windows_WWindowPeer
3958 * Method: repositionSecurityWarning
3959 * Signature: ()V
3960 */
3961 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv * env,jobject self)3962 Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env,
3963 jobject self)
3964 {
3965 TRY;
3966
3967 RepositionSecurityWarningStruct *rsws =
3968 new RepositionSecurityWarningStruct;
3969 rsws->window = env->NewGlobalRef(self);
3970
3971 AwtToolkit::GetInstance().InvokeFunction(
3972 AwtWindow::_RepositionSecurityWarning, rsws);
3973 // global refs and mds are deleted in _RepositionSecurityWarning
3974
3975 CATCH_BAD_ALLOC;
3976 }
3977
3978 /*
3979 * Class: sun_awt_windows_WWindowPeer
3980 * Method: windowDPIChange
3981 * Signature: (IFFIFF)V
3982 */
3983 JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_windowDPIChange(JNIEnv * env,jobject self,jint prevScreen,jfloat prevScaleX,jfloat prevScaleY,jint screen,jfloat scaleX,jfloat scaleY)3984 Java_sun_awt_windows_WWindowPeer_windowDPIChange(JNIEnv *env, jobject self,
3985 jint prevScreen, jfloat prevScaleX, jfloat prevScaleY,
3986 jint screen, jfloat scaleX, jfloat scaleY)
3987 {
3988 TRY;
3989
3990 ScaleStruct *ss = new ScaleStruct;
3991 ss->window = env->NewGlobalRef(self);
3992 ss->prevScreen = prevScreen;
3993 ss->prevScaleX = prevScaleX;
3994 ss->prevScaleY = prevScaleY;
3995 ss->screen = screen;
3996 ss->scaleX = scaleX;
3997 ss->scaleY = scaleY;
3998
3999 AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_WindowDPIChange, ss);
4000 // global refs and ss are deleted in _WindowDPIChange
4001
4002 CATCH_BAD_ALLOC;
4003 }
4004
4005 /*
4006 * Class: sun_awt_windows_WLightweightFramePeer
4007 * Method: overrideNativeHandle
4008 * Signature: (J)V
4009 */
Java_sun_awt_windows_WLightweightFramePeer_overrideNativeHandle(JNIEnv * env,jobject self,jlong hwnd)4010 JNIEXPORT void JNICALL Java_sun_awt_windows_WLightweightFramePeer_overrideNativeHandle
4011 (JNIEnv *env, jobject self, jlong hwnd)
4012 {
4013 TRY;
4014
4015 OverrideHandle *oh = new OverrideHandle;
4016 oh->frame = env->NewGlobalRef(self);
4017 oh->handle = (HWND) hwnd;
4018
4019 AwtToolkit::GetInstance().SyncCall(AwtFrame::_OverrideHandle, oh);
4020 // global ref and oh are deleted in _OverrideHandle()
4021
4022 CATCH_BAD_ALLOC;
4023 }
4024
4025 } /* extern "C" */
4026