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