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