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