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