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