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