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