1 /* 2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "awt.h" 27 28 #include <jlong.h> 29 30 #include "awt_Component.h" 31 #include "awt_Container.h" 32 #include "awt_Frame.h" 33 #include "awt_Dialog.h" 34 #include "awt_Insets.h" 35 #include "awt_Panel.h" 36 #include "awt_Toolkit.h" 37 #include "awt_Window.h" 38 #include "awt_Win32GraphicsDevice.h" 39 #include "awt_BitmapUtil.h" 40 #include "awt_IconCursor.h" 41 #include "ComCtl32Util.h" 42 43 #include "java_awt_Insets.h" 44 #include <java_awt_Container.h> 45 #include <java_awt_event_ComponentEvent.h> 46 #include "sun_awt_windows_WCanvasPeer.h" 47 48 #include <windowsx.h> 49 #include <math.h> 50 #if !defined(__int3264) 51 typedef __int32 LONG_PTR; 52 #endif // __int3264 53 54 #if defined(_MSC_VER) && _MSC_VER >= 1800 55 # define ROUND_TO_INT(num) ((int) round(num)) 56 #else 57 # define ROUND_TO_INT(num) ((int) floor((num) + 0.5)) 58 #endif 59 // Used for Swing's Menu/Tooltip animation Support 60 const int UNSPECIFIED = 0; 61 const int TOOLTIP = 1; 62 const int MENU = 2; 63 const int SUBMENU = 3; 64 const int POPUPMENU = 4; 65 const int COMBOBOX_POPUP = 5; 66 const int TYPES_COUNT = 6; 67 jint windowTYPES[TYPES_COUNT]; 68 69 70 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 71 */ 72 73 /***********************************************************************/ 74 // struct for _SetAlwaysOnTop() method 75 struct SetAlwaysOnTopStruct { 76 jobject window; 77 jboolean value; 78 }; 79 // struct for _SetTitle() method 80 struct SetTitleStruct { 81 jobject window; 82 jstring title; 83 }; 84 // struct for _SetResizable() method 85 struct SetResizableStruct { 86 jobject window; 87 jboolean resizable; 88 }; 89 // struct for _UpdateInsets() method 90 struct UpdateInsetsStruct { 91 jobject window; 92 jobject insets; 93 }; 94 // struct for _ReshapeFrame() method 95 struct ReshapeFrameStruct { 96 jobject frame; 97 jint x, y; 98 jint w, h; 99 }; 100 // struct for _SetIconImagesData 101 struct SetIconImagesDataStruct { 102 jobject window; 103 jintArray iconRaster; 104 jint w, h; 105 jintArray smallIconRaster; 106 jint smw, smh; 107 }; 108 // struct for _SetMinSize() method 109 // and other methods setting sizes 110 struct SizeStruct { 111 jobject window; 112 jint w, h; 113 }; 114 // struct for _SetFocusableWindow() method 115 struct SetFocusableWindowStruct { 116 jobject window; 117 jboolean isFocusableWindow; 118 }; 119 // struct for _ModalDisable() method 120 struct ModalDisableStruct { 121 jobject window; 122 jlong blockerHWnd; 123 }; 124 // struct for _SetOpacity() method 125 struct OpacityStruct { 126 jobject window; 127 jint iOpacity; 128 }; 129 // struct for _SetOpaque() method 130 struct OpaqueStruct { 131 jobject window; 132 jboolean isOpaque; 133 }; 134 // struct for _UpdateWindow() method 135 struct UpdateWindowStruct { 136 jobject window; 137 jintArray data; 138 HBITMAP hBitmap; 139 jint width, height; 140 }; 141 // Struct for _RequestWindowFocus() method 142 struct RequestWindowFocusStruct { 143 jobject component; 144 jboolean isMouseEventCause; 145 }; 146 // struct for _RepositionSecurityWarning() method 147 struct RepositionSecurityWarningStruct { 148 jobject window; 149 }; 150 151 struct SetFullScreenExclusiveModeStateStruct { 152 jobject window; 153 jboolean isFSEMState; 154 }; 155 156 // struct for _WindowDPIChange() method 157 struct ScaleStruct { 158 jobject window; 159 jint prevScreen; 160 jfloat prevScaleX; 161 jfloat prevScaleY; 162 jint screen; 163 jfloat scaleX; 164 jfloat scaleY; 165 }; 166 167 struct OverrideHandle { 168 jobject frame; 169 HWND handle; 170 }; 171 172 /************************************************************************ 173 * AwtWindow fields 174 */ 175 176 jfieldID AwtWindow::warningStringID; 177 jfieldID AwtWindow::locationByPlatformID; 178 jfieldID AwtWindow::autoRequestFocusID; 179 jfieldID AwtWindow::securityWarningWidthID; 180 jfieldID AwtWindow::securityWarningHeightID; 181 182 jfieldID AwtWindow::sysXID; 183 jfieldID AwtWindow::sysYID; 184 jfieldID AwtWindow::sysWID; 185 jfieldID AwtWindow::sysHID; 186 jfieldID AwtWindow::windowTypeID; 187 188 jmethodID AwtWindow::getWarningStringMID; 189 jmethodID AwtWindow::calculateSecurityWarningPositionMID; 190 jmethodID AwtWindow::windowTypeNameMID; 191 192 int AwtWindow::ms_instanceCounter = 0; 193 HHOOK AwtWindow::ms_hCBTFilter; 194 AwtWindow * AwtWindow::m_grabbedWindow = NULL; 195 BOOL AwtWindow::sm_resizing = FALSE; 196 UINT AwtWindow::untrustedWindowsCounter = 0; 197 198 /************************************************************************ 199 * AwtWindow class methods 200 */ 201 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 if (env->EnsureLocalCapacity(3) < 0) { 1575 return; 1576 } 1577 1578 jobject target = GetTarget(env); 1579 jobject jOpposite = NULL; 1580 if (opposite != NULL) { 1581 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite); 1582 if (awtOpposite != NULL) { 1583 jOpposite = awtOpposite->GetTarget(env); 1584 } 1585 } 1586 jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id, 1587 jOpposite, oldState, newState, ::JVM_CurrentTimeMillis(NULL, 0)); 1588 DASSERT(!safe_ExceptionOccurred(env)); 1589 DASSERT(event != NULL); 1590 if (jOpposite != NULL) { 1591 env->DeleteLocalRef(jOpposite); jOpposite = NULL; 1592 } 1593 env->DeleteLocalRef(target); target = NULL; 1594 CHECK_NULL(event); 1595 1596 if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS || 1597 id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS) 1598 { 1599 jobject sequencedEvent = env->NewObject(sequencedEventCls, 1600 sequencedEventConst, 1601 event); 1602 DASSERT(!safe_ExceptionOccurred(env)); 1603 DASSERT(sequencedEvent != NULL); 1604 env->DeleteLocalRef(event); 1605 event = sequencedEvent; 1606 } 1607 1608 SendEvent(event); 1609 1610 env->DeleteLocalRef(event); 1611 } 1612 1613 BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest) 1614 { 1615 // We used to reject non mouse window activation if our app wasn't active. 1616 // This code since has been removed as the fix for 7185280 1617 1618 HWND proxyContainerHWnd = GetProxyToplevelContainer(); 1619 HWND proxyHWnd = GetProxyFocusOwner(); 1620 1621 if (proxyContainerHWnd == NULL || proxyHWnd == NULL) { 1622 return FALSE; 1623 } 1624 1625 // Activate the proxy toplevel container 1626 if (::GetActiveWindow() != proxyContainerHWnd) { 1627 sm_suppressFocusAndActivation = TRUE; 1628 ::BringWindowToTop(proxyContainerHWnd); 1629 ::SetForegroundWindow(proxyContainerHWnd); 1630 sm_suppressFocusAndActivation = FALSE; 1631 1632 if (::GetActiveWindow() != proxyContainerHWnd) { 1633 return FALSE; // activation has been rejected 1634 } 1635 } 1636 1637 // Focus the proxy itself 1638 if (::GetFocus() != proxyHWnd) { 1639 sm_suppressFocusAndActivation = TRUE; 1640 ::SetFocus(proxyHWnd); 1641 sm_suppressFocusAndActivation = FALSE; 1642 1643 if (::GetFocus() != proxyHWnd) { 1644 return FALSE; // focus has been rejected (that is unlikely) 1645 } 1646 } 1647 1648 const HWND focusedWindow = AwtComponent::GetFocusedWindow(); 1649 if (focusedWindow != GetHWnd()) { 1650 if (focusedWindow != NULL) { 1651 // Deactivate the old focused window 1652 AwtWindow::SynthesizeWmActivate(FALSE, focusedWindow, GetHWnd()); 1653 } 1654 // Activate the new focused window. 1655 AwtWindow::SynthesizeWmActivate(TRUE, GetHWnd(), focusedWindow); 1656 } 1657 return TRUE; 1658 } 1659 1660 MsgRouting AwtWindow::WmActivate(UINT nState, BOOL fMinimized, HWND opposite) 1661 { 1662 jint type; 1663 1664 if (nState != WA_INACTIVE) { 1665 type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS; 1666 AwtComponent::SetFocusedWindow(GetHWnd()); 1667 } else { 1668 // The owner is not necassarily getting WM_ACTIVATE(WA_INACTIVE). 1669 // So, initiate retaining the actualFocusedWindow. 1670 AwtFrame *owner = GetOwningFrameOrDialog(); 1671 if (owner) { 1672 owner->CheckRetainActualFocusedWindow(opposite); 1673 } 1674 1675 if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) { 1676 m_grabbedWindow->Ungrab(); 1677 } 1678 type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS; 1679 AwtComponent::SetFocusedWindow(NULL); 1680 sm_focusOwner = NULL; 1681 } 1682 1683 SendWindowEvent(type, opposite); 1684 return mrConsume; 1685 } 1686 1687 MsgRouting AwtWindow::WmCreate() 1688 { 1689 return mrDoDefault; 1690 } 1691 1692 MsgRouting AwtWindow::WmClose() 1693 { 1694 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSING); 1695 1696 /* Rely on above notification to handle quitting as needed */ 1697 return mrConsume; 1698 } 1699 1700 MsgRouting AwtWindow::WmDestroy() 1701 { 1702 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSED); 1703 return AwtComponent::WmDestroy(); 1704 } 1705 1706 MsgRouting AwtWindow::WmShowWindow(BOOL show, UINT status) 1707 { 1708 /* 1709 * Original fix for 4810575. Modified for 6386592. 1710 * If a simple window gets disposed we should synthesize 1711 * WM_ACTIVATE for its nearest owner. This is not performed by default because 1712 * the owner frame/dialog is natively active. 1713 */ 1714 HWND hwndSelf = GetHWnd(); 1715 HWND hwndOwner = ::GetParent(hwndSelf); 1716 1717 if (!show && IsSimpleWindow() && hwndSelf == AwtComponent::GetFocusedWindow() && 1718 hwndOwner != NULL && ::IsWindowVisible(hwndOwner)) 1719 { 1720 AwtFrame *owner = (AwtFrame*)AwtComponent::GetComponent(hwndOwner); 1721 if (owner != NULL) { 1722 owner->AwtSetActiveWindow(); 1723 } 1724 } 1725 1726 //Fixed 4842599: REGRESSION: JPopupMenu not Hidden Properly After Iconified and Deiconified 1727 if (show && (status == SW_PARENTOPENING)) { 1728 if (!IsVisible()) { 1729 return mrConsume; 1730 } 1731 } 1732 return AwtCanvas::WmShowWindow(show, status); 1733 } 1734 1735 /* 1736 * Override AwtComponent's move handling to first update the 1737 * java AWT target's position fields directly, since Windows 1738 * and below can be resized from outside of java (by user) 1739 */ 1740 MsgRouting AwtWindow::WmMove(int x, int y) 1741 { 1742 if ( ::IsIconic(GetHWnd()) ) { 1743 // fixes 4065534 (robi.khan@eng) 1744 // if a window is iconified we don't want to update 1745 // it's target's position since minimized Win32 windows 1746 // move to -32000, -32000 for whatever reason 1747 // NOTE: See also AwtWindow::Reshape 1748 return mrDoDefault; 1749 } 1750 1751 if (m_screenNum == -1) { 1752 // Set initial value 1753 m_screenNum = GetScreenImOn(); 1754 } 1755 else { 1756 CheckIfOnNewScreen(); 1757 } 1758 1759 /* Update the java AWT target component's fields directly */ 1760 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1761 if (env->EnsureLocalCapacity(1) < 0) { 1762 return mrConsume; 1763 } 1764 jobject peer = GetPeer(env); 1765 jobject target = env->GetObjectField(peer, AwtObject::targetID); 1766 1767 RECT rect; 1768 ::GetWindowRect(GetHWnd(), &rect); 1769 1770 (env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left)); 1771 (env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top)); 1772 (env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left)); 1773 (env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top)); 1774 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED); 1775 1776 env->DeleteLocalRef(target); 1777 return AwtComponent::WmMove(x, y); 1778 } 1779 1780 MsgRouting AwtWindow::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 1781 { 1782 MsgRouting r = AwtCanvas::WmGetMinMaxInfo(lpmmi); 1783 if ((m_minSize.x == 0) && (m_minSize.y == 0)) { 1784 return r; 1785 } 1786 lpmmi->ptMinTrackSize.x = m_minSize.x; 1787 lpmmi->ptMinTrackSize.y = m_minSize.y; 1788 return mrConsume; 1789 } 1790 1791 MsgRouting AwtWindow::WmSizing() 1792 { 1793 if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) { 1794 return mrDoDefault; 1795 } 1796 1797 DTRACE_PRINTLN("AwtWindow::WmSizing fullWindowDragEnabled"); 1798 1799 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED); 1800 1801 HWND thisHwnd = GetHWnd(); 1802 if (thisHwnd == NULL) { 1803 return mrDoDefault; 1804 } 1805 1806 // Call WComponentPeer::dynamicallyLayoutContainer() 1807 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1808 jobject peer = GetPeer(env); 1809 JNU_CallMethodByName(env, NULL, peer, "dynamicallyLayoutContainer", "()V"); 1810 DASSERT(!safe_ExceptionOccurred(env)); 1811 1812 return mrDoDefault; 1813 } 1814 1815 MsgRouting AwtWindow::WmEnterSizeMove() 1816 { 1817 m_winSizeMove = TRUE; 1818 return mrDoDefault; 1819 } 1820 1821 MsgRouting AwtWindow::WmExitSizeMove() 1822 { 1823 m_winSizeMove = FALSE; 1824 CheckWindowDPIChange(); 1825 return mrDoDefault; 1826 } 1827 1828 /* 1829 * Override AwtComponent's size handling to first update the 1830 * java AWT target's dimension fields directly, since Windows 1831 * and below can be resized from outside of java (by user) 1832 */ 1833 MsgRouting AwtWindow::WmSize(UINT type, int w, int h) 1834 { 1835 currentWmSizeState = type; 1836 1837 if (type == SIZE_MINIMIZED) { 1838 UpdateSecurityWarningVisibility(); 1839 return mrDoDefault; 1840 } 1841 1842 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1843 if (env->EnsureLocalCapacity(1) < 0) 1844 return mrDoDefault; 1845 jobject target = GetTarget(env); 1846 // fix 4167248 : ensure the insets are up-to-date before using 1847 BOOL insetsChanged = UpdateInsets(NULL); 1848 int newWidth = w + m_insets.left + m_insets.right; 1849 int newHeight = h + m_insets.top + m_insets.bottom; 1850 1851 (env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth)); 1852 (env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight)); 1853 1854 jobject peer = GetPeer(env); 1855 (env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth)); 1856 (env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight)); 1857 1858 if (!AwtWindow::IsResizing()) { 1859 WindowResized(); 1860 } 1861 1862 env->DeleteLocalRef(target); 1863 return AwtComponent::WmSize(type, w, h); 1864 } 1865 1866 MsgRouting AwtWindow::WmPaint(HDC) 1867 { 1868 PaintUpdateRgn(&m_insets); 1869 return mrConsume; 1870 } 1871 1872 MsgRouting AwtWindow::WmSettingChange(UINT wFlag, LPCTSTR pszSection) 1873 { 1874 if (wFlag == SPI_SETNONCLIENTMETRICS) { 1875 // user changed window metrics in 1876 // Control Panel->Display->Appearance 1877 // which may cause window insets to change 1878 UpdateInsets(NULL); 1879 1880 // [rray] fix for 4407329 - Changing Active Window Border width in display 1881 // settings causes problems 1882 WindowResized(); 1883 Invalidate(NULL); 1884 1885 return mrConsume; 1886 } 1887 return mrDoDefault; 1888 } 1889 1890 MsgRouting AwtWindow::WmNcCalcSize(BOOL fCalcValidRects, 1891 LPNCCALCSIZE_PARAMS lpncsp, LRESULT& retVal) 1892 { 1893 MsgRouting mrRetVal = mrDoDefault; 1894 1895 if (fCalcValidRects == FALSE) { 1896 return mrDoDefault; 1897 } 1898 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1899 if (env->EnsureLocalCapacity(2) < 0) { 1900 return mrConsume; 1901 } 1902 // WM_NCCALCSIZE is usually in response to a resize, but 1903 // also can be triggered by SetWindowPos(SWP_FRAMECHANGED), 1904 // which means the insets will have changed - rnk 4/7/1998 1905 retVal = static_cast<UINT>(DefWindowProc( 1906 WM_NCCALCSIZE, fCalcValidRects, reinterpret_cast<LPARAM>(lpncsp))); 1907 if (HasValidRect()) { 1908 UpdateInsets(NULL); 1909 } 1910 mrRetVal = mrConsume; 1911 return mrRetVal; 1912 } 1913 1914 MsgRouting AwtWindow::WmNcHitTest(UINT x, UINT y, LRESULT& retVal) 1915 { 1916 // If this window is blocked by modal dialog, return HTCLIENT for any point of it. 1917 // That prevents it to be moved or resized using the mouse. Disabling these 1918 // actions to be launched from sysmenu is implemented by ignoring WM_SYSCOMMAND 1919 if (::IsWindow(GetModalBlocker(GetHWnd()))) { 1920 retVal = HTCLIENT; 1921 } else { 1922 retVal = DefWindowProc(WM_NCHITTEST, 0, MAKELPARAM(x, y)); 1923 } 1924 return mrConsume; 1925 } 1926 1927 MsgRouting AwtWindow::WmGetIcon(WPARAM iconType, LRESULT& retValue) 1928 { 1929 return mrDoDefault; 1930 } 1931 1932 LRESULT AwtWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 1933 { 1934 MsgRouting mr = mrDoDefault; 1935 LRESULT retValue = 0L; 1936 1937 switch(message) { 1938 case WM_GETICON: 1939 mr = WmGetIcon(wParam, retValue); 1940 break; 1941 case WM_SYSCOMMAND: 1942 //Fixed 6355340: Contents of frame are not layed out properly on maximize 1943 if ((wParam & 0xFFF0) == SC_SIZE) { 1944 AwtWindow::sm_resizing = TRUE; 1945 mr = WmSysCommand(static_cast<UINT>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1946 if (mr != mrConsume) { 1947 // Perform size-move loop here 1948 AwtWindow::DefWindowProc(message, wParam, lParam); 1949 } 1950 AwtWindow::sm_resizing = FALSE; 1951 if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) { 1952 WindowResized(); 1953 } else { 1954 /* 1955 * 8016356: check whether window snapping occurred after 1956 * resizing, i.e. GetWindowRect() returns the real 1957 * (snapped) window rectangle, e.g. (179, 0)-(483, 1040), 1958 * but GetWindowPlacement() returns the rectangle of 1959 * normal window position, e.g. (179, 189)-(483, 445) and 1960 * they are different. If so, send ComponentResized event. 1961 */ 1962 WINDOWPLACEMENT wp; 1963 ::GetWindowPlacement(GetHWnd(), &wp); 1964 RECT rc; 1965 ::GetWindowRect(GetHWnd(), &rc); 1966 if (!::EqualRect(&rc, &wp.rcNormalPosition)) { 1967 WindowResized(); 1968 } 1969 } 1970 mr = mrConsume; 1971 } 1972 break; 1973 } 1974 1975 if (mr != mrConsume) { 1976 retValue = AwtCanvas::WindowProc(message, wParam, lParam); 1977 } 1978 return retValue; 1979 } 1980 1981 /* 1982 * Fix for BugTraq ID 4041703: keyDown not being invoked. 1983 * This method overrides AwtCanvas::HandleEvent() since 1984 * an empty Window always receives the focus on the activation 1985 * so we don't have to modify the behavior. 1986 */ 1987 MsgRouting AwtWindow::HandleEvent(MSG *msg, BOOL synthetic) 1988 { 1989 return AwtComponent::HandleEvent(msg, synthetic); 1990 } 1991 1992 void AwtWindow::WindowResized() 1993 { 1994 SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED); 1995 // Need to replace surfaceData on resize to catch changes to 1996 // various component-related values, such as insets 1997 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1998 env->CallVoidMethod(m_peerObject, AwtComponent::replaceSurfaceDataLaterMID); 1999 } 2000 2001 BOOL CALLBACK InvalidateChildRect(HWND hWnd, LPARAM) 2002 { 2003 TRY; 2004 2005 ::InvalidateRect(hWnd, NULL, TRUE); 2006 return TRUE; 2007 2008 CATCH_BAD_ALLOC_RET(FALSE); 2009 } 2010 2011 void AwtWindow::Invalidate(RECT* r) 2012 { 2013 ::InvalidateRect(GetHWnd(), NULL, TRUE); 2014 ::EnumChildWindows(GetHWnd(), (WNDENUMPROC)InvalidateChildRect, 0); 2015 } 2016 2017 BOOL AwtWindow::IsResizable() { 2018 return m_isResizable; 2019 } 2020 2021 void AwtWindow::SetResizable(BOOL isResizable) 2022 { 2023 m_isResizable = isResizable; 2024 if (IsEmbeddedFrame()) { 2025 return; 2026 } 2027 LONG style = GetStyle(); 2028 LONG resizeStyle = WS_MAXIMIZEBOX; 2029 2030 if (IsUndecorated() == FALSE) { 2031 resizeStyle |= WS_THICKFRAME; 2032 } 2033 2034 if (isResizable) { 2035 style |= resizeStyle; 2036 } else { 2037 style &= ~resizeStyle; 2038 } 2039 SetStyle(style); 2040 RedrawNonClient(); 2041 } 2042 2043 // SetWindowPos flags to cause frame edge to be recalculated 2044 static const UINT SwpFrameChangeFlags = 2045 SWP_FRAMECHANGED | /* causes WM_NCCALCSIZE to be called */ 2046 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | 2047 SWP_NOACTIVATE | SWP_NOCOPYBITS | 2048 SWP_NOREPOSITION | SWP_NOSENDCHANGING; 2049 2050 // 2051 // Forces WM_NCCALCSIZE to be called to recalculate 2052 // window border (updates insets) without redrawing it 2053 // 2054 void AwtWindow::RecalcNonClient() 2055 { 2056 ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_NOREDRAW); 2057 } 2058 2059 // 2060 // Forces WM_NCCALCSIZE to be called to recalculate 2061 // window border (updates insets) and redraws border to match 2062 // 2063 void AwtWindow::RedrawNonClient() 2064 { 2065 ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_ASYNCWINDOWPOS); 2066 } 2067 2068 int AwtWindow::GetScreenImOn() { 2069 HMONITOR hmon; 2070 int scrnNum; 2071 2072 hmon = ::MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY); 2073 DASSERT(hmon != NULL); 2074 2075 scrnNum = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hmon); 2076 DASSERT(scrnNum > -1); 2077 2078 return scrnNum; 2079 } 2080 2081 /* Check to see if we've been moved onto another screen. 2082 * If so, update internal data, surfaces, etc. 2083 */ 2084 2085 void AwtWindow::CheckIfOnNewScreen() { 2086 int curScrn = GetScreenImOn(); 2087 2088 if (curScrn != m_screenNum) { // we've been moved 2089 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2090 2091 jclass peerCls = env->GetObjectClass(m_peerObject); 2092 DASSERT(peerCls); 2093 CHECK_NULL(peerCls); 2094 2095 jmethodID draggedID = env->GetMethodID(peerCls, "draggedToNewScreen", 2096 "()V"); 2097 DASSERT(draggedID); 2098 if (draggedID == NULL) { 2099 env->DeleteLocalRef(peerCls); 2100 return; 2101 } 2102 2103 env->CallVoidMethod(m_peerObject, draggedID); 2104 m_screenNum = curScrn; 2105 2106 env->DeleteLocalRef(peerCls); 2107 } 2108 } 2109 2110 void AwtWindow::CheckWindowDPIChange() { 2111 2112 if (prevScaleRec.screen != -1 ) { 2113 float prevScaleX = prevScaleRec.scaleX; 2114 float prevScaleY = prevScaleRec.scaleY; 2115 2116 if (prevScaleX >= 1 && prevScaleY >= 1) { 2117 Devices::InstanceAccess devices; 2118 AwtWin32GraphicsDevice* device = devices->GetDevice(m_screenNum); 2119 if (device) { 2120 float scaleX = device->GetScaleX(); 2121 float scaleY = device->GetScaleY(); 2122 if (prevScaleX != scaleX || prevScaleY != scaleY) { 2123 WindowDPIChange(prevScaleRec.screen, prevScaleX, prevScaleY, 2124 m_screenNum, scaleX, scaleY); 2125 } 2126 } 2127 } 2128 prevScaleRec.screen = -1; 2129 } 2130 } 2131 2132 void AwtWindow::WindowDPIChange(int prevScreen, 2133 float prevScaleX, float prevScaleY, 2134 int screen, float scaleX, 2135 float scaleY) 2136 { 2137 int x; 2138 int y; 2139 int w; 2140 int h; 2141 RECT rect; 2142 2143 if (prevScaleX == scaleX && prevScaleY == scaleY) { 2144 return; 2145 } 2146 2147 ::GetWindowRect(GetHWnd(), &rect); 2148 x = rect.left; 2149 y = rect.top; 2150 w = static_cast<int>((rect.right - rect.left) * scaleX / prevScaleX); 2151 h = static_cast<int>((rect.bottom - rect.top) * scaleY / prevScaleY); 2152 2153 if (prevScreen != screen) { 2154 Devices::InstanceAccess devices; 2155 AwtWin32GraphicsDevice* device = devices->GetDevice(screen); 2156 if (device) { 2157 RECT bounds; 2158 if (MonitorBounds(device->GetMonitor(), &bounds)) { 2159 x = x < bounds.left ? bounds.left : x; 2160 y = y < bounds.top ? bounds.top : y; 2161 2162 x = (x + w > bounds.right) ? bounds.right - w : x; 2163 y = (y + h > bounds.bottom) ? bounds.bottom - h : y; 2164 } 2165 } 2166 } 2167 2168 ReshapeNoScale(x, y, w, h); 2169 } 2170 2171 BOOL AwtWindow::IsFocusableWindow() { 2172 /* 2173 * For Window/Frame/Dialog to accept focus it should: 2174 * - be focusable; 2175 * - be not blocked by any modal blocker. 2176 */ 2177 BOOL focusable = m_isFocusableWindow && !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); 2178 AwtFrame *owner = GetOwningFrameOrDialog(); // NULL for Frame and Dialog 2179 2180 if (owner != NULL) { 2181 /* 2182 * Also for Window (not Frame/Dialog) to accept focus: 2183 * - its decorated parent should accept focus; 2184 */ 2185 focusable = focusable && owner->IsFocusableWindow(); 2186 } 2187 return focusable; 2188 } 2189 2190 void AwtWindow::SetModalBlocker(HWND window, HWND blocker) { 2191 if (!::IsWindow(window)) { 2192 return; 2193 } 2194 2195 if (::IsWindow(blocker)) { 2196 ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker)); 2197 ::EnableWindow(window, FALSE); 2198 } else { 2199 ::RemoveProp(window, ModalBlockerProp); 2200 AwtComponent *comp = AwtComponent::GetComponent(window); 2201 // we don't expect to be called with non-java HWNDs 2202 DASSERT(comp && comp->IsTopLevel()); 2203 // we should not unblock disabled toplevels 2204 ::EnableWindow(window, comp->isEnabled()); 2205 } 2206 } 2207 2208 void AwtWindow::SetAndActivateModalBlocker(HWND window, HWND blocker) { 2209 if (!::IsWindow(window)) { 2210 return; 2211 } 2212 AwtWindow::SetModalBlocker(window, blocker); 2213 if (::IsWindow(blocker)) { 2214 // We must check for visibility. Otherwise invisible dialog will receive WM_ACTIVATE. 2215 if (::IsWindowVisible(blocker)) { 2216 ::BringWindowToTop(blocker); 2217 ::SetForegroundWindow(blocker); 2218 } 2219 } 2220 } 2221 2222 HWND AwtWindow::GetTopmostModalBlocker(HWND window) 2223 { 2224 HWND ret, blocker = NULL; 2225 2226 do { 2227 ret = blocker; 2228 blocker = AwtWindow::GetModalBlocker(window); 2229 window = blocker; 2230 } while (::IsWindow(blocker)); 2231 2232 return ret; 2233 } 2234 2235 void AwtWindow::FlashWindowEx(HWND hWnd, UINT count, DWORD timeout, DWORD flags) { 2236 FLASHWINFO fi; 2237 fi.cbSize = sizeof(fi); 2238 fi.hwnd = hWnd; 2239 fi.dwFlags = flags; 2240 fi.uCount = count; 2241 fi.dwTimeout = timeout; 2242 ::FlashWindowEx(&fi); 2243 } 2244 2245 jboolean 2246 AwtWindow::_RequestWindowFocus(void *param) 2247 { 2248 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2249 2250 RequestWindowFocusStruct *rfs = (RequestWindowFocusStruct *)param; 2251 jobject self = rfs->component; 2252 jboolean isMouseEventCause = rfs->isMouseEventCause; 2253 2254 jboolean result = JNI_FALSE; 2255 AwtWindow *window = NULL; 2256 2257 PDATA pData; 2258 JNI_CHECK_NULL_GOTO(self, "peer", ret); 2259 pData = JNI_GET_PDATA(self); 2260 if (pData == NULL) { 2261 // do nothing just return false 2262 goto ret; 2263 } 2264 2265 window = (AwtWindow *)pData; 2266 if (::IsWindow(window->GetHWnd())) { 2267 result = (jboolean)window->SendMessage(WM_AWT_WINDOW_SETACTIVE, (WPARAM)isMouseEventCause, 0); 2268 } 2269 ret: 2270 env->DeleteGlobalRef(self); 2271 2272 delete rfs; 2273 2274 return result; 2275 } 2276 2277 void AwtWindow::_ToFront(void *param) 2278 { 2279 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2280 2281 jobject self = (jobject)param; 2282 2283 AwtWindow *w = NULL; 2284 2285 PDATA pData; 2286 JNI_CHECK_PEER_GOTO(self, ret); 2287 w = (AwtWindow *)pData; 2288 if (::IsWindow(w->GetHWnd())) 2289 { 2290 UINT flags = SWP_NOMOVE|SWP_NOSIZE; 2291 BOOL focusable = w->IsFocusableWindow(); 2292 BOOL autoRequestFocus = w->IsAutoRequestFocus(); 2293 2294 if (!focusable || !autoRequestFocus) 2295 { 2296 flags = flags|SWP_NOACTIVATE; 2297 } 2298 ::SetWindowPos(w->GetHWnd(), HWND_TOP, 0, 0, 0, 0, flags); 2299 if (focusable && autoRequestFocus) 2300 { 2301 ::SetForegroundWindow(w->GetHWnd()); 2302 } 2303 } 2304 ret: 2305 env->DeleteGlobalRef(self); 2306 } 2307 2308 void AwtWindow::_ToBack(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 HWND hwnd = w->GetHWnd(); 2322 // if (AwtComponent::GetComponent(hwnd) == NULL) { 2323 // // Window was disposed. Don't bother. 2324 // return; 2325 // } 2326 2327 ::SetWindowPos(hwnd, HWND_BOTTOM, 0, 0 ,0, 0, 2328 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); 2329 2330 // If hwnd is the foreground window or if *any* of its owners are, then 2331 // we have to reset the foreground window. The reason is that when we send 2332 // hwnd to back, all of its owners are sent to back as well. If any one of 2333 // them is the foreground window, then it's possible that we could end up 2334 // with a foreground window behind a window of another application. 2335 HWND foregroundWindow = ::GetForegroundWindow(); 2336 BOOL adjustForegroundWindow; 2337 HWND toTest = hwnd; 2338 do 2339 { 2340 adjustForegroundWindow = (toTest == foregroundWindow); 2341 if (adjustForegroundWindow) 2342 { 2343 break; 2344 } 2345 toTest = ::GetWindow(toTest, GW_OWNER); 2346 } 2347 while (toTest != NULL); 2348 2349 if (adjustForegroundWindow) 2350 { 2351 HWND foregroundSearch = hwnd, newForegroundWindow = NULL; 2352 while (1) 2353 { 2354 foregroundSearch = ::GetNextWindow(foregroundSearch, GW_HWNDPREV); 2355 if (foregroundSearch == NULL) 2356 { 2357 break; 2358 } 2359 LONG style = static_cast<LONG>(::GetWindowLongPtr(foregroundSearch, GWL_STYLE)); 2360 if ((style & WS_CHILD) || !(style & WS_VISIBLE)) 2361 { 2362 continue; 2363 } 2364 2365 AwtComponent *c = AwtComponent::GetComponent(foregroundSearch); 2366 if ((c != NULL) && !::IsWindow(AwtWindow::GetModalBlocker(c->GetHWnd()))) 2367 { 2368 newForegroundWindow = foregroundSearch; 2369 } 2370 } 2371 if (newForegroundWindow != NULL) 2372 { 2373 ::SetWindowPos(newForegroundWindow, HWND_TOP, 0, 0, 0, 0, 2374 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); 2375 if (((AwtWindow*)AwtComponent::GetComponent(newForegroundWindow))->IsFocusableWindow()) 2376 { 2377 ::SetForegroundWindow(newForegroundWindow); 2378 } 2379 } 2380 else 2381 { 2382 // We *have* to set the active HWND to something new. We simply 2383 // cannot risk having an active Java HWND which is behind an HWND 2384 // of a native application. This really violates the Windows user 2385 // experience. 2386 // 2387 // Windows won't allow us to set the foreground window to NULL, 2388 // so we use the desktop window instead. To the user, it appears 2389 // that there is no foreground window system-wide. 2390 ::SetForegroundWindow(::GetDesktopWindow()); 2391 } 2392 } 2393 } 2394 ret: 2395 env->DeleteGlobalRef(self); 2396 } 2397 2398 void AwtWindow::_SetAlwaysOnTop(void *param) 2399 { 2400 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2401 2402 SetAlwaysOnTopStruct *sas = (SetAlwaysOnTopStruct *)param; 2403 jobject self = sas->window; 2404 jboolean value = sas->value; 2405 2406 AwtWindow *w = NULL; 2407 2408 PDATA pData; 2409 JNI_CHECK_PEER_GOTO(self, ret); 2410 w = (AwtWindow *)pData; 2411 if (::IsWindow(w->GetHWnd())) 2412 { 2413 w->SendMessage(WM_AWT_SETALWAYSONTOP, (WPARAM)value, (LPARAM)w); 2414 w->m_alwaysOnTop = (bool)value; 2415 } 2416 ret: 2417 env->DeleteGlobalRef(self); 2418 2419 delete sas; 2420 } 2421 2422 void AwtWindow::_SetTitle(void *param) 2423 { 2424 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2425 2426 SetTitleStruct *sts = (SetTitleStruct *)param; 2427 jobject self = sts->window; 2428 jstring title = sts->title; 2429 2430 AwtWindow *w = NULL; 2431 2432 PDATA pData; 2433 JNI_CHECK_PEER_GOTO(self, ret); 2434 JNI_CHECK_NULL_GOTO(title, "null title", ret); 2435 2436 w = (AwtWindow *)pData; 2437 if (::IsWindow(w->GetHWnd())) 2438 { 2439 int length = env->GetStringLength(title); 2440 TCHAR *buffer = new TCHAR[length + 1]; 2441 env->GetStringRegion(title, 0, length, reinterpret_cast<jchar*>(buffer)); 2442 buffer[length] = L'\0'; 2443 VERIFY(::SetWindowText(w->GetHWnd(), buffer)); 2444 delete[] buffer; 2445 } 2446 ret: 2447 env->DeleteGlobalRef(self); 2448 if (title != NULL) { 2449 env->DeleteGlobalRef(title); 2450 } 2451 2452 delete sts; 2453 } 2454 2455 void AwtWindow::_SetResizable(void *param) 2456 { 2457 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2458 2459 SetResizableStruct *srs = (SetResizableStruct *)param; 2460 jobject self = srs->window; 2461 jboolean resizable = srs->resizable; 2462 2463 AwtWindow *w = NULL; 2464 2465 PDATA pData; 2466 JNI_CHECK_PEER_GOTO(self, ret); 2467 w = (AwtWindow *)pData; 2468 if (::IsWindow(w->GetHWnd())) 2469 { 2470 DASSERT(!IsBadReadPtr(w, sizeof(AwtWindow))); 2471 w->SetResizable(resizable != 0); 2472 } 2473 ret: 2474 env->DeleteGlobalRef(self); 2475 2476 delete srs; 2477 } 2478 2479 void AwtWindow::_UpdateInsets(void *param) 2480 { 2481 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2482 2483 UpdateInsetsStruct *uis = (UpdateInsetsStruct *)param; 2484 jobject self = uis->window; 2485 jobject insets = uis->insets; 2486 2487 AwtWindow *w = NULL; 2488 2489 PDATA pData; 2490 JNI_CHECK_PEER_GOTO(self, ret); 2491 JNI_CHECK_NULL_GOTO(insets, "null insets", ret); 2492 w = (AwtWindow *)pData; 2493 if (::IsWindow(w->GetHWnd())) 2494 { 2495 w->UpdateInsets(insets); 2496 } 2497 ret: 2498 env->DeleteGlobalRef(self); 2499 env->DeleteGlobalRef(insets); 2500 2501 delete uis; 2502 } 2503 2504 void AwtWindow::_ReshapeFrame(void *param) 2505 { 2506 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2507 2508 ReshapeFrameStruct *rfs = (ReshapeFrameStruct *)param; 2509 jobject self = rfs->frame; 2510 jint x = rfs->x; 2511 jint y = rfs->y; 2512 jint w = rfs->w; 2513 jint h = rfs->h; 2514 2515 if (env->EnsureLocalCapacity(1) < 0) 2516 { 2517 env->DeleteGlobalRef(self); 2518 delete rfs; 2519 return; 2520 } 2521 2522 AwtFrame *p = NULL; 2523 2524 PDATA pData; 2525 JNI_CHECK_PEER_GOTO(self, ret); 2526 p = (AwtFrame *)pData; 2527 if (::IsWindow(p->GetHWnd())) 2528 { 2529 jobject target = env->GetObjectField(self, AwtObject::targetID); 2530 if (target != NULL) 2531 { 2532 // enforce tresholds before sending the event 2533 // Fix for 4459064 : do not enforce thresholds for embedded frames 2534 if (!p->IsEmbeddedFrame()) 2535 { 2536 jobject peer = p->GetPeer(env); 2537 int minWidth = ::GetSystemMetrics(SM_CXMIN); 2538 int minHeight = ::GetSystemMetrics(SM_CYMIN); 2539 if (w < minWidth) 2540 { 2541 env->SetIntField(target, AwtComponent::widthID, 2542 w = minWidth); 2543 env->SetIntField(peer, AwtWindow::sysWID, 2544 w); 2545 } 2546 if (h < minHeight) 2547 { 2548 env->SetIntField(target, AwtComponent::heightID, 2549 h = minHeight); 2550 env->SetIntField(peer, AwtWindow::sysHID, 2551 h); 2552 } 2553 } 2554 env->DeleteLocalRef(target); 2555 2556 RECT *r = new RECT; 2557 ::SetRect(r, x, y, x + w, y + h); 2558 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, 0, (LPARAM)r); 2559 // r is deleted in message handler 2560 2561 // After the input method window shown, the dimension & position may not 2562 // be valid until this method is called. So we need to adjust the 2563 // IME candidate window position for the same reason as commented on 2564 // awt_Frame.cpp Show() method. 2565 if (p->isInputMethodWindow() && ::IsWindowVisible(p->GetHWnd())) { 2566 p->AdjustCandidateWindowPos(); 2567 } 2568 } 2569 else 2570 { 2571 JNU_ThrowNullPointerException(env, "null target"); 2572 } 2573 } 2574 ret: 2575 env->DeleteGlobalRef(self); 2576 2577 delete rfs; 2578 } 2579 2580 void AwtWindow::_OverrideHandle(void *param) 2581 { 2582 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2583 2584 OverrideHandle* oh = (OverrideHandle *) param; 2585 jobject self = oh->frame; 2586 AwtWindow *f = NULL; 2587 2588 PDATA pData; 2589 JNI_CHECK_PEER_GOTO(self, ret); 2590 f = (AwtWindow *)pData; 2591 f->OverrideHWnd(oh->handle); 2592 ret: 2593 env->DeleteGlobalRef(self); 2594 2595 delete oh; 2596 } 2597 2598 /* 2599 * This is AwtWindow-specific function that is not intended for reusing 2600 */ 2601 HICON CreateIconFromRaster(JNIEnv* env, jintArray iconRaster, jint w, jint h) 2602 { 2603 HBITMAP mask = NULL; 2604 HBITMAP image = NULL; 2605 HICON icon = NULL; 2606 if (iconRaster != NULL) { 2607 int* iconRasterBuffer = NULL; 2608 try { 2609 iconRasterBuffer = (int *)env->GetPrimitiveArrayCritical(iconRaster, 0); 2610 2611 JNI_CHECK_NULL_GOTO(iconRasterBuffer, "iconRaster data", done); 2612 2613 mask = BitmapUtil::CreateTransparencyMaskFromARGB(w, h, iconRasterBuffer); 2614 image = BitmapUtil::CreateV4BitmapFromARGB(w, h, iconRasterBuffer); 2615 } catch (...) { 2616 if (iconRasterBuffer != NULL) { 2617 env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0); 2618 } 2619 throw; 2620 } 2621 if (iconRasterBuffer != NULL) { 2622 env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0); 2623 } 2624 } 2625 if (mask && image) { 2626 ICONINFO icnInfo; 2627 memset(&icnInfo, 0, sizeof(ICONINFO)); 2628 icnInfo.hbmMask = mask; 2629 icnInfo.hbmColor = image; 2630 icnInfo.fIcon = TRUE; 2631 icon = ::CreateIconIndirect(&icnInfo); 2632 } 2633 if (image) { 2634 destroy_BMP(image); 2635 } 2636 if (mask) { 2637 destroy_BMP(mask); 2638 } 2639 done: 2640 return icon; 2641 } 2642 2643 void AwtWindow::SetIconData(JNIEnv* env, jintArray iconRaster, jint w, jint h, 2644 jintArray smallIconRaster, jint smw, jint smh) 2645 { 2646 HICON hOldIcon = NULL; 2647 HICON hOldIconSm = NULL; 2648 //Destroy previous icon if it isn't inherited 2649 if ((m_hIcon != NULL) && !m_iconInherited) { 2650 hOldIcon = m_hIcon; 2651 } 2652 m_hIcon = NULL; 2653 if ((m_hIconSm != NULL) && !m_iconInherited) { 2654 hOldIconSm = m_hIconSm; 2655 } 2656 m_hIconSm = NULL; 2657 m_hIcon = CreateIconFromRaster(env, iconRaster, w, h); 2658 JNU_CHECK_EXCEPTION(env); 2659 m_hIconSm = CreateIconFromRaster(env, smallIconRaster, smw, smh); 2660 2661 m_iconInherited = (m_hIcon == NULL); 2662 if (m_iconInherited) { 2663 HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER); 2664 AwtWindow* owner = (AwtWindow *)AwtComponent::GetComponent(hOwner); 2665 if (owner != NULL) { 2666 m_hIcon = owner->GetHIcon(); 2667 m_hIconSm = owner->GetHIconSm(); 2668 } else { 2669 m_iconInherited = FALSE; 2670 } 2671 } 2672 DoUpdateIcon(); 2673 EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)this); 2674 if (hOldIcon != NULL) { 2675 DestroyIcon(hOldIcon); 2676 } 2677 if (hOldIconSm != NULL) { 2678 DestroyIcon(hOldIconSm); 2679 } 2680 } 2681 2682 BOOL AwtWindow::UpdateOwnedIconCallback(HWND hWndOwned, LPARAM lParam) 2683 { 2684 HWND hWndOwner = ::GetWindow(hWndOwned, GW_OWNER); 2685 AwtWindow* owner = (AwtWindow*)lParam; 2686 if (hWndOwner == owner->GetHWnd()) { 2687 AwtComponent* comp = AwtComponent::GetComponent(hWndOwned); 2688 if (comp != NULL && comp->IsTopLevel()) { 2689 AwtWindow* owned = (AwtWindow *)comp; 2690 if (owned->m_iconInherited) { 2691 owned->m_hIcon = owner->m_hIcon; 2692 owned->m_hIconSm = owner->m_hIconSm; 2693 owned->DoUpdateIcon(); 2694 EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)owned); 2695 } 2696 } 2697 } 2698 return TRUE; 2699 } 2700 2701 void AwtWindow::DoUpdateIcon() 2702 { 2703 //Does nothing for windows, is overriden for frames and dialogs 2704 } 2705 2706 void AwtWindow::RedrawWindow() 2707 { 2708 if (isOpaque()) { 2709 ::RedrawWindow(GetHWnd(), NULL, NULL, 2710 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); 2711 } else { 2712 ::EnterCriticalSection(&contentBitmapCS); 2713 if (hContentBitmap != NULL) { 2714 UpdateWindowImpl(contentWidth, contentHeight, hContentBitmap); 2715 } 2716 ::LeaveCriticalSection(&contentBitmapCS); 2717 } 2718 } 2719 2720 // Deletes the hContentBitmap if it is non-null 2721 void AwtWindow::DeleteContentBitmap() 2722 { 2723 ::EnterCriticalSection(&contentBitmapCS); 2724 if (hContentBitmap != NULL) { 2725 ::DeleteObject(hContentBitmap); 2726 hContentBitmap = NULL; 2727 } 2728 ::LeaveCriticalSection(&contentBitmapCS); 2729 } 2730 2731 // The effects are enabled only upon showing the window. 2732 // See 6780496 for details. 2733 void AwtWindow::EnableTranslucency(BOOL enable) 2734 { 2735 if (enable) { 2736 SetTranslucency(getOpacity(), isOpaque(), FALSE, TRUE); 2737 } else { 2738 SetTranslucency(0xFF, TRUE, FALSE); 2739 } 2740 } 2741 2742 /** 2743 * Sets the translucency effects. 2744 * 2745 * This method is used to: 2746 * 2747 * 1. Apply the translucency effects upon showing the window 2748 * (setValues == FALSE, useDefaultForOldValues == TRUE); 2749 * 2. Turn off the effects upon hiding the window 2750 * (setValues == FALSE, useDefaultForOldValues == FALSE); 2751 * 3. Set the effects per user's request 2752 * (setValues == TRUE, useDefaultForOldValues == FALSE); 2753 * 2754 * In case #3 the effects may or may not be applied immediately depending on 2755 * the current visibility status of the window. 2756 * 2757 * The setValues argument indicates if we need to preserve the passed values 2758 * in local fields for further use. 2759 * The useDefaultForOldValues argument indicates whether we should consider 2760 * the window as if it has not any effects applied at the moment. 2761 */ 2762 void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque, BOOL setValues, 2763 BOOL useDefaultForOldValues) 2764 { 2765 BYTE old_opacity = useDefaultForOldValues ? 0xFF : getOpacity(); 2766 BOOL old_opaque = useDefaultForOldValues ? TRUE : isOpaque(); 2767 2768 if (opacity == old_opacity && opaque == old_opaque) { 2769 return; 2770 } 2771 2772 if (setValues) { 2773 m_opacity = opacity; 2774 m_opaque = opaque; 2775 } 2776 2777 // If we're invisible and are storing the values, return 2778 // Otherwise, apply the effects immediately 2779 if (!IsVisible() && setValues) { 2780 return; 2781 } 2782 2783 HWND hwnd = GetHWnd(); 2784 2785 if (opaque != old_opaque) { 2786 DeleteContentBitmap(); 2787 } 2788 2789 if (opaque && opacity == 0xff) { 2790 // Turn off all the effects 2791 AwtWindow::SetLayered(hwnd, false); 2792 2793 // Ask the window to repaint itself and all the children 2794 RedrawWindow(); 2795 } else { 2796 // We're going to enable some effects 2797 if (!AwtWindow::IsLayered(hwnd)) { 2798 AwtWindow::SetLayered(hwnd, true); 2799 } else { 2800 if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) { 2801 // _One_ of the modes uses the SetLayeredWindowAttributes. 2802 // Need to reset the style in this case. 2803 // If both modes are simple (i.e. just changing the opacity level), 2804 // no need to reset the style. 2805 AwtWindow::SetLayered(hwnd, false); 2806 AwtWindow::SetLayered(hwnd, true); 2807 } 2808 } 2809 2810 if (opaque) { 2811 // Simple opacity mode 2812 ::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), opacity, LWA_ALPHA); 2813 } 2814 } 2815 } 2816 2817 static HBITMAP CreateBitmapFromRaster(JNIEnv* env, jintArray raster, jint w, jint h) 2818 { 2819 HBITMAP image = NULL; 2820 if (raster != NULL) { 2821 int* rasterBuffer = NULL; 2822 try { 2823 rasterBuffer = (int *)env->GetPrimitiveArrayCritical(raster, 0); 2824 JNI_CHECK_NULL_GOTO(rasterBuffer, "raster data", done); 2825 image = BitmapUtil::CreateBitmapFromARGBPre(w, h, w*4, rasterBuffer); 2826 } catch (...) { 2827 if (rasterBuffer != NULL) { 2828 env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0); 2829 } 2830 throw; 2831 } 2832 if (rasterBuffer != NULL) { 2833 env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0); 2834 } 2835 } 2836 done: 2837 return image; 2838 } 2839 2840 void AwtWindow::UpdateWindowImpl(int width, int height, HBITMAP hBitmap) 2841 { 2842 if (isOpaque()) { 2843 return; 2844 } 2845 2846 HWND hWnd = GetHWnd(); 2847 HDC hdcDst = ::GetDC(NULL); 2848 HDC hdcSrc = ::CreateCompatibleDC(NULL); 2849 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcSrc, hBitmap); 2850 2851 //XXX: this code doesn't paint the children (say, the java.awt.Button)! 2852 //So, if we ever want to support HWs here, we need to repaint them 2853 //in some other way... 2854 //::SendMessage(hWnd, WM_PRINT, (WPARAM)hdcSrc, /*PRF_CHECKVISIBLE |*/ 2855 // PRF_CHILDREN /*| PRF_CLIENT | PRF_NONCLIENT*/); 2856 2857 POINT ptSrc; 2858 ptSrc.x = ptSrc.y = 0; 2859 2860 RECT rect; 2861 POINT ptDst; 2862 SIZE size; 2863 2864 ::GetWindowRect(hWnd, &rect); 2865 ptDst.x = rect.left; 2866 ptDst.y = rect.top; 2867 size.cx = width; 2868 size.cy = height; 2869 2870 BLENDFUNCTION bf; 2871 2872 bf.SourceConstantAlpha = getOpacity(); 2873 bf.AlphaFormat = AC_SRC_ALPHA; 2874 bf.BlendOp = AC_SRC_OVER; 2875 bf.BlendFlags = 0; 2876 2877 ::UpdateLayeredWindow(hWnd, hdcDst, &ptDst, &size, hdcSrc, &ptSrc, 2878 RGB(0, 0, 0), &bf, ULW_ALPHA); 2879 2880 ::ReleaseDC(NULL, hdcDst); 2881 ::SelectObject(hdcSrc, hOldBitmap); 2882 ::DeleteDC(hdcSrc); 2883 } 2884 2885 void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height, 2886 HBITMAP hNewBitmap) 2887 { 2888 if (isOpaque()) { 2889 return; 2890 } 2891 2892 HBITMAP hBitmap; 2893 if (hNewBitmap == NULL) { 2894 if (data == NULL) { 2895 return; 2896 } 2897 hBitmap = CreateBitmapFromRaster(env, data, width, height); 2898 if (hBitmap == NULL) { 2899 return; 2900 } 2901 } else { 2902 hBitmap = hNewBitmap; 2903 } 2904 2905 ::EnterCriticalSection(&contentBitmapCS); 2906 DeleteContentBitmap(); 2907 hContentBitmap = hBitmap; 2908 contentWidth = width; 2909 contentHeight = height; 2910 UpdateWindowImpl(width, height, hBitmap); 2911 ::LeaveCriticalSection(&contentBitmapCS); 2912 } 2913 2914 /* 2915 * Fixed 6353381: it's improved fix for 4792958 2916 * which was backed-out to avoid 5059656 2917 */ 2918 BOOL AwtWindow::HasValidRect() 2919 { 2920 RECT inside; 2921 RECT outside; 2922 2923 if (::IsIconic(GetHWnd())) { 2924 return FALSE; 2925 } 2926 2927 ::GetClientRect(GetHWnd(), &inside); 2928 ::GetWindowRect(GetHWnd(), &outside); 2929 2930 BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0); 2931 BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP 2932 (outside.left == 32000 && outside.top == 32000) || // Win95 && Win98 2933 (outside.left == 3000 && outside.top == 3000)); // Win95 && Win98 2934 2935 // the bounds correspond to iconic state 2936 if (isZeroClientArea && isInvalidLocation) 2937 { 2938 return FALSE; 2939 } 2940 2941 return TRUE; 2942 } 2943 2944 2945 void AwtWindow::_SetIconImagesData(void * param) 2946 { 2947 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2948 2949 SetIconImagesDataStruct* s = (SetIconImagesDataStruct*)param; 2950 jobject self = s->window; 2951 2952 jintArray iconRaster = s->iconRaster; 2953 jintArray smallIconRaster = s->smallIconRaster; 2954 2955 AwtWindow *window = NULL; 2956 2957 PDATA pData; 2958 JNI_CHECK_PEER_GOTO(self, ret); 2959 // ok to pass null raster: default AWT icon 2960 2961 window = (AwtWindow*)pData; 2962 if (::IsWindow(window->GetHWnd())) 2963 { 2964 window->SetIconData(env, iconRaster, s->w, s->h, smallIconRaster, s->smw, s->smh); 2965 2966 } 2967 2968 ret: 2969 env->DeleteGlobalRef(self); 2970 env->DeleteGlobalRef(iconRaster); 2971 env->DeleteGlobalRef(smallIconRaster); 2972 delete s; 2973 } 2974 2975 void AwtWindow::_SetMinSize(void* param) 2976 { 2977 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2978 2979 SizeStruct *ss = (SizeStruct *)param; 2980 jobject self = ss->window; 2981 jint w = ss->w; 2982 jint h = ss->h; 2983 //Perform size setting 2984 AwtWindow *window = NULL; 2985 2986 PDATA pData; 2987 JNI_CHECK_PEER_GOTO(self, ret); 2988 window = (AwtWindow *)pData; 2989 window->m_minSize.x = w; 2990 window->m_minSize.y = h; 2991 ret: 2992 env->DeleteGlobalRef(self); 2993 delete ss; 2994 } 2995 2996 jint AwtWindow::_GetScreenImOn(void *param) 2997 { 2998 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2999 3000 jobject self = (jobject)param; 3001 3002 // It's entirely possible that our native resources have been destroyed 3003 // before our java peer - if we're dispose()d, for instance. 3004 // Alert caller w/ IllegalComponentStateException. 3005 if (self == NULL) { 3006 JNU_ThrowByName(env, "java/awt/IllegalComponentStateException", 3007 "Peer null in JNI"); 3008 return 0; 3009 } 3010 PDATA pData = JNI_GET_PDATA(self); 3011 if (pData == NULL) { 3012 JNU_ThrowByName(env, "java/awt/IllegalComponentStateException", 3013 "Native resources unavailable"); 3014 env->DeleteGlobalRef(self); 3015 return 0; 3016 } 3017 3018 jint result = 0; 3019 AwtWindow *w = (AwtWindow *)pData; 3020 if (::IsWindow(w->GetHWnd())) 3021 { 3022 result = (jint)w->GetScreenImOn(); 3023 } 3024 3025 env->DeleteGlobalRef(self); 3026 3027 return result; 3028 } 3029 3030 void AwtWindow::_SetFocusableWindow(void *param) 3031 { 3032 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3033 3034 SetFocusableWindowStruct *sfws = (SetFocusableWindowStruct *)param; 3035 jobject self = sfws->window; 3036 jboolean isFocusableWindow = sfws->isFocusableWindow; 3037 3038 AwtWindow *window = NULL; 3039 3040 PDATA pData; 3041 JNI_CHECK_PEER_GOTO(self, ret); 3042 window = (AwtWindow *)pData; 3043 3044 window->m_isFocusableWindow = isFocusableWindow; 3045 3046 // A simple window is permanently set to WS_EX_NOACTIVATE 3047 if (!window->IsSimpleWindow()) { 3048 if (!window->m_isFocusableWindow) { 3049 LONG isPopup = window->GetStyle() & WS_POPUP; 3050 window->SetStyleEx(window->GetStyleEx() | (isPopup ? 0 : WS_EX_APPWINDOW) | WS_EX_NOACTIVATE); 3051 } else { 3052 window->SetStyleEx(window->GetStyleEx() & ~WS_EX_APPWINDOW & ~WS_EX_NOACTIVATE); 3053 } 3054 } 3055 3056 ret: 3057 env->DeleteGlobalRef(self); 3058 delete sfws; 3059 } 3060 3061 void AwtWindow::_ModalDisable(void *param) 3062 { 3063 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3064 3065 ModalDisableStruct *mds = (ModalDisableStruct *)param; 3066 jobject self = mds->window; 3067 HWND blockerHWnd = (HWND)mds->blockerHWnd; 3068 3069 AwtWindow *window = NULL; 3070 HWND windowHWnd = 0; 3071 3072 JNI_CHECK_NULL_GOTO(self, "peer", ret); 3073 PDATA pData = JNI_GET_PDATA(self); 3074 if (pData == NULL) { 3075 env->DeleteGlobalRef(self); 3076 delete mds; 3077 return; 3078 } 3079 3080 window = (AwtWindow *)pData; 3081 windowHWnd = window->GetHWnd(); 3082 if (::IsWindow(windowHWnd)) { 3083 AwtWindow::SetAndActivateModalBlocker(windowHWnd, blockerHWnd); 3084 } 3085 3086 ret: 3087 env->DeleteGlobalRef(self); 3088 3089 delete mds; 3090 } 3091 3092 void AwtWindow::_ModalEnable(void *param) 3093 { 3094 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3095 3096 jobject self = (jobject)param; 3097 3098 AwtWindow *window = NULL; 3099 HWND windowHWnd = 0; 3100 3101 JNI_CHECK_NULL_GOTO(self, "peer", ret); 3102 PDATA pData = JNI_GET_PDATA(self); 3103 if (pData == NULL) { 3104 env->DeleteGlobalRef(self); 3105 return; 3106 } 3107 3108 window = (AwtWindow *)pData; 3109 windowHWnd = window->GetHWnd(); 3110 if (::IsWindow(windowHWnd)) { 3111 AwtWindow::SetModalBlocker(windowHWnd, NULL); 3112 } 3113 3114 ret: 3115 env->DeleteGlobalRef(self); 3116 } 3117 3118 void AwtWindow::_SetOpacity(void* param) 3119 { 3120 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3121 3122 OpacityStruct *os = (OpacityStruct *)param; 3123 jobject self = os->window; 3124 BYTE iOpacity = (BYTE)os->iOpacity; 3125 3126 PDATA pData; 3127 JNI_CHECK_PEER_GOTO(self, ret); 3128 AwtWindow *window = (AwtWindow *)pData; 3129 3130 window->SetTranslucency(iOpacity, window->isOpaque()); 3131 3132 ret: 3133 env->DeleteGlobalRef(self); 3134 delete os; 3135 } 3136 3137 void AwtWindow::_SetOpaque(void* param) 3138 { 3139 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3140 3141 OpaqueStruct *os = (OpaqueStruct *)param; 3142 jobject self = os->window; 3143 BOOL isOpaque = (BOOL)os->isOpaque; 3144 3145 PDATA pData; 3146 JNI_CHECK_PEER_GOTO(self, ret); 3147 AwtWindow *window = (AwtWindow *)pData; 3148 3149 window->SetTranslucency(window->getOpacity(), isOpaque); 3150 3151 ret: 3152 env->DeleteGlobalRef(self); 3153 delete os; 3154 } 3155 3156 void AwtWindow::_UpdateWindow(void* param) 3157 { 3158 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3159 3160 UpdateWindowStruct *uws = (UpdateWindowStruct *)param; 3161 jobject self = uws->window; 3162 jintArray data = uws->data; 3163 3164 PDATA pData; 3165 JNI_CHECK_PEER_GOTO(self, ret); 3166 AwtWindow *window = (AwtWindow *)pData; 3167 3168 window->UpdateWindow(env, data, (int)uws->width, (int)uws->height, 3169 uws->hBitmap); 3170 3171 ret: 3172 env->DeleteGlobalRef(self); 3173 if (data != NULL) { 3174 env->DeleteGlobalRef(data); 3175 } 3176 delete uws; 3177 } 3178 3179 void AwtWindow::_SetFullScreenExclusiveModeState(void *param) 3180 { 3181 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3182 3183 SetFullScreenExclusiveModeStateStruct * data = 3184 (SetFullScreenExclusiveModeStateStruct*)param; 3185 jobject self = data->window; 3186 jboolean state = data->isFSEMState; 3187 3188 PDATA pData; 3189 JNI_CHECK_PEER_GOTO(self, ret); 3190 AwtWindow *window = (AwtWindow *)pData; 3191 3192 window->setFullScreenExclusiveModeState(state != 0); 3193 3194 ret: 3195 env->DeleteGlobalRef(self); 3196 delete data; 3197 } 3198 3199 void AwtWindow::_GetNativeWindowSize(void* param) { 3200 3201 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3202 3203 SizeStruct *ss = (SizeStruct *)param; 3204 jobject self = ss->window; 3205 AwtWindow *window = NULL; 3206 PDATA pData; 3207 JNI_CHECK_PEER_RETURN(self); 3208 window = (AwtWindow *)pData; 3209 3210 RECT rc; 3211 ::GetWindowRect(window->GetHWnd(), &rc); 3212 ss->w = rc.right - rc.left; 3213 ss->h = rc.bottom - rc.top; 3214 3215 env->DeleteGlobalRef(self); 3216 } 3217 3218 void AwtWindow::_WindowDPIChange(void* param) 3219 { 3220 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3221 3222 ScaleStruct *ss = (ScaleStruct *)param; 3223 jobject self = ss->window; 3224 jint prevScreen = ss->prevScreen; 3225 jfloat prevScaleX = ss->prevScaleX; 3226 jfloat prevScaleY = ss->prevScaleY; 3227 jint screen = ss->screen; 3228 jfloat scaleX = ss->scaleX; 3229 jfloat scaleY = ss->scaleY; 3230 3231 PDATA pData; 3232 JNI_CHECK_PEER_GOTO(self, ret); 3233 AwtWindow *window = (AwtWindow *)pData; 3234 3235 if (window->m_winSizeMove) { 3236 if (window->prevScaleRec.screen == -1) { 3237 window->prevScaleRec.screen = prevScreen; 3238 window->prevScaleRec.scaleX = prevScaleX; 3239 window->prevScaleRec.scaleY = prevScaleY; 3240 } 3241 } 3242 else { 3243 window->WindowDPIChange(prevScreen, prevScaleX, prevScaleY, 3244 screen, scaleX, scaleY); 3245 } 3246 3247 ret: 3248 env->DeleteGlobalRef(self); 3249 delete ss; 3250 } 3251 3252 extern "C" int getSystemMetricValue(int msgType); 3253 extern "C" { 3254 3255 /* 3256 * Class: java_awt_Window 3257 * Method: initIDs 3258 * Signature: ()V 3259 */ 3260 JNIEXPORT void JNICALL 3261 Java_java_awt_Window_initIDs(JNIEnv *env, jclass cls) 3262 { 3263 TRY; 3264 3265 CHECK_NULL(AwtWindow::warningStringID = 3266 env->GetFieldID(cls, "warningString", "Ljava/lang/String;")); 3267 CHECK_NULL(AwtWindow::locationByPlatformID = 3268 env->GetFieldID(cls, "locationByPlatform", "Z")); 3269 CHECK_NULL(AwtWindow::securityWarningWidthID = 3270 env->GetFieldID(cls, "securityWarningWidth", "I")); 3271 CHECK_NULL(AwtWindow::securityWarningHeightID = 3272 env->GetFieldID(cls, "securityWarningHeight", "I")); 3273 CHECK_NULL(AwtWindow::getWarningStringMID = 3274 env->GetMethodID(cls, "getWarningString", "()Ljava/lang/String;")); 3275 CHECK_NULL(AwtWindow::autoRequestFocusID = 3276 env->GetFieldID(cls, "autoRequestFocus", "Z")); 3277 CHECK_NULL(AwtWindow::calculateSecurityWarningPositionMID = 3278 env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;")); 3279 3280 jclass windowTypeClass = env->FindClass("java/awt/Window$Type"); 3281 CHECK_NULL(windowTypeClass); 3282 AwtWindow::windowTypeNameMID = 3283 env->GetMethodID(windowTypeClass, "name", "()Ljava/lang/String;"); 3284 env->DeleteLocalRef(windowTypeClass); 3285 3286 CATCH_BAD_ALLOC; 3287 } 3288 3289 } /* extern "C" */ 3290 3291 3292 /************************************************************************ 3293 * WindowPeer native methods 3294 */ 3295 3296 extern "C" { 3297 3298 /* 3299 * Class: sun_awt_windows_WWindowPeer 3300 * Method: initIDs 3301 * Signature: ()V 3302 */ 3303 JNIEXPORT void JNICALL 3304 Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls) 3305 { 3306 TRY; 3307 3308 CHECK_NULL(AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I")); 3309 CHECK_NULL(AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I")); 3310 CHECK_NULL(AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I")); 3311 CHECK_NULL(AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I")); 3312 3313 AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType", 3314 "Ljava/awt/Window$Type;"); 3315 3316 CATCH_BAD_ALLOC; 3317 } 3318 3319 /* 3320 * Class: sun_awt_windows_WWindowPeer 3321 * Method: toFront 3322 * Signature: ()V 3323 */ 3324 JNIEXPORT void JNICALL 3325 Java_sun_awt_windows_WWindowPeer__1toFront(JNIEnv *env, jobject self) 3326 { 3327 TRY; 3328 3329 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToFront, 3330 env->NewGlobalRef(self)); 3331 // global ref is deleted in _ToFront() 3332 3333 CATCH_BAD_ALLOC; 3334 } 3335 3336 /* 3337 * Class: sun_awt_windows_WWindowPeer 3338 * Method: toBack 3339 * Signature: ()V 3340 */ 3341 JNIEXPORT void JNICALL 3342 Java_sun_awt_windows_WWindowPeer_toBack(JNIEnv *env, jobject self) 3343 { 3344 TRY; 3345 3346 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToBack, 3347 env->NewGlobalRef(self)); 3348 // global ref is deleted in _ToBack() 3349 3350 CATCH_BAD_ALLOC; 3351 } 3352 3353 /* 3354 * Class: sun_awt_windows_WWindowPeer 3355 * Method: setAlwaysOnTop 3356 * Signature: (Z)V 3357 */ 3358 JNIEXPORT void JNICALL 3359 Java_sun_awt_windows_WWindowPeer_setAlwaysOnTopNative(JNIEnv *env, jobject self, 3360 jboolean value) 3361 { 3362 TRY; 3363 3364 SetAlwaysOnTopStruct *sas = new SetAlwaysOnTopStruct; 3365 sas->window = env->NewGlobalRef(self); 3366 sas->value = value; 3367 3368 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetAlwaysOnTop, sas); 3369 // global ref and sas are deleted in _SetAlwaysOnTop 3370 3371 CATCH_BAD_ALLOC; 3372 } 3373 3374 /* 3375 * Class: sun_awt_windows_WWindowPeer 3376 * Method: _setTitle 3377 * Signature: (Ljava/lang/String;)V 3378 */ 3379 JNIEXPORT void JNICALL 3380 Java_sun_awt_windows_WWindowPeer__1setTitle(JNIEnv *env, jobject self, 3381 jstring title) 3382 { 3383 TRY; 3384 3385 SetTitleStruct *sts = new SetTitleStruct; 3386 sts->window = env->NewGlobalRef(self); 3387 sts->title = (jstring)env->NewGlobalRef(title); 3388 3389 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetTitle, sts); 3390 /// global refs and sts are deleted in _SetTitle() 3391 3392 CATCH_BAD_ALLOC; 3393 } 3394 3395 /* 3396 * Class: sun_awt_windows_WWindowPeer 3397 * Method: _setResizable 3398 * Signature: (Z)V 3399 */ 3400 JNIEXPORT void JNICALL 3401 Java_sun_awt_windows_WWindowPeer__1setResizable(JNIEnv *env, jobject self, 3402 jboolean resizable) 3403 { 3404 TRY; 3405 3406 SetResizableStruct *srs = new SetResizableStruct; 3407 srs->window = env->NewGlobalRef(self); 3408 srs->resizable = resizable; 3409 3410 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetResizable, srs); 3411 // global ref and srs are deleted in _SetResizable 3412 3413 CATCH_BAD_ALLOC; 3414 } 3415 3416 /* 3417 * Class: sun_awt_windows_WWindowPeer 3418 * Method: create 3419 * Signature: (Lsun/awt/windows/WComponentPeer;)V 3420 */ 3421 JNIEXPORT void JNICALL 3422 Java_sun_awt_windows_WWindowPeer_createAwtWindow(JNIEnv *env, jobject self, 3423 jobject parent) 3424 { 3425 TRY; 3426 3427 AwtToolkit::CreateComponent(self, parent, 3428 (AwtToolkit::ComponentFactory) 3429 AwtWindow::Create); 3430 3431 CATCH_BAD_ALLOC; 3432 } 3433 3434 /* 3435 * Class: sun_awt_windows_WWindowPeer 3436 * Method: updateInsets 3437 * Signature: (Ljava/awt/Insets;)V 3438 */ 3439 JNIEXPORT void JNICALL 3440 Java_sun_awt_windows_WWindowPeer_updateInsets(JNIEnv *env, jobject self, 3441 jobject insets) 3442 { 3443 TRY; 3444 3445 UpdateInsetsStruct *uis = new UpdateInsetsStruct; 3446 uis->window = env->NewGlobalRef(self); 3447 uis->insets = env->NewGlobalRef(insets); 3448 3449 AwtToolkit::GetInstance().SyncCall(AwtWindow::_UpdateInsets, uis); 3450 // global refs and uis are deleted in _UpdateInsets() 3451 3452 CATCH_BAD_ALLOC; 3453 } 3454 3455 /* 3456 * Class: sun_awt_windows_WWindowPeer 3457 * Method: reshapeFrame 3458 * Signature: (IIII)V 3459 */ 3460 JNIEXPORT void JNICALL 3461 Java_sun_awt_windows_WWindowPeer_reshapeFrame(JNIEnv *env, jobject self, 3462 jint x, jint y, jint w, jint h) 3463 { 3464 TRY; 3465 3466 ReshapeFrameStruct *rfs = new ReshapeFrameStruct; 3467 rfs->frame = env->NewGlobalRef(self); 3468 rfs->x = x; 3469 rfs->y = y; 3470 rfs->w = w; 3471 rfs->h = h; 3472 3473 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ReshapeFrame, rfs); 3474 // global ref and rfs are deleted in _ReshapeFrame() 3475 3476 CATCH_BAD_ALLOC; 3477 } 3478 3479 /* 3480 * Class: sun_awt_windows_WWindowPeer 3481 * Method: getNativeWindowSize 3482 * Signature: ()Ljava/awt/Dimension; 3483 */ 3484 JNIEXPORT jobject JNICALL Java_sun_awt_windows_WWindowPeer_getNativeWindowSize 3485 (JNIEnv *env, jobject self) { 3486 3487 jobject res = NULL; 3488 TRY; 3489 SizeStruct *ss = new SizeStruct; 3490 ss->window = env->NewGlobalRef(self); 3491 3492 AwtToolkit::GetInstance().SyncCall(AwtWindow::_GetNativeWindowSize, ss); 3493 3494 int w = ss->w; 3495 int h = ss->h; 3496 3497 delete ss; 3498 // global ref is deleted in _GetNativeWindowSize() 3499 3500 static jmethodID dimMID = NULL; 3501 static jclass dimClassID = NULL; 3502 if (dimClassID == NULL) { 3503 jclass dimClassIDLocal = env->FindClass("java/awt/Dimension"); 3504 CHECK_NULL_RETURN(dimClassIDLocal, NULL); 3505 dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal); 3506 env->DeleteLocalRef(dimClassIDLocal); 3507 } 3508 3509 if (dimMID == NULL) { 3510 dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V"); 3511 CHECK_NULL_RETURN(dimMID, NULL); 3512 } 3513 3514 return env->NewObject(dimClassID, dimMID, w, h); 3515 3516 CATCH_BAD_ALLOC_RET(NULL); 3517 } 3518 3519 /* 3520 * Class: sun_awt_windows_WWindowPeer 3521 * Method: getSysMinWidth 3522 * Signature: ()I 3523 */ 3524 JNIEXPORT jint JNICALL 3525 Java_sun_awt_windows_WWindowPeer_getSysMinWidth(JNIEnv *env, jclass self) 3526 { 3527 TRY; 3528 3529 return ::GetSystemMetrics(SM_CXMIN); 3530 3531 CATCH_BAD_ALLOC_RET(0); 3532 } 3533 3534 /* 3535 * Class: sun_awt_windows_WWindowPeer 3536 * Method: getSysMinHeight 3537 * Signature: ()I 3538 */ 3539 JNIEXPORT jint JNICALL 3540 Java_sun_awt_windows_WWindowPeer_getSysMinHeight(JNIEnv *env, jclass self) 3541 { 3542 TRY; 3543 3544 return ::GetSystemMetrics(SM_CYMIN); 3545 3546 CATCH_BAD_ALLOC_RET(0); 3547 } 3548 3549 /* 3550 * Class: sun_awt_windows_WWindowPeer 3551 * Method: getSysIconHeight 3552 * Signature: ()I 3553 */ 3554 JNIEXPORT jint JNICALL 3555 Java_sun_awt_windows_WWindowPeer_getSysIconHeight(JNIEnv *env, jclass self) 3556 { 3557 TRY; 3558 3559 return getSystemMetricValue(SM_CYICON); 3560 3561 CATCH_BAD_ALLOC_RET(0); 3562 } 3563 3564 /* 3565 * Class: sun_awt_windows_WWindowPeer 3566 * Method: getSysIconWidth 3567 * Signature: ()I 3568 */ 3569 JNIEXPORT jint JNICALL 3570 Java_sun_awt_windows_WWindowPeer_getSysIconWidth(JNIEnv *env, jclass self) 3571 { 3572 TRY; 3573 3574 return getSystemMetricValue(SM_CXICON); 3575 3576 CATCH_BAD_ALLOC_RET(0); 3577 } 3578 3579 /* 3580 * Class: sun_awt_windows_WWindowPeer 3581 * Method: getSysSmIconHeight 3582 * Signature: ()I 3583 */ 3584 JNIEXPORT jint JNICALL 3585 Java_sun_awt_windows_WWindowPeer_getSysSmIconHeight(JNIEnv *env, jclass self) 3586 { 3587 TRY; 3588 3589 return getSystemMetricValue(SM_CYSMICON); 3590 3591 CATCH_BAD_ALLOC_RET(0); 3592 } 3593 3594 /* 3595 * Class: sun_awt_windows_WWindowPeer 3596 * Method: getSysSmIconWidth 3597 * Signature: ()I 3598 */ 3599 JNIEXPORT jint JNICALL 3600 Java_sun_awt_windows_WWindowPeer_getSysSmIconWidth(JNIEnv *env, jclass self) 3601 { 3602 TRY; 3603 3604 return getSystemMetricValue(SM_CXSMICON); 3605 3606 CATCH_BAD_ALLOC_RET(0); 3607 } 3608 3609 int getSystemMetricValue(int msgType) { 3610 int value = 1; 3611 int logPixels = LOGPIXELSX; 3612 switch (msgType) { 3613 case SM_CXICON: 3614 value = ::GetSystemMetrics(SM_CXICON); 3615 break; 3616 case SM_CYICON: 3617 value = ::GetSystemMetrics(SM_CYICON); 3618 logPixels = LOGPIXELSY; 3619 break; 3620 case SM_CXSMICON: 3621 value = ::GetSystemMetrics(SM_CXSMICON); 3622 break; 3623 case SM_CYSMICON: 3624 value = ::GetSystemMetrics(SM_CYSMICON); 3625 logPixels = LOGPIXELSY; 3626 break; 3627 } 3628 static int dpi = -1; 3629 if (dpi == -1) { 3630 HWND hWnd = ::GetDesktopWindow(); 3631 HDC hDC = ::GetDC(hWnd); 3632 dpi = GetDeviceCaps(hDC, logPixels); 3633 ::ReleaseDC(hWnd, hDC); 3634 } 3635 if(dpi != 0 && dpi != 96) { 3636 float invScaleX = 96.0f / dpi; 3637 value = (int) ROUND_TO_INT(value * invScaleX); 3638 } 3639 return value; 3640 } 3641 3642 /* 3643 * Class: sun_awt_windows_WWindowPeer 3644 * Method: setIconImagesData 3645 * Signature: ([I)V 3646 */ 3647 JNIEXPORT void JNICALL 3648 Java_sun_awt_windows_WWindowPeer_setIconImagesData(JNIEnv *env, jobject self, 3649 jintArray iconRaster, jint w, jint h, 3650 jintArray smallIconRaster, jint smw, jint smh) 3651 { 3652 TRY; 3653 3654 SetIconImagesDataStruct *sims = new SetIconImagesDataStruct; 3655 3656 sims->window = env->NewGlobalRef(self); 3657 sims->iconRaster = (jintArray)env->NewGlobalRef(iconRaster); 3658 sims->w = w; 3659 sims->h = h; 3660 sims->smallIconRaster = (jintArray)env->NewGlobalRef(smallIconRaster); 3661 sims->smw = smw; 3662 sims->smh = smh; 3663 3664 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetIconImagesData, sims); 3665 // global refs and sims are deleted in _SetIconImagesData() 3666 3667 CATCH_BAD_ALLOC; 3668 } 3669 3670 /* 3671 * Class: sun_awt_windows_WWindowPeer 3672 * Method: setMinSize 3673 * Signature: (Lsun/awt/windows/WWindowPeer;)V 3674 */ 3675 JNIEXPORT void JNICALL 3676 Java_sun_awt_windows_WWindowPeer_setMinSize(JNIEnv *env, jobject self, 3677 jint w, jint h) 3678 { 3679 TRY; 3680 3681 SizeStruct *ss = new SizeStruct; 3682 ss->window = env->NewGlobalRef(self); 3683 ss->w = w; 3684 ss->h = h; 3685 3686 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetMinSize, ss); 3687 // global refs and mds are deleted in _SetMinSize 3688 3689 CATCH_BAD_ALLOC; 3690 } 3691 3692 /* 3693 * Class: sun_awt_windows_WWindowPeer 3694 * Method: getScreenImOn 3695 * Signature: ()I 3696 */ 3697 JNIEXPORT jint JNICALL 3698 Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self) 3699 { 3700 TRY; 3701 3702 return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall( 3703 (void *(*)(void *))AwtWindow::_GetScreenImOn, 3704 env->NewGlobalRef(self)))); 3705 // global ref is deleted in _GetScreenImOn() 3706 3707 CATCH_BAD_ALLOC_RET(-1); 3708 } 3709 3710 /* 3711 * Class: sun_awt_windows_WWindowPeer 3712 * Method: setFullScreenExclusiveModeState 3713 * Signature: (Z)V 3714 */ 3715 JNIEXPORT void JNICALL 3716 Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env, 3717 jobject self, jboolean state) 3718 { 3719 TRY; 3720 3721 SetFullScreenExclusiveModeStateStruct *data = 3722 new SetFullScreenExclusiveModeStateStruct; 3723 data->window = env->NewGlobalRef(self); 3724 data->isFSEMState = state; 3725 3726 AwtToolkit::GetInstance().SyncCall( 3727 AwtWindow::_SetFullScreenExclusiveModeState, data); 3728 // global ref and data are deleted in the invoked method 3729 3730 CATCH_BAD_ALLOC; 3731 } 3732 3733 /* 3734 * Class: sun_awt_windows_WWindowPeer 3735 * Method: modalDisable 3736 * Signature: (J)V 3737 */ 3738 JNIEXPORT void JNICALL 3739 Java_sun_awt_windows_WWindowPeer_modalDisable(JNIEnv *env, jobject self, 3740 jobject blocker, jlong blockerHWnd) 3741 { 3742 TRY; 3743 3744 ModalDisableStruct *mds = new ModalDisableStruct; 3745 mds->window = env->NewGlobalRef(self); 3746 mds->blockerHWnd = blockerHWnd; 3747 3748 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalDisable, mds); 3749 // global ref and mds are deleted in _ModalDisable 3750 3751 CATCH_BAD_ALLOC; 3752 } 3753 3754 /* 3755 * Class: sun_awt_windows_WWindowPeer 3756 * Method: modalEnable 3757 * Signature: ()V 3758 */ 3759 JNIEXPORT void JNICALL 3760 Java_sun_awt_windows_WWindowPeer_modalEnable(JNIEnv *env, jobject self, jobject blocker) 3761 { 3762 TRY; 3763 3764 AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalEnable, 3765 env->NewGlobalRef(self)); 3766 // global ref is deleted in _ModalEnable 3767 3768 CATCH_BAD_ALLOC; 3769 } 3770 3771 /* 3772 * Class: sun_awt_windows_WWindowPeer 3773 * Method: setFocusableWindow 3774 * Signature: (Z)V 3775 */ 3776 JNIEXPORT void JNICALL 3777 Java_sun_awt_windows_WWindowPeer_setFocusableWindow(JNIEnv *env, jobject self, jboolean isFocusableWindow) 3778 { 3779 TRY; 3780 3781 SetFocusableWindowStruct *sfws = new SetFocusableWindowStruct; 3782 sfws->window = env->NewGlobalRef(self); 3783 sfws->isFocusableWindow = isFocusableWindow; 3784 3785 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetFocusableWindow, sfws); 3786 // global ref and sfws are deleted in _SetFocusableWindow() 3787 3788 CATCH_BAD_ALLOC; 3789 } 3790 3791 JNIEXPORT void JNICALL 3792 Java_sun_awt_windows_WWindowPeer_nativeGrab(JNIEnv *env, jobject self) 3793 { 3794 TRY; 3795 3796 AwtToolkit::GetInstance().SyncCall(AwtWindow::_Grab, env->NewGlobalRef(self)); 3797 // global ref is deleted in _Grab() 3798 3799 CATCH_BAD_ALLOC; 3800 } 3801 3802 JNIEXPORT void JNICALL 3803 Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self) 3804 { 3805 TRY; 3806 3807 AwtToolkit::GetInstance().SyncCall(AwtWindow::_Ungrab, env->NewGlobalRef(self)); 3808 // global ref is deleted in _Ungrab() 3809 3810 CATCH_BAD_ALLOC; 3811 } 3812 3813 /* 3814 * Class: sun_awt_windows_WWindowPeer 3815 * Method: setOpacity 3816 * Signature: (I)V 3817 */ 3818 JNIEXPORT void JNICALL 3819 Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv *env, jobject self, 3820 jint iOpacity) 3821 { 3822 TRY; 3823 3824 OpacityStruct *os = new OpacityStruct; 3825 os->window = env->NewGlobalRef(self); 3826 os->iOpacity = iOpacity; 3827 3828 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os); 3829 // global refs and mds are deleted in _SetMinSize 3830 3831 CATCH_BAD_ALLOC; 3832 } 3833 3834 /* 3835 * Class: sun_awt_windows_WWindowPeer 3836 * Method: setOpaqueImpl 3837 * Signature: (Z)V 3838 */ 3839 JNIEXPORT void JNICALL 3840 Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv *env, jobject self, 3841 jboolean isOpaque) 3842 { 3843 TRY; 3844 3845 OpaqueStruct *os = new OpaqueStruct; 3846 os->window = env->NewGlobalRef(self); 3847 os->isOpaque = isOpaque; 3848 3849 AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os); 3850 // global refs and mds are deleted in _SetMinSize 3851 3852 CATCH_BAD_ALLOC; 3853 } 3854 3855 /* 3856 * Class: sun_awt_windows_WWindowPeer 3857 * Method: updateWindowImpl 3858 * Signature: ([III)V 3859 */ 3860 JNIEXPORT void JNICALL 3861 Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv *env, jobject self, 3862 jintArray data, 3863 jint width, jint height) 3864 { 3865 TRY; 3866 3867 UpdateWindowStruct *uws = new UpdateWindowStruct; 3868 uws->window = env->NewGlobalRef(self); 3869 uws->data = (jintArray)env->NewGlobalRef(data); 3870 uws->hBitmap = NULL; 3871 uws->width = width; 3872 uws->height = height; 3873 3874 AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws); 3875 // global refs and mds are deleted in _UpdateWindow 3876 3877 CATCH_BAD_ALLOC; 3878 } 3879 3880 /** 3881 * This method is called from the WGL pipeline when it needs to update 3882 * the layered window WindowPeer's C++ level object. 3883 */ 3884 void AwtWindow_UpdateWindow(JNIEnv *env, jobject peer, 3885 jint width, jint height, HBITMAP hBitmap) 3886 { 3887 TRY; 3888 3889 UpdateWindowStruct *uws = new UpdateWindowStruct; 3890 uws->window = env->NewGlobalRef(peer); 3891 uws->data = NULL; 3892 uws->hBitmap = hBitmap; 3893 uws->width = width; 3894 uws->height = height; 3895 3896 AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws); 3897 // global refs and mds are deleted in _UpdateWindow 3898 3899 CATCH_BAD_ALLOC; 3900 } 3901 3902 /* 3903 * Class: sun_awt_windows_WComponentPeer 3904 * Method: requestFocus 3905 * Signature: (Z)Z 3906 */ 3907 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WWindowPeer_requestWindowFocus 3908 (JNIEnv *env, jobject self, jboolean isMouseEventCause) 3909 { 3910 TRY; 3911 3912 jobject selfGlobalRef = env->NewGlobalRef(self); 3913 3914 RequestWindowFocusStruct *rfs = new RequestWindowFocusStruct; 3915 rfs->component = selfGlobalRef; 3916 rfs->isMouseEventCause = isMouseEventCause; 3917 3918 return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall( 3919 (void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs)); 3920 // global refs and rfs are deleted in _RequestWindowFocus 3921 3922 CATCH_BAD_ALLOC_RET(JNI_FALSE); 3923 } 3924 3925 /* 3926 * Class: sun_awt_windows_WWindowPeer 3927 * Method: repositionSecurityWarning 3928 * Signature: ()V 3929 */ 3930 JNIEXPORT void JNICALL 3931 Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env, 3932 jobject self) 3933 { 3934 TRY; 3935 3936 RepositionSecurityWarningStruct *rsws = 3937 new RepositionSecurityWarningStruct; 3938 rsws->window = env->NewGlobalRef(self); 3939 3940 AwtToolkit::GetInstance().InvokeFunction( 3941 AwtWindow::_RepositionSecurityWarning, rsws); 3942 // global refs and mds are deleted in _RepositionSecurityWarning 3943 3944 CATCH_BAD_ALLOC; 3945 } 3946 3947 /* 3948 * Class: sun_awt_windows_WWindowPeer 3949 * Method: windowDPIChange 3950 * Signature: (IFFIFF)V 3951 */ 3952 JNIEXPORT void JNICALL 3953 Java_sun_awt_windows_WWindowPeer_windowDPIChange(JNIEnv *env, jobject self, 3954 jint prevScreen, jfloat prevScaleX, jfloat prevScaleY, 3955 jint screen, jfloat scaleX, jfloat scaleY) 3956 { 3957 TRY; 3958 3959 ScaleStruct *ss = new ScaleStruct; 3960 ss->window = env->NewGlobalRef(self); 3961 ss->prevScreen = prevScreen; 3962 ss->prevScaleX = prevScaleX; 3963 ss->prevScaleY = prevScaleY; 3964 ss->screen = screen; 3965 ss->scaleX = scaleX; 3966 ss->scaleY = scaleY; 3967 3968 AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_WindowDPIChange, ss); 3969 // global refs and ss are deleted in _WindowDPIChange 3970 3971 CATCH_BAD_ALLOC; 3972 } 3973 3974 /* 3975 * Class: sun_awt_windows_WLightweightFramePeer 3976 * Method: overrideNativeHandle 3977 * Signature: (J)V 3978 */ 3979 JNIEXPORT void JNICALL Java_sun_awt_windows_WLightweightFramePeer_overrideNativeHandle 3980 (JNIEnv *env, jobject self, jlong hwnd) 3981 { 3982 TRY; 3983 3984 OverrideHandle *oh = new OverrideHandle; 3985 oh->frame = env->NewGlobalRef(self); 3986 oh->handle = (HWND) hwnd; 3987 3988 AwtToolkit::GetInstance().SyncCall(AwtFrame::_OverrideHandle, oh); 3989 // global ref and oh are deleted in _OverrideHandle() 3990 3991 CATCH_BAD_ALLOC; 3992 } 3993 3994 } /* extern "C" */