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