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