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