1 /* 2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "awt_Toolkit.h" 27 #include "awt_Frame.h" 28 #include "awt_MenuBar.h" 29 #include "awt_Dialog.h" 30 #include "awt_IconCursor.h" 31 #include "awt_Win32GraphicsDevice.h" 32 #include "ComCtl32Util.h" 33 34 #include <windowsx.h> 35 36 #include <java_lang_Integer.h> 37 #include <sun_awt_windows_WEmbeddedFrame.h> 38 #include <sun_awt_windows_WEmbeddedFramePeer.h> 39 40 41 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 42 */ 43 44 /***********************************************************************/ 45 // Struct for _SetState() method 46 struct SetStateStruct { 47 jobject frame; 48 jint state; 49 }; 50 // Struct for _SetMaximizedBounds() method 51 struct SetMaximizedBoundsStruct { 52 jobject frame; 53 jint x, y; 54 jint width, height; 55 }; 56 // Struct for _SetMenuBar() method 57 struct SetMenuBarStruct { 58 jobject frame; 59 jobject menubar; 60 }; 61 62 // Struct for _SetIMMOption() method 63 struct SetIMMOptionStruct { 64 jobject frame; 65 jstring option; 66 }; 67 // Struct for _SynthesizeWmActivate() method 68 struct SynthesizeWmActivateStruct { 69 jobject frame; 70 jboolean doActivate; 71 }; 72 // Struct for _NotifyModalBlocked() method 73 struct NotifyModalBlockedStruct { 74 jobject frame; 75 jobject peer; 76 jobject blockerPeer; 77 jboolean blocked; 78 }; 79 // Information about thread containing modal blocked embedded frames 80 struct BlockedThreadStruct { 81 int framesCount; 82 HHOOK mouseHook; 83 HHOOK modalHook; 84 }; 85 86 87 // Communication with plugin control 88 89 // The value must be the same as in AxControl.h 90 #define WM_AX_REQUEST_FOCUS_TO_EMBEDDER (WM_USER + 197) 91 92 static bool SetFocusToPluginControl(HWND hwndPlugin); 93 94 /************************************************************************ 95 * AwtFrame fields 96 */ 97 98 jfieldID AwtFrame::handleID; 99 100 jfieldID AwtFrame::undecoratedID; 101 jmethodID AwtFrame::getExtendedStateMID; 102 jmethodID AwtFrame::setExtendedStateMID; 103 104 jmethodID AwtFrame::activateEmbeddingTopLevelMID; 105 jfieldID AwtFrame::isEmbeddedInIEID; 106 107 Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads"); 108 109 /************************************************************************ 110 * AwtFrame methods 111 */ 112 113 AwtFrame::AwtFrame() { 114 m_parentWnd = NULL; 115 menuBar = NULL; 116 m_isEmbedded = FALSE; 117 m_isEmbeddedInIE = FALSE; 118 m_isLightweight = FALSE; 119 m_ignoreWmSize = FALSE; 120 m_isMenuDropped = FALSE; 121 m_isInputMethodWindow = FALSE; 122 m_isUndecorated = FALSE; 123 m_imeTargetComponent = NULL; 124 m_actualFocusedWindow = NULL; 125 m_iconic = FALSE; 126 m_zoomed = FALSE; 127 m_maxBoundsSet = FALSE; 128 m_forceResetZoomed = FALSE; 129 130 isInManualMoveOrSize = FALSE; 131 grabbedHitTest = 0; 132 } 133 134 AwtFrame::~AwtFrame() 135 { 136 } 137 138 void AwtFrame::Dispose() 139 { 140 AwtWindow::Dispose(); 141 } 142 143 LPCTSTR AwtFrame::GetClassName() { 144 return AWT_FRAME_WINDOW_CLASS_NAME; 145 } 146 147 /* 148 * Create a new AwtFrame object and window. 149 */ 150 AwtFrame* AwtFrame::Create(jobject self, jobject parent) 151 { 152 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 153 if (env->EnsureLocalCapacity(1) < 0) { 154 return NULL; 155 } 156 157 PDATA pData; 158 HWND hwndParent = NULL; 159 AwtFrame* frame; 160 jclass cls = NULL; 161 jclass inputMethodWindowCls = NULL; 162 jobject target = NULL; 163 164 try { 165 target = env->GetObjectField(self, AwtObject::targetID); 166 JNI_CHECK_NULL_GOTO(target, "target", done); 167 168 if (parent != NULL) { 169 JNI_CHECK_PEER_GOTO(parent, done); 170 { 171 AwtFrame* parent = (AwtFrame *)pData; 172 hwndParent = parent->GetHWnd(); 173 } 174 } 175 176 frame = new AwtFrame(); 177 178 { 179 /* 180 * A variation on Netscape's hack for embedded frames: the client 181 * area of the browser is a Java Frame for parenting purposes, but 182 * really a Windows child window 183 */ 184 BOOL isEmbeddedInstance = FALSE; 185 BOOL isEmbedded = FALSE; 186 cls = env->FindClass("sun/awt/EmbeddedFrame"); 187 188 if (cls) { 189 isEmbeddedInstance = env->IsInstanceOf(target, cls); 190 } else { 191 throw std::bad_alloc(); 192 } 193 INT_PTR handle; 194 if (isEmbeddedInstance) { 195 handle = static_cast<INT_PTR>(env->GetLongField(target, AwtFrame::handleID)); 196 if (handle != 0) { 197 isEmbedded = TRUE; 198 } 199 } 200 frame->m_isEmbedded = isEmbedded; 201 202 BOOL isLightweight = FALSE; 203 cls = env->FindClass("sun/awt/LightweightFrame"); 204 if (cls) { 205 isLightweight = env->IsInstanceOf(target, cls); 206 } else { 207 throw std::bad_alloc(); 208 } 209 frame->m_isLightweight = isLightweight; 210 211 if (isEmbedded) { 212 hwndParent = (HWND)handle; 213 214 // JDK-8056915: Handle focus communication between plugin and frame 215 frame->m_isEmbeddedInIE = IsEmbeddedInIE(hwndParent); 216 if (frame->m_isEmbeddedInIE) { 217 env->SetBooleanField(target, isEmbeddedInIEID, JNI_TRUE); 218 } 219 220 RECT rect; 221 ::GetClientRect(hwndParent, &rect); 222 //Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6 223 frame->m_isUndecorated = true; 224 /* 225 * Fix for BugTraq ID 4337754. 226 * Initialize m_peerObject before the first call 227 * to AwtFrame::GetClassName(). 228 */ 229 frame->m_peerObject = env->NewGlobalRef(self); 230 frame->RegisterClass(); 231 DWORD exStyle = WS_EX_NOPARENTNOTIFY; 232 233 if (GetRTL()) { 234 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; 235 if (GetRTLReadingOrder()) 236 exStyle |= WS_EX_RTLREADING; 237 } 238 239 frame->m_hwnd = ::CreateWindowEx(exStyle, 240 frame->GetClassName(), TEXT(""), 241 WS_CHILD | WS_CLIPCHILDREN, 242 0, 0, 243 rect.right, rect.bottom, 244 hwndParent, NULL, 245 AwtToolkit::GetInstance().GetModuleHandle(), 246 NULL); 247 frame->LinkObjects(env, self); 248 frame->SubclassHWND(); 249 250 // Update target's dimensions to reflect this embedded window. 251 ::GetClientRect(frame->m_hwnd, &rect); 252 ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2); 253 254 env->SetIntField(target, AwtComponent::xID, rect.left); 255 env->SetIntField(target, AwtComponent::yID, rect.top); 256 env->SetIntField(target, AwtComponent::widthID, 257 rect.right-rect.left); 258 env->SetIntField(target, AwtComponent::heightID, 259 rect.bottom-rect.top); 260 frame->InitPeerGraphicsConfig(env, self); 261 AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent); 262 } else if (isLightweight) { 263 frame->m_isUndecorated = true; 264 frame->m_peerObject = env->NewGlobalRef(self); 265 frame->RegisterClass(); 266 267 DWORD exStyle = 0; 268 DWORD style = WS_POPUP; 269 270 frame->CreateHWnd(env, L"", 271 style, 272 exStyle, 273 0, 0, 0, 0, 274 0, 275 NULL, 276 ::GetSysColor(COLOR_WINDOWTEXT), 277 ::GetSysColor(COLOR_WINDOWFRAME), 278 self); 279 } else { 280 jint state = env->CallIntMethod(self, AwtFrame::getExtendedStateMID); 281 DWORD exStyle; 282 DWORD style; 283 284 // for input method windows, use minimal decorations 285 inputMethodWindowCls = env->FindClass("sun/awt/im/InputMethodWindow"); 286 if (inputMethodWindowCls == NULL) { 287 throw std::bad_alloc(); 288 } 289 290 if (env->IsInstanceOf(target, inputMethodWindowCls)) { 291 //for below-the-spot composition window, use no decoration 292 if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE){ 293 exStyle = 0; 294 style = WS_POPUP|WS_CLIPCHILDREN; 295 frame->m_isUndecorated = TRUE; 296 } else { 297 exStyle = WS_EX_PALETTEWINDOW; 298 style = WS_CLIPCHILDREN; 299 } 300 frame->m_isInputMethodWindow = TRUE; 301 } else if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE) { 302 exStyle = 0; 303 style = WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | 304 WS_MAXIMIZEBOX | WS_MINIMIZEBOX; 305 if (state & java_awt_Frame_ICONIFIED) { 306 frame->setIconic(TRUE); 307 } 308 frame->m_isUndecorated = TRUE; 309 } else { 310 exStyle = WS_EX_WINDOWEDGE; 311 style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; 312 if (state & java_awt_Frame_ICONIFIED) { 313 frame->setIconic(TRUE); 314 } 315 } 316 317 if (GetRTL()) { 318 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; 319 if (GetRTLReadingOrder()) 320 exStyle |= WS_EX_RTLREADING; 321 } 322 323 jint x = env->GetIntField(target, AwtComponent::xID); 324 jint y = env->GetIntField(target, AwtComponent::yID); 325 jint width = env->GetIntField(target, AwtComponent::widthID); 326 jint height = env->GetIntField(target, AwtComponent::heightID); 327 328 frame->CreateHWnd(env, L"", 329 style, 330 exStyle, 331 0, 0, 0, 0, 332 hwndParent, 333 NULL, 334 ::GetSysColor(COLOR_WINDOWTEXT), 335 ::GetSysColor(COLOR_WINDOWFRAME), 336 self); 337 /* 338 * Reshape here instead of during create, so that a 339 * WM_NCCALCSIZE is sent. 340 */ 341 frame->Reshape(x, y, width, height); 342 } 343 } 344 } catch (...) { 345 env->DeleteLocalRef(target); 346 env->DeleteLocalRef(cls); 347 env->DeleteLocalRef(inputMethodWindowCls); 348 throw; 349 } 350 351 done: 352 env->DeleteLocalRef(target); 353 env->DeleteLocalRef(cls); 354 env->DeleteLocalRef(inputMethodWindowCls); 355 356 return frame; 357 } 358 359 /* 360 * Returns true if the frame is embedded into Internet Explorer. 361 * The function checks the class name of the parent window of the embedded frame. 362 */ 363 BOOL AwtFrame::IsEmbeddedInIE(HWND hwndParent) 364 { 365 const char *pluginClass = "Java Plug-in Control Window"; 366 #define PARENT_CLASS_BUFFER_SIZE 64 367 char parentClass[PARENT_CLASS_BUFFER_SIZE]; 368 369 return (::GetClassNameA(hwndParent, parentClass, PARENT_CLASS_BUFFER_SIZE) > 0) 370 && (strncmp(parentClass, pluginClass, PARENT_CLASS_BUFFER_SIZE) == 0); 371 } 372 373 374 LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr) 375 { 376 LRESULT retValue = 0L; 377 378 AwtComponent *focusOwner = NULL; 379 AwtComponent *imeTargetComponent = NULL; 380 381 // IME and input language related messages need to be sent to a window 382 // which has the Java input focus 383 switch (message) { 384 case WM_IME_STARTCOMPOSITION: 385 case WM_IME_ENDCOMPOSITION: 386 case WM_IME_COMPOSITION: 387 case WM_IME_SETCONTEXT: 388 case WM_IME_NOTIFY: 389 case WM_IME_CONTROL: 390 case WM_IME_COMPOSITIONFULL: 391 case WM_IME_SELECT: 392 case WM_IME_CHAR: 393 case WM_IME_REQUEST: 394 case WM_IME_KEYDOWN: 395 case WM_IME_KEYUP: 396 case WM_INPUTLANGCHANGEREQUEST: 397 case WM_INPUTLANGCHANGE: 398 if (message == WM_IME_STARTCOMPOSITION) { 399 SetImeTargetComponent(sm_focusOwner); 400 } 401 imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent()); 402 if (imeTargetComponent != NULL && 403 imeTargetComponent != this) // avoid recursive calls 404 { 405 retValue = imeTargetComponent->WindowProc(message, wParam, lParam); 406 mr = mrConsume; 407 } 408 if (message == WM_IME_ENDCOMPOSITION) { 409 SetImeTargetComponent(NULL); 410 } 411 break; 412 case WM_SETFOCUS: 413 if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain 414 415 if (!sm_suppressFocusAndActivation) { 416 if (IsLightweightFrame() || IsEmbeddedFrame()) { 417 AwtSetActiveWindow(); 418 } 419 } 420 mr = mrConsume; 421 break; 422 case WM_KILLFOCUS: 423 if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain 424 425 if (!sm_suppressFocusAndActivation) { 426 if (IsLightweightFrame() || IsEmbeddedFrame()) { 427 HWND oppositeToplevelHWnd = AwtComponent::GetTopLevelParentForWindow((HWND)wParam); 428 if (oppositeToplevelHWnd != AwtComponent::GetFocusedWindow()) { 429 AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL); 430 } 431 } 432 } else if (sm_restoreFocusAndActivation) { 433 if (AwtComponent::GetFocusedWindow() != NULL) { 434 AwtWindow *focusedWindow = (AwtWindow*)GetComponent(AwtComponent::GetFocusedWindow()); 435 if (focusedWindow != NULL) { 436 // Will just silently restore native focus & activation. 437 focusedWindow->AwtSetActiveWindow(); 438 } 439 } 440 } 441 mr = mrConsume; 442 break; 443 case 0x0127: // WM_CHANGEUISTATE 444 case 0x0128: // WM_UPDATEUISTATE 445 mr = mrConsume; 446 break; 447 } 448 449 return retValue; 450 } 451 452 LRESULT AwtFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 453 { 454 MsgRouting mr = mrDoDefault; 455 LRESULT retValue = 0L; 456 457 retValue = ProxyWindowProc(message, wParam, lParam, mr); 458 459 if (mr != mrConsume) { 460 retValue = AwtWindow::WindowProc(message, wParam, lParam); 461 } 462 return retValue; 463 } 464 465 MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status) 466 { 467 /* 468 * Fix for 6492970. 469 * When a non-focusable toplevel is shown alone the Java process 470 * is not foreground. If one shows another (focusable) toplevel 471 * the native platform not always makes it foreground (see the CR). 472 * Even worse, sometimes it sends the newly shown toplevel WM_ACTIVATE 473 * message. This breaks Java focus. To workaround the problem we 474 * set the toplevel being shown foreground programmatically. 475 * The fix is localized to non-foreground process case only. 476 * (See also: 6599270) 477 */ 478 if (!IsEmbeddedFrame() && show == TRUE && status == 0) { 479 HWND fgHWnd = ::GetForegroundWindow(); 480 if (fgHWnd != NULL) { 481 DWORD fgProcessID; 482 ::GetWindowThreadProcessId(fgHWnd, &fgProcessID); 483 484 if (fgProcessID != ::GetCurrentProcessId()) { 485 AwtWindow* window = (AwtWindow*)GetComponent(GetHWnd()); 486 487 if (window != NULL && window->IsFocusableWindow() && window->IsAutoRequestFocus() && 488 !::IsWindow(GetModalBlocker(GetHWnd()))) 489 { 490 // When the Java process is not allowed to set the foreground window 491 // (see MSDN) the request below will just have no effect. 492 ::SetForegroundWindow(GetHWnd()); 493 } 494 } 495 } 496 } 497 return AwtWindow::WmShowWindow(show, status); 498 } 499 500 MsgRouting AwtFrame::WmMouseUp(UINT flags, int x, int y, int button) { 501 if (isInManualMoveOrSize) { 502 isInManualMoveOrSize = FALSE; 503 ::ReleaseCapture(); 504 return mrConsume; 505 } 506 return AwtWindow::WmMouseUp(flags, x, y, button); 507 } 508 509 MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) { 510 /** 511 * If this Frame is non-focusable then we should implement move and size operation for it by 512 * ourselfves because we don't dispatch appropriate mouse messages to default window procedure. 513 */ 514 if (!IsFocusableWindow() && isInManualMoveOrSize) { 515 DWORD curPos = ::GetMessagePos(); 516 x = GET_X_LPARAM(curPos); 517 y = GET_Y_LPARAM(curPos); 518 RECT r; 519 ::GetWindowRect(GetHWnd(), &r); 520 POINT mouseLoc = {x, y}; 521 mouseLoc.x -= savedMousePos.x; 522 mouseLoc.y -= savedMousePos.y; 523 savedMousePos.x = x; 524 savedMousePos.y = y; 525 if (grabbedHitTest == HTCAPTION) { 526 ::SetWindowPos(GetHWnd(), NULL, r.left+mouseLoc.x, r.top+mouseLoc.y, 527 r.right-r.left, r.bottom-r.top, 528 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); 529 } else { 530 switch (grabbedHitTest) { 531 case HTTOP: 532 r.top += mouseLoc.y; 533 break; 534 case HTBOTTOM: 535 r.bottom += mouseLoc.y; 536 break; 537 case HTRIGHT: 538 r.right += mouseLoc.x; 539 break; 540 case HTLEFT: 541 r.left += mouseLoc.x; 542 break; 543 case HTTOPLEFT: 544 r.left += mouseLoc.x; 545 r.top += mouseLoc.y; 546 break; 547 case HTTOPRIGHT: 548 r.top += mouseLoc.y; 549 r.right += mouseLoc.x; 550 break; 551 case HTBOTTOMLEFT: 552 r.left += mouseLoc.x; 553 r.bottom += mouseLoc.y; 554 break; 555 case HTBOTTOMRIGHT: 556 case HTSIZE: 557 r.right += mouseLoc.x; 558 r.bottom += mouseLoc.y; 559 break; 560 } 561 562 ::SetWindowPos(GetHWnd(), NULL, r.left, r.top, 563 r.right-r.left, r.bottom-r.top, 564 SWP_NOACTIVATE | SWP_NOZORDER | 565 SWP_NOCOPYBITS | SWP_DEFERERASE); 566 } 567 return mrConsume; 568 } else { 569 return AwtWindow::WmMouseMove(flags, x, y); 570 } 571 } 572 573 MsgRouting AwtFrame::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) { 574 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { 575 /* 576 * Fix for 6399659. 577 * The native system shouldn't activate the next window in z-order 578 * when minimizing non-focusable window. 579 */ 580 if (hitTest == HTMINBUTTON) { 581 ::ShowWindow(GetHWnd(), SW_SHOWMINNOACTIVE); 582 return mrConsume; 583 } 584 /** 585 * If this Frame is non-focusable then we should implement move and size operation for it by 586 * ourselfves because we don't dispatch appropriate mouse messages to default window procedure. 587 */ 588 if ((button & DBL_CLICK) && hitTest == HTCAPTION) { 589 // Double click on caption - maximize or restore Frame. 590 if (IsResizable()) { 591 if (::IsZoomed(GetHWnd())) { 592 ::ShowWindow(GetHWnd(), SW_SHOWNOACTIVATE); 593 } else { 594 ::ShowWindow(GetHWnd(), SW_MAXIMIZE); 595 } 596 } 597 return mrConsume; 598 } 599 switch (hitTest) { 600 case HTMAXBUTTON: 601 if (IsResizable()) { 602 if (::IsZoomed(GetHWnd())) { 603 ::ShowWindow(GetHWnd(), SW_SHOWNOACTIVATE); 604 } else { 605 ::ShowWindow(GetHWnd(), SW_MAXIMIZE); 606 } 607 } 608 return mrConsume; 609 default: 610 return mrDoDefault; 611 } 612 } 613 return AwtWindow::WmNcMouseUp(hitTest, x, y, button); 614 } 615 616 MsgRouting AwtFrame::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 617 // By Swing request, click on the Frame's decorations (even on 618 // grabbed Frame) should generate UngrabEvent 619 if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) { 620 m_grabbedWindow->Ungrab(); 621 } 622 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { 623 switch (hitTest) { 624 case HTTOP: 625 case HTBOTTOM: 626 case HTLEFT: 627 case HTRIGHT: 628 case HTTOPLEFT: 629 case HTTOPRIGHT: 630 case HTBOTTOMLEFT: 631 case HTBOTTOMRIGHT: 632 case HTSIZE: 633 // Zoomed or non-resizable unfocusable frames should not be resizable. 634 if (isZoomed() || !IsResizable()) { 635 return mrConsume; 636 } 637 case HTCAPTION: 638 // We are going to perform default mouse action on non-client area of this window 639 // Grab mouse for this purpose and store coordinates for motion vector calculation 640 savedMousePos.x = x; 641 savedMousePos.y = y; 642 ::SetCapture(GetHWnd()); 643 isInManualMoveOrSize = TRUE; 644 grabbedHitTest = hitTest; 645 return mrConsume; 646 default: 647 return mrDoDefault; 648 } 649 } 650 return AwtWindow::WmNcMouseDown(hitTest, x, y, button); 651 } 652 653 // Override AwtWindow::Reshape() to handle minimized/maximized 654 // frames (see 6525850, 4065534) 655 void AwtFrame::Reshape(int x, int y, int width, int height) 656 { 657 if (isIconic()) { 658 // normal AwtComponent::Reshape will not work for iconified windows so... 659 WINDOWPLACEMENT wp; 660 POINT ptMinPosition = {x,y}; 661 POINT ptMaxPosition = {0,0}; 662 RECT rcNormalPosition = {x,y,x+width,y+height}; 663 RECT rcWorkspace; 664 HWND hWndDesktop = GetDesktopWindow(); 665 HWND hWndSelf = GetHWnd(); 666 667 // SetWindowPlacement takes workspace coordinates, but 668 // if taskbar is at top of screen, workspace coords != 669 // screen coords, so offset by workspace origin 670 VERIFY(::SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&rcWorkspace, 0)); 671 ::OffsetRect(&rcNormalPosition, -rcWorkspace.left, -rcWorkspace.top); 672 673 // set the window size for when it is not-iconified 674 wp.length = sizeof(wp); 675 wp.flags = WPF_SETMINPOSITION; 676 wp.showCmd = IsVisible() ? SW_SHOWMINIMIZED : SW_HIDE; 677 wp.ptMinPosition = ptMinPosition; 678 wp.ptMaxPosition = ptMaxPosition; 679 wp.rcNormalPosition = rcNormalPosition; 680 681 // If the call is not guarded with ignoreWmSize, 682 // a regression for bug 4851435 appears. 683 // Having this call guarded also prevents 684 // changing the iconified state of the frame 685 // while calling the Frame.setBounds() method. 686 m_ignoreWmSize = TRUE; 687 ::SetWindowPlacement(hWndSelf, &wp); 688 m_ignoreWmSize = FALSE; 689 690 return; 691 } 692 693 if (isZoomed()) { 694 // setting size of maximized window, we remove the 695 // maximized state bit (matches Motif behaviour) 696 // (calling ShowWindow(SW_RESTORE) would fire an 697 // activation event which we don't want) 698 LONG style = GetStyle(); 699 DASSERT(style & WS_MAXIMIZE); 700 style ^= WS_MAXIMIZE; 701 SetStyle(style); 702 } 703 704 AwtWindow::Reshape(x, y, width, height); 705 } 706 707 708 /* Show the frame in it's current state */ 709 void 710 AwtFrame::Show() 711 { 712 m_visible = true; 713 HWND hwnd = GetHWnd(); 714 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 715 716 if (IsLightweightFrame()) { 717 return; 718 } 719 720 DTRACE_PRINTLN3("AwtFrame::Show:%s%s%s", 721 m_iconic ? " iconic" : "", 722 m_zoomed ? " zoomed" : "", 723 m_iconic || m_zoomed ? "" : " normal"); 724 725 BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID); 726 727 if (locationByPlatform) { 728 moveToDefaultLocation(); 729 } 730 EnableTranslucency(TRUE); 731 732 BOOL autoRequestFocus = IsAutoRequestFocus(); 733 734 if (m_iconic) { 735 if (m_zoomed) { 736 // This whole function could probably be rewritten to use 737 // ::SetWindowPlacement but MS docs doesn't tell if 738 // ::SetWindowPlacement is a proper superset of 739 // ::ShowWindow. So let's be conservative and only use it 740 // here, where we really do need it. 741 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED"); 742 WINDOWPLACEMENT wp; 743 ::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT)); 744 wp.length = sizeof(WINDOWPLACEMENT); 745 ::GetWindowPlacement(hwnd, &wp); 746 if (!IsFocusableWindow() || !autoRequestFocus) { 747 wp.showCmd = SW_SHOWMINNOACTIVE; 748 } else { 749 wp.showCmd = SW_SHOWMINIMIZED; 750 } 751 wp.flags |= WPF_RESTORETOMAXIMIZED; 752 ::SetWindowPlacement(hwnd, &wp); 753 } 754 else { 755 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED)"); 756 if (!IsFocusableWindow() || !autoRequestFocus) { 757 ::ShowWindow(hwnd, SW_SHOWMINNOACTIVE); 758 } else { 759 ::ShowWindow(hwnd, SW_SHOWMINIMIZED); 760 } 761 } 762 } 763 else if (m_zoomed) { 764 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMAXIMIZED)"); 765 if (!autoRequestFocus) { 766 767 m_filterFocusAndActivation = TRUE; 768 ::ShowWindow(hwnd, SW_MAXIMIZE); 769 m_filterFocusAndActivation = FALSE; 770 771 } else if (!IsFocusableWindow()) { 772 ::ShowWindow(hwnd, SW_MAXIMIZE); 773 } else { 774 ::ShowWindow(hwnd, SW_SHOWMAXIMIZED); 775 } 776 } 777 else if (m_isInputMethodWindow) { 778 // Don't activate input methow window 779 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWNA)"); 780 ::ShowWindow(hwnd, SW_SHOWNA); 781 782 // After the input method window shown, we have to adjust the 783 // IME candidate window position. Here is why. 784 // Usually, when IMM opens the candidate window, it sends WM_IME_NOTIFY w/ 785 // IMN_OPENCANDIDATE message to the awt component window. The 786 // awt component makes a Java call to acquire the text position 787 // in order to show the candidate window just below the input method window. 788 // However, by the time it acquires the position, the input method window 789 // hasn't been displayed yet, the position returned is just below 790 // the composed text and when the input method window is shown, it 791 // will hide part of the candidate list. To fix this, we have to 792 // adjust the candidate window position after the input method window 793 // is shown. See bug 5012944. 794 AdjustCandidateWindowPos(); 795 } 796 else { 797 // Nor iconic, nor zoomed (handled above) - so use SW_RESTORE 798 // to show in "normal" state regardless of whatever stale 799 // state might the invisible window still has. 800 DTRACE_PRINTLN("AwtFrame::Show(SW_RESTORE)"); 801 if (!IsFocusableWindow() || !autoRequestFocus) { 802 ::ShowWindow(hwnd, SW_SHOWNOACTIVATE); 803 } else { 804 ::ShowWindow(hwnd, SW_RESTORE); 805 } 806 } 807 } 808 809 void 810 AwtFrame::SendWindowStateEvent(int oldState, int newState) 811 { 812 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_STATE_CHANGED, 813 NULL, oldState, newState); 814 } 815 816 void 817 AwtFrame::ClearMaximizedBounds() 818 { 819 m_maxBoundsSet = FALSE; 820 } 821 822 void AwtFrame::AdjustCandidateWindowPos() 823 { 824 // This method should only be called if the current frame 825 // is the input method window frame. 826 if (!m_isInputMethodWindow) { 827 return; 828 } 829 830 RECT inputWinRec, focusWinRec; 831 AwtComponent *comp = AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 832 if (comp == NULL) { 833 return; 834 } 835 836 ::GetWindowRect(GetHWnd(), &inputWinRec); 837 ::GetWindowRect(sm_focusOwner, &focusWinRec); 838 839 LPARAM candType = comp->GetCandidateType(); 840 HWND defaultIMEWnd = ::ImmGetDefaultIMEWnd(GetHWnd()); 841 if (defaultIMEWnd == NULL) { 842 return; 843 } 844 UINT bits = 1; 845 // adjusts the candidate window position 846 for (int iCandType = 0; iCandType < 32; iCandType++, bits<<=1) { 847 if (candType & bits) { 848 CANDIDATEFORM cf; 849 cf.dwIndex = iCandType; 850 cf.dwStyle = CFS_CANDIDATEPOS; 851 // Since the coordinates are relative to the containing window, 852 // we have to calculate the coordinates as below. 853 cf.ptCurrentPos.x = inputWinRec.left - focusWinRec.left; 854 cf.ptCurrentPos.y = inputWinRec.bottom - focusWinRec.top; 855 856 // sends IMC_SETCANDIDATEPOS to IMM to move the candidate window. 857 ::SendMessage(defaultIMEWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, (LPARAM)&cf); 858 } 859 } 860 } 861 862 void 863 AwtFrame::SetMaximizedBounds(int x, int y, int w, int h) 864 { 865 m_maxPos.x = x; 866 m_maxPos.y = y; 867 m_maxSize.x = w; 868 m_maxSize.y = h; 869 m_maxBoundsSet = TRUE; 870 } 871 872 MsgRouting AwtFrame::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 873 { 874 //Firstly call AwtWindow's function 875 MsgRouting r = AwtWindow::WmGetMinMaxInfo(lpmmi); 876 877 //Then replace maxPos & maxSize if necessary 878 if (!m_maxBoundsSet) { 879 return r; 880 } 881 882 if (m_maxPos.x != java_lang_Integer_MAX_VALUE) 883 lpmmi->ptMaxPosition.x = m_maxPos.x; 884 if (m_maxPos.y != java_lang_Integer_MAX_VALUE) 885 lpmmi->ptMaxPosition.y = m_maxPos.y; 886 if (m_maxSize.x != java_lang_Integer_MAX_VALUE) 887 lpmmi->ptMaxSize.x = m_maxSize.x; 888 if (m_maxSize.y != java_lang_Integer_MAX_VALUE) 889 lpmmi->ptMaxSize.y = m_maxSize.y; 890 return mrConsume; 891 } 892 893 MsgRouting AwtFrame::WmSize(UINT type, int w, int h) 894 { 895 currentWmSizeState = type; 896 if (currentWmSizeState == SIZE_MINIMIZED) { 897 UpdateSecurityWarningVisibility(); 898 } 899 900 if (m_ignoreWmSize) { 901 return mrDoDefault; 902 } 903 904 DTRACE_PRINTLN6("AwtFrame::WmSize: %dx%d,%s visible, state%s%s%s", 905 w, h, 906 ::IsWindowVisible(GetHWnd()) ? "" : " not", 907 m_iconic ? " iconic" : "", 908 m_zoomed ? " zoomed" : "", 909 m_iconic || m_zoomed ? "" : " normal"); 910 911 BOOL iconify = type == SIZE_MINIMIZED; 912 913 // Note that zoom may be set to TRUE in several cases: 914 // 1. type == SIZE_MAXIMIZED means that either the user or 915 // the developer (via setExtendedState(MAXIMIZED_BOTH) 916 // maximizes the frame. 917 // 2. type == SIZE_MINIMIZED && isZoomed() means that a maximized 918 // frame is to be minimized. If the user minimizes a maximized 919 // frame, we need to keep the zoomed property TRUE. However, 920 // if the developer calls setExtendedState(ICONIFIED), i.e. 921 // w/o combining the ICONIFIED state with the MAXIMIZED state, 922 // we MUST RESET the zoomed property. 923 // The flag m_forceResetZoomed identifies the latter case. 924 BOOL zoom = 925 ( 926 type == SIZE_MAXIMIZED 927 || 928 (type == SIZE_MINIMIZED && isZoomed()) 929 ) 930 && !m_forceResetZoomed; 931 932 // Set the new state and send appropriate Java event 933 jint oldState = java_awt_Frame_NORMAL; 934 if (isIconic()) { 935 oldState |= java_awt_Frame_ICONIFIED; 936 } 937 if (isZoomed()) { 938 oldState |= java_awt_Frame_MAXIMIZED_BOTH; 939 } 940 941 jint newState = java_awt_Frame_NORMAL; 942 if (iconify) { 943 newState |= java_awt_Frame_ICONIFIED; 944 } 945 if (zoom) { 946 newState |= java_awt_Frame_MAXIMIZED_BOTH; 947 } 948 949 setIconic(iconify); 950 setZoomed(zoom); 951 952 jint changed = oldState ^ newState; 953 if (changed != 0) { 954 DTRACE_PRINTLN2("AwtFrame::WmSize: reporting state change %x -> %x", 955 oldState, newState); 956 957 // sync target with peer 958 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 959 env->CallVoidMethod(GetPeer(env), AwtFrame::setExtendedStateMID, newState); 960 961 // report (de)iconification to old clients 962 if (changed & java_awt_Frame_ICONIFIED) { 963 if (newState & java_awt_Frame_ICONIFIED) { 964 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_ICONIFIED); 965 } else { 966 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_DEICONIFIED); 967 } 968 } 969 970 // New (since 1.4) state change event 971 SendWindowStateEvent(oldState, newState); 972 } 973 974 // If window is in iconic state, do not send COMPONENT_RESIZED event 975 if (isIconic()) { 976 return mrDoDefault; 977 } 978 979 return AwtWindow::WmSize(type, w, h); 980 } 981 982 MsgRouting AwtFrame::WmActivate(UINT nState, BOOL fMinimized, HWND opposite) 983 { 984 jint type; 985 986 if (nState != WA_INACTIVE) { 987 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())) || 988 CheckActivateActualFocusedWindow(opposite)) 989 { 990 return mrConsume; 991 } 992 type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS; 993 AwtComponent::SetFocusedWindow(GetHWnd()); 994 995 } else { 996 if (!::IsWindow(AwtWindow::GetModalBlocker(opposite))) { 997 // If deactivation happens because of press on grabbing 998 // window - this is nonsense, since grabbing window is 999 // assumed to have focus and watch for deactivation. But 1000 // this can happen - if grabbing window is proxied Window, 1001 // with Frame keeping real focus for it. 1002 if (m_grabbedWindow != NULL) { 1003 if (m_grabbedWindow->GetHWnd() == opposite) { 1004 // Do nothing 1005 } else { 1006 // Normally, we would rather check that this == 1007 // grabbed window, and focus is leaving it - 1008 // ungrab. But since we know about proxied 1009 // windows, we simply assume this is one of the 1010 // known cases. 1011 if (!m_grabbedWindow->IsOneOfOwnersOf((AwtWindow*)AwtComponent::GetComponent(opposite))) { 1012 m_grabbedWindow->Ungrab(); 1013 } 1014 } 1015 } 1016 CheckRetainActualFocusedWindow(opposite); 1017 1018 type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS; 1019 AwtComponent::SetFocusedWindow(NULL); 1020 sm_focusOwner = NULL; 1021 } 1022 } 1023 1024 SendWindowEvent(type, opposite); 1025 return mrConsume; 1026 } 1027 1028 BOOL AwtFrame::CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd) 1029 { 1030 if (m_actualFocusedWindow != NULL) { 1031 HWND hwnd = m_actualFocusedWindow->GetHWnd(); 1032 if (hwnd != NULL && ::IsWindowVisible(hwnd)) { 1033 SynthesizeWmActivate(TRUE, hwnd, deactivatedOpositeHWnd); 1034 return TRUE; 1035 } 1036 m_actualFocusedWindow = NULL; 1037 } 1038 return FALSE; 1039 } 1040 1041 void AwtFrame::CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd) 1042 { 1043 // If actual focused window is not this Frame 1044 if (AwtComponent::GetFocusedWindow() != GetHWnd()) { 1045 // Make sure the actual focused window is an owned window of this frame 1046 AwtWindow *focusedWindow = (AwtWindow *)AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 1047 if (focusedWindow != NULL && focusedWindow->GetOwningFrameOrDialog() == this) { 1048 1049 // Check that the opposite window is not this frame, nor an owned window of this frame 1050 if (activatedOpositeHWnd != NULL) { 1051 AwtWindow *oppositeWindow = (AwtWindow *)AwtComponent::GetComponent(activatedOpositeHWnd); 1052 if (oppositeWindow && oppositeWindow != this && 1053 oppositeWindow->GetOwningFrameOrDialog() != this) 1054 { 1055 m_actualFocusedWindow = focusedWindow; 1056 } 1057 } else { 1058 m_actualFocusedWindow = focusedWindow; 1059 } 1060 } 1061 } 1062 } 1063 1064 BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest) 1065 { 1066 if (hittest == HTCLIENT) { 1067 // Don't let the actualFocusedWindow to steal focus if: 1068 // a) the frame is clicked in its client area; 1069 // b) focus is requested to some of the frame's child. 1070 m_actualFocusedWindow = NULL; 1071 } 1072 if (IsLightweightFrame()) { 1073 return TRUE; 1074 } 1075 if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) { 1076 HWND hwndProxy = GetProxyFocusOwner(); 1077 // Do nothing if this frame is focused already 1078 if (::GetFocus() != hwndProxy) { 1079 // Fix for JDK-8056915: 1080 // If window activated with mouse, set focus to plugin control window 1081 // first to preserve focus owner inside browser window 1082 if (SetFocusToPluginControl(::GetParent(GetHWnd()))) { 1083 return TRUE; 1084 } 1085 // Plugin control window is already focused, so do normal processing 1086 } 1087 } 1088 return AwtWindow::AwtSetActiveWindow(isMouseEventCause); 1089 } 1090 1091 MsgRouting AwtFrame::WmEnterMenuLoop(BOOL isTrackPopupMenu) 1092 { 1093 if ( !isTrackPopupMenu ) { 1094 m_isMenuDropped = TRUE; 1095 } 1096 return mrDoDefault; 1097 } 1098 1099 MsgRouting AwtFrame::WmExitMenuLoop(BOOL isTrackPopupMenu) 1100 { 1101 if ( !isTrackPopupMenu ) { 1102 m_isMenuDropped = FALSE; 1103 } 1104 return mrDoDefault; 1105 } 1106 1107 AwtMenuBar* AwtFrame::GetMenuBar() 1108 { 1109 return menuBar; 1110 } 1111 1112 void AwtFrame::SetMenuBar(AwtMenuBar* mb) 1113 { 1114 menuBar = mb; 1115 if (mb == NULL) { 1116 // Remove existing menu bar, if any. 1117 ::SetMenu(GetHWnd(), NULL); 1118 } else { 1119 if (menuBar->GetHMenu() != NULL) { 1120 ::SetMenu(GetHWnd(), menuBar->GetHMenu()); 1121 } 1122 } 1123 } 1124 1125 MsgRouting AwtFrame::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo) 1126 { 1127 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1128 1129 // if the item to be redrawn is the menu bar, then do it 1130 AwtMenuBar* awtMenubar = GetMenuBar(); 1131 if (drawInfo.CtlType == ODT_MENU && (awtMenubar != NULL) && 1132 (::GetMenu( GetHWnd() ) == (HMENU)drawInfo.hwndItem) ) 1133 { 1134 awtMenubar->DrawItem(drawInfo); 1135 return mrConsume; 1136 } 1137 1138 return AwtComponent::WmDrawItem(ctrlId, drawInfo); 1139 } 1140 1141 MsgRouting AwtFrame::WmMeasureItem(UINT ctrlId, MEASUREITEMSTRUCT& measureInfo) 1142 { 1143 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1144 AwtMenuBar* awtMenubar = GetMenuBar(); 1145 if ((measureInfo.CtlType == ODT_MENU) && (awtMenubar != NULL)) 1146 { 1147 // AwtMenu instance is stored in itemData. Use it to check if this 1148 // menu is the menu bar. 1149 AwtMenu * pMenu = (AwtMenu *) measureInfo.itemData; 1150 DASSERT(pMenu != NULL); 1151 if ( pMenu == awtMenubar ) 1152 { 1153 HWND hWnd = GetHWnd(); 1154 HDC hDC = ::GetDC(hWnd); 1155 DASSERT(hDC != NULL); 1156 awtMenubar->MeasureItem(hDC, measureInfo); 1157 VERIFY(::ReleaseDC(hWnd, hDC)); 1158 return mrConsume; 1159 } 1160 } 1161 1162 return AwtComponent::WmMeasureItem(ctrlId, measureInfo); 1163 } 1164 1165 MsgRouting AwtFrame::WmGetIcon(WPARAM iconType, LRESULT& retVal) 1166 { 1167 //Workaround windows bug: 1168 //when reseting from specific icon to class icon 1169 //taskbar is not updated 1170 if (iconType <= 2 /*ICON_SMALL2*/) { 1171 retVal = (LRESULT)GetEffectiveIcon(iconType); 1172 return mrConsume; 1173 } else { 1174 return mrDoDefault; 1175 } 1176 } 1177 1178 void AwtFrame::DoUpdateIcon() 1179 { 1180 //Workaround windows bug: 1181 //when reseting from specific icon to class icon 1182 //taskbar is not updated 1183 HICON hIcon = GetEffectiveIcon(ICON_BIG); 1184 HICON hIconSm = GetEffectiveIcon(ICON_SMALL); 1185 SendMessage(WM_SETICON, ICON_BIG, (LPARAM)hIcon); 1186 SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); 1187 } 1188 1189 HICON AwtFrame::GetEffectiveIcon(int iconType) 1190 { 1191 BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/)); 1192 HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon(); 1193 if (hIcon == NULL) { 1194 hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() : 1195 AwtToolkit::GetInstance().GetAwtIcon(); 1196 } 1197 return hIcon; 1198 } 1199 1200 static BOOL keepOnMinimize(jobject peer) { 1201 static BOOL checked = FALSE; 1202 static BOOL keep = FALSE; 1203 if (!checked) { 1204 keep = (JNU_GetStaticFieldByName(AwtToolkit::GetEnv(), NULL, 1205 "sun/awt/windows/WFramePeer", "keepOnMinimize", "Z").z) == JNI_TRUE; 1206 checked = TRUE; 1207 } 1208 return keep; 1209 } 1210 1211 MsgRouting AwtFrame::WmSysCommand(UINT uCmdType, int xPos, int yPos) 1212 { 1213 // ignore any WM_SYSCOMMAND if this window is blocked by modal dialog 1214 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1215 return mrConsume; 1216 } 1217 1218 if (uCmdType == (SYSCOMMAND_IMM & 0xFFF0)){ 1219 JNIEnv* env = AwtToolkit::GetEnv(); 1220 JNU_CallMethodByName(env, NULL, m_peerObject, 1221 "notifyIMMOptionChange", "()V"); 1222 DASSERT(!safe_ExceptionOccurred(env)); 1223 return mrConsume; 1224 } 1225 if ((uCmdType == SC_MINIMIZE) && keepOnMinimize(m_peerObject)) { 1226 ::ShowWindow(GetHWnd(),SW_SHOWMINIMIZED); 1227 return mrConsume; 1228 } 1229 return AwtWindow::WmSysCommand(uCmdType, xPos, yPos); 1230 } 1231 1232 LRESULT AwtFrame::WinThreadExecProc(ExecuteArgs * args) 1233 { 1234 switch( args->cmdId ) { 1235 case FRAME_SETMENUBAR: 1236 { 1237 jobject mbPeer = (jobject)args->param1; 1238 1239 // cancel any currently dropped down menus 1240 if (m_isMenuDropped) { 1241 SendMessage(WM_CANCELMODE); 1242 } 1243 1244 if (mbPeer == NULL) { 1245 // Remove existing menu bar, if any 1246 SetMenuBar(NULL); 1247 } else { 1248 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1249 AwtMenuBar* menuBar = (AwtMenuBar *)JNI_GET_PDATA(mbPeer); 1250 SetMenuBar(menuBar); 1251 } 1252 DrawMenuBar(); 1253 break; 1254 } 1255 1256 default: 1257 AwtWindow::WinThreadExecProc(args); 1258 break; 1259 } 1260 1261 return 0L; 1262 } 1263 1264 void AwtFrame::_SynthesizeWmActivate(void *param) 1265 { 1266 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1267 1268 SynthesizeWmActivateStruct *sas = (SynthesizeWmActivateStruct *)param; 1269 jobject self = sas->frame; 1270 jboolean doActivate = sas->doActivate; 1271 1272 AwtFrame *frame = NULL; 1273 1274 PDATA pData; 1275 JNI_CHECK_PEER_GOTO(self, ret); 1276 frame = (AwtFrame *)pData; 1277 1278 SynthesizeWmActivate(doActivate, frame->GetHWnd(), NULL); 1279 ret: 1280 env->DeleteGlobalRef(self); 1281 1282 delete sas; 1283 } 1284 1285 jobject AwtFrame::_GetBoundsPrivate(void *param) 1286 { 1287 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1288 1289 jobject self = (jobject)param; 1290 1291 jobject result = NULL; 1292 AwtFrame *f = NULL; 1293 1294 PDATA pData; 1295 JNI_CHECK_PEER_GOTO(self, ret); 1296 f = (AwtFrame *)pData; 1297 if (::IsWindow(f->GetHWnd())) 1298 { 1299 RECT rect; 1300 ::GetWindowRect(f->GetHWnd(), &rect); 1301 HWND parent = ::GetParent(f->GetHWnd()); 1302 if (::IsWindow(parent)) 1303 { 1304 POINT zero; 1305 zero.x = 0; 1306 zero.y = 0; 1307 ::ClientToScreen(parent, &zero); 1308 ::OffsetRect(&rect, -zero.x, -zero.y); 1309 } 1310 1311 result = JNU_NewObjectByName(env, "java/awt/Rectangle", "(IIII)V", 1312 rect.left, rect.top, rect.bottom-rect.top, rect.right-rect.left); 1313 } 1314 ret: 1315 env->DeleteGlobalRef(self); 1316 1317 if (result != NULL) 1318 { 1319 jobject resultGlobalRef = env->NewGlobalRef(result); 1320 env->DeleteLocalRef(result); 1321 return resultGlobalRef; 1322 } 1323 else 1324 { 1325 return NULL; 1326 } 1327 } 1328 1329 void AwtFrame::_SetState(void *param) 1330 { 1331 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1332 1333 SetStateStruct *sss = (SetStateStruct *)param; 1334 jobject self = sss->frame; 1335 jint state = sss->state; 1336 1337 AwtFrame *f = NULL; 1338 1339 PDATA pData; 1340 JNI_CHECK_PEER_GOTO(self, ret); 1341 f = (AwtFrame *)pData; 1342 HWND hwnd = f->GetHWnd(); 1343 if (::IsWindow(hwnd)) 1344 { 1345 DASSERT(!IsBadReadPtr(f, sizeof(AwtFrame))); 1346 1347 BOOL iconify = (state & java_awt_Frame_ICONIFIED) != 0; 1348 BOOL zoom = (state & java_awt_Frame_MAXIMIZED_BOTH) 1349 == java_awt_Frame_MAXIMIZED_BOTH; 1350 1351 DTRACE_PRINTLN4("WFramePeer.setState:%s%s ->%s%s", 1352 f->isIconic() ? " iconic" : "", 1353 f->isZoomed() ? " zoomed" : "", 1354 iconify ? " iconic" : "", 1355 zoom ? " zoomed" : ""); 1356 1357 if (::IsWindowVisible(hwnd)) { 1358 BOOL focusable = f->IsFocusableWindow(); 1359 1360 WINDOWPLACEMENT wp; 1361 ::ZeroMemory(&wp, sizeof(wp)); 1362 wp.length = sizeof(wp); 1363 ::GetWindowPlacement(hwnd, &wp); 1364 1365 // Iconify first. 1366 // If both iconify & zoom are TRUE, handle this case 1367 // with wp.flags field below. 1368 if (iconify) { 1369 wp.showCmd = focusable ? SW_MINIMIZE : SW_SHOWMINNOACTIVE; 1370 } else if (zoom) { 1371 wp.showCmd = focusable ? SW_SHOWMAXIMIZED : SW_MAXIMIZE; 1372 } else { // zoom == iconify == FALSE 1373 wp.showCmd = focusable ? SW_RESTORE : SW_SHOWNOACTIVATE; 1374 } 1375 1376 if (zoom && iconify) { 1377 wp.flags |= WPF_RESTORETOMAXIMIZED; 1378 } else { 1379 wp.flags &= ~WPF_RESTORETOMAXIMIZED; 1380 } 1381 1382 if (!zoom) { 1383 f->m_forceResetZoomed = TRUE; 1384 } 1385 1386 // The SetWindowPlacement() causes the WmSize() invocation 1387 // which, in turn, actually updates the m_iconic & m_zoomed flags 1388 // as well as sends Java event (WINDOW_STATE_CHANGED.) 1389 ::SetWindowPlacement(hwnd, &wp); 1390 1391 f->m_forceResetZoomed = FALSE; 1392 } else { 1393 DTRACE_PRINTLN(" not visible, just recording the requested state"); 1394 1395 f->setIconic(iconify); 1396 f->setZoomed(zoom); 1397 } 1398 } 1399 ret: 1400 env->DeleteGlobalRef(self); 1401 1402 delete sss; 1403 } 1404 1405 jint AwtFrame::_GetState(void *param) 1406 { 1407 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1408 1409 jobject self = (jobject)param; 1410 1411 jint result = java_awt_Frame_NORMAL; 1412 AwtFrame *f = NULL; 1413 1414 PDATA pData; 1415 JNI_CHECK_PEER_GOTO(self, ret); 1416 f = (AwtFrame *)pData; 1417 if (::IsWindow(f->GetHWnd())) 1418 { 1419 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1420 if (f->isIconic()) { 1421 result |= java_awt_Frame_ICONIFIED; 1422 } 1423 if (f->isZoomed()) { 1424 result |= java_awt_Frame_MAXIMIZED_BOTH; 1425 } 1426 1427 DTRACE_PRINTLN2("WFramePeer.getState:%s%s", 1428 f->isIconic() ? " iconic" : "", 1429 f->isZoomed() ? " zoomed" : ""); 1430 } 1431 ret: 1432 env->DeleteGlobalRef(self); 1433 1434 return result; 1435 } 1436 1437 void AwtFrame::_SetMaximizedBounds(void *param) 1438 { 1439 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1440 1441 SetMaximizedBoundsStruct *smbs = (SetMaximizedBoundsStruct *)param; 1442 jobject self = smbs->frame; 1443 int x = smbs->x; 1444 int y = smbs->y; 1445 int width = smbs->width; 1446 int height = smbs->height; 1447 1448 AwtFrame *f = NULL; 1449 1450 PDATA pData; 1451 JNI_CHECK_PEER_GOTO(self, ret); 1452 f = (AwtFrame *)pData; 1453 if (::IsWindow(f->GetHWnd())) 1454 { 1455 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1456 f->SetMaximizedBounds(x, y, width, height); 1457 } 1458 ret: 1459 env->DeleteGlobalRef(self); 1460 1461 delete smbs; 1462 } 1463 1464 void AwtFrame::_ClearMaximizedBounds(void *param) 1465 { 1466 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1467 1468 jobject self = (jobject)param; 1469 1470 AwtFrame *f = NULL; 1471 1472 PDATA pData; 1473 JNI_CHECK_PEER_GOTO(self, ret); 1474 f = (AwtFrame *)pData; 1475 if (::IsWindow(f->GetHWnd())) 1476 { 1477 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1478 f->ClearMaximizedBounds(); 1479 } 1480 ret: 1481 env->DeleteGlobalRef(self); 1482 } 1483 1484 void AwtFrame::_SetMenuBar(void *param) 1485 { 1486 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1487 1488 SetMenuBarStruct *smbs = (SetMenuBarStruct *)param; 1489 jobject self = smbs->frame; 1490 jobject menubar = smbs->menubar; 1491 1492 AwtFrame *f = NULL; 1493 1494 PDATA pData; 1495 JNI_CHECK_PEER_GOTO(self, ret); 1496 f = (AwtFrame *)pData; 1497 if (::IsWindow(f->GetHWnd())) 1498 { 1499 ExecuteArgs args; 1500 args.cmdId = FRAME_SETMENUBAR; 1501 args.param1 = (LPARAM)menubar; 1502 f->WinThreadExecProc(&args); 1503 } 1504 ret: 1505 env->DeleteGlobalRef(self); 1506 env->DeleteGlobalRef(menubar); 1507 1508 delete smbs; 1509 } 1510 1511 void AwtFrame::_SetIMMOption(void *param) 1512 { 1513 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1514 1515 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; 1516 jobject self = sios->frame; 1517 jstring option = sios->option; 1518 1519 int badAlloc = 0; 1520 LPCTSTR coption; 1521 LPCTSTR empty = TEXT("InputMethod"); 1522 AwtFrame *f = NULL; 1523 1524 PDATA pData; 1525 JNI_CHECK_PEER_GOTO(self, ret); 1526 JNI_CHECK_NULL_GOTO(option, "IMMOption argument", ret); 1527 1528 f = (AwtFrame *)pData; 1529 if (::IsWindow(f->GetHWnd())) 1530 { 1531 coption = JNU_GetStringPlatformChars(env, option, NULL); 1532 if (coption == NULL) 1533 { 1534 badAlloc = 1; 1535 } 1536 if (!badAlloc) 1537 { 1538 HMENU hSysMenu = ::GetSystemMenu(f->GetHWnd(), FALSE); 1539 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); 1540 1541 if (coption != empty) 1542 { 1543 JNU_ReleaseStringPlatformChars(env, option, coption); 1544 } 1545 } 1546 } 1547 ret: 1548 env->DeleteGlobalRef(self); 1549 env->DeleteGlobalRef(option); 1550 1551 delete sios; 1552 1553 if (badAlloc) 1554 { 1555 throw std::bad_alloc(); 1556 } 1557 } 1558 1559 void AwtFrame::_NotifyModalBlocked(void *param) 1560 { 1561 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1562 1563 NotifyModalBlockedStruct *nmbs = (NotifyModalBlockedStruct *)param; 1564 jobject self = nmbs->frame; 1565 jobject peer = nmbs->peer; 1566 jobject blockerPeer = nmbs->blockerPeer; 1567 jboolean blocked = nmbs->blocked; 1568 1569 PDATA pData; 1570 1571 pData = JNI_GET_PDATA(peer); 1572 AwtFrame *f = (AwtFrame *)pData; 1573 1574 // dialog here may be NULL, for example, if the blocker is a native dialog 1575 // however, we need to install/unistall modal hooks anyway 1576 pData = JNI_GET_PDATA(blockerPeer); 1577 AwtDialog *d = (AwtDialog *)pData; 1578 1579 if ((f != NULL) && ::IsWindow(f->GetHWnd())) 1580 { 1581 // get an HWND of the toplevel window this embedded frame is within 1582 HWND fHWnd = f->GetHWnd(); 1583 while (::GetParent(fHWnd) != NULL) { 1584 fHWnd = ::GetParent(fHWnd); 1585 } 1586 // we must get a toplevel hwnd here, however due to some strange 1587 // behaviour of Java Plugin (a bug?) when running in IE at 1588 // this moment the embedded frame hasn't been placed into the 1589 // browser yet and fHWnd is not a toplevel, so we shouldn't install 1590 // the hook here 1591 if ((::GetWindowLong(fHWnd, GWL_STYLE) & WS_CHILD) == 0) { 1592 // if this toplevel is created in another thread, we should install 1593 // the modal hook into it to track window activation and mouse events 1594 DWORD fThread = ::GetWindowThreadProcessId(fHWnd, NULL); 1595 if (fThread != AwtToolkit::GetInstance().MainThread()) { 1596 // check if this thread has been already blocked 1597 BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)fThread); 1598 if (blocked) { 1599 if (blockedThread == NULL) { 1600 blockedThread = new BlockedThreadStruct; 1601 blockedThread->framesCount = 1; 1602 blockedThread->modalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtDialog::ModalFilterProc, 1603 0, fThread); 1604 blockedThread->mouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtDialog::MouseHookProc_NonTT, 1605 0, fThread); 1606 sm_BlockedThreads.put((void *)fThread, blockedThread); 1607 } else { 1608 blockedThread->framesCount++; 1609 } 1610 } else { 1611 // see the comment above: if Java Plugin behaviour when running in IE 1612 // was right, blockedThread would be always not NULL here 1613 if (blockedThread != NULL) { 1614 DASSERT(blockedThread->framesCount > 0); 1615 if ((blockedThread->framesCount) == 1) { 1616 ::UnhookWindowsHookEx(blockedThread->modalHook); 1617 ::UnhookWindowsHookEx(blockedThread->mouseHook); 1618 sm_BlockedThreads.remove((void *)fThread); 1619 delete blockedThread; 1620 } else { 1621 blockedThread->framesCount--; 1622 } 1623 } 1624 } 1625 } 1626 } 1627 } 1628 1629 env->DeleteGlobalRef(self); 1630 env->DeleteGlobalRef(peer); 1631 env->DeleteGlobalRef(blockerPeer); 1632 1633 delete nmbs; 1634 } 1635 1636 /************************************************************************ 1637 * WFramePeer native methods 1638 */ 1639 1640 extern "C" { 1641 1642 /* 1643 * Class: java_awt_Frame 1644 * Method: initIDs 1645 * Signature: ()V 1646 */ 1647 JNIEXPORT void JNICALL 1648 Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls) 1649 { 1650 TRY; 1651 1652 AwtFrame::undecoratedID = env->GetFieldID(cls,"undecorated","Z"); 1653 DASSERT(AwtFrame::undecoratedID != NULL); 1654 1655 CATCH_BAD_ALLOC; 1656 } 1657 1658 /* 1659 * Class: sun_awt_windows_WFramePeer 1660 * Method: initIDs 1661 * Signature: ()V 1662 */ 1663 JNIEXPORT void JNICALL 1664 Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls) 1665 { 1666 TRY; 1667 1668 AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V"); 1669 DASSERT(AwtFrame::setExtendedStateMID); 1670 CHECK_NULL(AwtFrame::setExtendedStateMID); 1671 1672 AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I"); 1673 DASSERT(AwtFrame::getExtendedStateMID); 1674 1675 CATCH_BAD_ALLOC; 1676 } 1677 1678 /* 1679 * Class: sun_awt_windows_WFramePeer 1680 * Method: setState 1681 * Signature: (I)V 1682 */ 1683 JNIEXPORT void JNICALL 1684 Java_sun_awt_windows_WFramePeer_setState(JNIEnv *env, jobject self, 1685 jint state) 1686 { 1687 TRY; 1688 1689 SetStateStruct *sss = new SetStateStruct; 1690 sss->frame = env->NewGlobalRef(self); 1691 sss->state = state; 1692 1693 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetState, sss); 1694 // global ref and sss are deleted in _SetState() 1695 1696 CATCH_BAD_ALLOC; 1697 } 1698 1699 /* 1700 * Class: sun_awt_windows_WFramePeer 1701 * Method: getState 1702 * Signature: ()I 1703 */ 1704 JNIEXPORT jint JNICALL 1705 Java_sun_awt_windows_WFramePeer_getState(JNIEnv *env, jobject self) 1706 { 1707 TRY; 1708 1709 jobject selfGlobalRef = env->NewGlobalRef(self); 1710 1711 return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall( 1712 (void*(*)(void*))AwtFrame::_GetState, 1713 (void *)selfGlobalRef))); 1714 // selfGlobalRef is deleted in _GetState() 1715 1716 CATCH_BAD_ALLOC_RET(java_awt_Frame_NORMAL); 1717 } 1718 1719 1720 /* 1721 * Class: sun_awt_windows_WFramePeer 1722 * Method: setMaximizedBounds 1723 * Signature: (IIII)V 1724 */ 1725 JNIEXPORT void JNICALL 1726 Java_sun_awt_windows_WFramePeer_setMaximizedBounds(JNIEnv *env, jobject self, 1727 jint x, jint y, jint width, jint height) 1728 { 1729 TRY; 1730 1731 SetMaximizedBoundsStruct *smbs = new SetMaximizedBoundsStruct; 1732 smbs->frame = env->NewGlobalRef(self); 1733 smbs->x = x; 1734 smbs->y = y; 1735 smbs->width = width; 1736 smbs->height = height; 1737 1738 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMaximizedBounds, smbs); 1739 // global ref and smbs are deleted in _SetMaximizedBounds() 1740 1741 CATCH_BAD_ALLOC; 1742 } 1743 1744 1745 /* 1746 * Class: sun_awt_windows_WFramePeer 1747 * Method: clearMaximizedBounds 1748 * Signature: ()V 1749 */ 1750 JNIEXPORT void JNICALL 1751 Java_sun_awt_windows_WFramePeer_clearMaximizedBounds(JNIEnv *env, jobject self) 1752 { 1753 TRY; 1754 1755 jobject selfGlobalRef = env->NewGlobalRef(self); 1756 1757 AwtToolkit::GetInstance().SyncCall(AwtFrame::_ClearMaximizedBounds, 1758 (void *)selfGlobalRef); 1759 // selfGlobalRef is deleted in _ClearMaximizedBounds() 1760 1761 CATCH_BAD_ALLOC; 1762 } 1763 1764 1765 /* 1766 * Class: sun_awt_windows_WFramePeer 1767 * Method: setMenuBar0 1768 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V 1769 */ 1770 JNIEXPORT void JNICALL 1771 Java_sun_awt_windows_WFramePeer_setMenuBar0(JNIEnv *env, jobject self, 1772 jobject mbPeer) 1773 { 1774 TRY; 1775 1776 SetMenuBarStruct *smbs = new SetMenuBarStruct; 1777 smbs->frame = env->NewGlobalRef(self); 1778 smbs->menubar = env->NewGlobalRef(mbPeer); 1779 1780 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMenuBar, smbs); 1781 // global refs ans smbs are deleted in _SetMenuBar() 1782 1783 CATCH_BAD_ALLOC; 1784 } 1785 1786 /* 1787 * Class: sun_awt_windows_WFramePeer 1788 * Method: create 1789 * Signature: (Lsun/awt/windows/WComponentPeer;)V 1790 */ 1791 JNIEXPORT void JNICALL 1792 Java_sun_awt_windows_WFramePeer_createAwtFrame(JNIEnv *env, jobject self, 1793 jobject parent) 1794 { 1795 TRY; 1796 1797 AwtToolkit::CreateComponent(self, parent, 1798 (AwtToolkit::ComponentFactory) 1799 AwtFrame::Create); 1800 PDATA pData; 1801 JNI_CHECK_PEER_CREATION_RETURN(self); 1802 1803 CATCH_BAD_ALLOC; 1804 } 1805 1806 /* 1807 * Class: sun_awt_windows_WFramePeer 1808 * Method: getSysMenuHeight 1809 * Signature: ()I 1810 */ 1811 JNIEXPORT jint JNICALL 1812 Java_sun_awt_windows_WFramePeer_getSysMenuHeight(JNIEnv *env, jclass self) 1813 { 1814 TRY; 1815 1816 return ::GetSystemMetrics(SM_CYMENUSIZE); 1817 1818 CATCH_BAD_ALLOC_RET(0); 1819 } 1820 1821 /* 1822 * Class: sun_awt_windows_WFramePeer 1823 * Method: pSetIMMOption 1824 * Signature: (Ljava/lang/String;)V 1825 */ 1826 JNIEXPORT void JNICALL 1827 Java_sun_awt_windows_WFramePeer_pSetIMMOption(JNIEnv *env, jobject self, 1828 jstring option) 1829 { 1830 TRY; 1831 1832 SetIMMOptionStruct *sios = new SetIMMOptionStruct; 1833 sios->frame = env->NewGlobalRef(self); 1834 sios->option = (jstring)env->NewGlobalRef(option); 1835 1836 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetIMMOption, sios); 1837 // global refs and sios are deleted in _SetIMMOption() 1838 1839 CATCH_BAD_ALLOC; 1840 } 1841 1842 } /* extern "C" */ 1843 1844 1845 /************************************************************************ 1846 * WEmbeddedFrame native methods 1847 */ 1848 1849 extern "C" { 1850 1851 /* 1852 * Class: sun_awt_windows_WFramePeer 1853 * Method: initIDs 1854 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V 1855 */ 1856 JNIEXPORT void JNICALL 1857 Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls) 1858 { 1859 TRY; 1860 1861 AwtFrame::handleID = env->GetFieldID(cls, "handle", "J"); 1862 DASSERT(AwtFrame::handleID != NULL); 1863 CHECK_NULL(AwtFrame::handleID); 1864 1865 AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V"); 1866 DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL); 1867 CHECK_NULL(AwtFrame::activateEmbeddingTopLevelMID); 1868 1869 AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z"); 1870 DASSERT(AwtFrame::isEmbeddedInIEID != NULL); 1871 1872 CATCH_BAD_ALLOC; 1873 } 1874 1875 JNIEXPORT void JNICALL 1876 Java_sun_awt_windows_WEmbeddedFrame_notifyModalBlockedImpl(JNIEnv *env, 1877 jobject self, 1878 jobject peer, 1879 jobject blockerPeer, 1880 jboolean blocked) 1881 { 1882 TRY; 1883 1884 NotifyModalBlockedStruct *nmbs = new NotifyModalBlockedStruct; 1885 nmbs->frame = env->NewGlobalRef(self); 1886 nmbs->peer = env->NewGlobalRef(peer); 1887 nmbs->blockerPeer = env->NewGlobalRef(blockerPeer); 1888 nmbs->blocked = blocked; 1889 1890 AwtToolkit::GetInstance().SyncCall(AwtFrame::_NotifyModalBlocked, nmbs); 1891 // global refs and nmbs are deleted in _NotifyModalBlocked() 1892 1893 CATCH_BAD_ALLOC; 1894 } 1895 1896 } /* extern "C" */ 1897 1898 1899 /************************************************************************ 1900 * WEmbeddedFramePeer native methods 1901 */ 1902 1903 extern "C" { 1904 1905 JNIEXPORT void JNICALL 1906 Java_sun_awt_windows_WEmbeddedFramePeer_create(JNIEnv *env, jobject self, 1907 jobject parent) 1908 { 1909 TRY; 1910 1911 JNI_CHECK_NULL_RETURN(self, "peer"); 1912 AwtToolkit::CreateComponent(self, parent, 1913 (AwtToolkit::ComponentFactory) 1914 AwtFrame::Create); 1915 PDATA pData; 1916 JNI_CHECK_PEER_CREATION_RETURN(self); 1917 1918 CATCH_BAD_ALLOC; 1919 } 1920 1921 JNIEXPORT jobject JNICALL 1922 Java_sun_awt_windows_WEmbeddedFramePeer_getBoundsPrivate(JNIEnv *env, jobject self) 1923 { 1924 TRY; 1925 1926 jobject result = (jobject)AwtToolkit::GetInstance().SyncCall( 1927 (void *(*)(void *))AwtFrame::_GetBoundsPrivate, 1928 env->NewGlobalRef(self)); 1929 // global ref is deleted in _GetBoundsPrivate 1930 1931 if (result != NULL) 1932 { 1933 jobject resultLocalRef = env->NewLocalRef(result); 1934 env->DeleteGlobalRef(result); 1935 return resultLocalRef; 1936 } 1937 else 1938 { 1939 return NULL; 1940 } 1941 1942 CATCH_BAD_ALLOC_RET(NULL); 1943 } 1944 1945 JNIEXPORT void JNICALL 1946 Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate) 1947 { 1948 TRY; 1949 1950 SynthesizeWmActivateStruct *sas = new SynthesizeWmActivateStruct; 1951 sas->frame = env->NewGlobalRef(self); 1952 sas->doActivate = doActivate; 1953 1954 /* 1955 * WARNING: invoking this function without synchronization by m_Sync CriticalSection. 1956 * Taking this lock results in a deadlock. 1957 */ 1958 AwtToolkit::GetInstance().InvokeFunction(AwtFrame::_SynthesizeWmActivate, sas); 1959 // global ref and sas are deleted in _SynthesizeWmActivate() 1960 1961 CATCH_BAD_ALLOC; 1962 } 1963 1964 } /* extern "C" */ 1965 1966 static bool SetFocusToPluginControl(HWND hwndPlugin) 1967 { 1968 HWND hwndFocus = ::GetFocus(); 1969 1970 if (hwndFocus == hwndPlugin) { 1971 return false; 1972 } 1973 1974 ::SetFocus(hwndPlugin); 1975 DWORD dwError = ::GetLastError(); 1976 if (dwError != ERROR_SUCCESS) { 1977 // If direct call failed, use a special message to set focus 1978 return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0); 1979 } 1980 return true; 1981 }