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