1 /* 2 * Copyright (c) 1996, 2020, 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 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 253 AwtWindow::~AwtWindow() 254 { 255 if (warningString != NULL) { 256 delete [] warningString; 257 } 258 DeleteContentBitmap(); 259 ::DeleteCriticalSection(&contentBitmapCS); 260 } 261 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 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 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 319 AwtWindow::Ungrab() { 320 Ungrab(TRUE); 321 } 322 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 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 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 374 MsgRouting AwtWindow::WmWindowPosChanging(LPARAM windowPos) { 375 return mrDoDefault; 376 } 377 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 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 417 LPCTSTR AwtWindow::GetClassName() { 418 return TEXT("SunAwtWindow"); 419 } 420 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 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 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 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 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 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 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 641 void AwtWindow::DestroyHWnd() 642 { 643 DestroyWarningWindow(); 644 AwtCanvas::DestroyHWnd(); 645 } 646 647 LPCTSTR AwtWindow::GetWarningWindowClassName() 648 { 649 return TEXT("SunAwtWarningWindow"); 650 } 651 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 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 681 void AwtWindow::UnregisterWarningWindowClass() 682 { 683 ::UnregisterClass(AwtWindow::GetWarningWindowClassName(), AwtToolkit::GetInstance().GetModuleHandle()); 684 } 685 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. 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 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 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 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 843 void AwtWindow::RepaintWarningWindow() 844 { 845 HDC hdc = ::GetDC(warningWindow); 846 PaintWarningWindow(warningWindow, hdc); 847 ::ReleaseDC(warningWindow, hdc); 848 } 849 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 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 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 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 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. 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 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 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 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 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. */ 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 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 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 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 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 */ 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 */ 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 */ 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 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 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 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 1718 MsgRouting AwtWindow::WmCreate() 1719 { 1720 return mrDoDefault; 1721 } 1722 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 1731 MsgRouting AwtWindow::WmDestroy() 1732 { 1733 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSED); 1734 return AwtComponent::WmDestroy(); 1735 } 1736 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 */ 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 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 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 1846 MsgRouting AwtWindow::WmEnterSizeMove() 1847 { 1848 m_winSizeMove = TRUE; 1849 return mrDoDefault; 1850 } 1851 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 */ 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 1897 MsgRouting AwtWindow::WmPaint(HDC) 1898 { 1899 PaintUpdateRgn(&m_insets); 1900 return mrConsume; 1901 } 1902 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 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 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 1958 MsgRouting AwtWindow::WmGetIcon(WPARAM iconType, LRESULT& retValue) 1959 { 1960 return mrDoDefault; 1961 } 1962 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 */ 2018 MsgRouting AwtWindow::HandleEvent(MSG *msg, BOOL synthetic) 2019 { 2020 return AwtComponent::HandleEvent(msg, synthetic); 2021 } 2022 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 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 2042 void AwtWindow::Invalidate(RECT* r) 2043 { 2044 ::InvalidateRect(GetHWnd(), NULL, TRUE); 2045 ::EnumChildWindows(GetHWnd(), (WNDENUMPROC)InvalidateChildRect, 0); 2046 } 2047 2048 BOOL AwtWindow::IsResizable() { 2049 return m_isResizable; 2050 } 2051 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 // 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 // 2094 void AwtWindow::RedrawNonClient() 2095 { 2096 ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_ASYNCWINDOWPOS); 2097 } 2098 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 = p->ScaleDownX(::GetSystemMetrics(SM_CXMIN)); 2569 int minHeight = p->ScaleDownY(::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 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 */ 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 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 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 2732 void AwtWindow::DoUpdateIcon() 2733 { 2734 //Does nothing for windows, is overriden for frames and dialogs 2735 } 2736 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 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. 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 */ 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 _SetOpacity 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 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 _SetOpaque 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 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 */ 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 */ 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 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 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 */ 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" */