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