1 /* 2 * Copyright (c) 1996, 2016, 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 = NULL; 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 return mrConsume; 998 } else { 999 // If deactivation happens because of press on grabbing 1000 // window - this is nonsense, since grabbing window is 1001 // assumed to have focus and watch for deactivation. But 1002 // this can happen - if grabbing window is proxied Window, 1003 // with Frame keeping real focus for it. 1004 if (m_grabbedWindow != NULL) { 1005 if (m_grabbedWindow->GetHWnd() == opposite) { 1006 // Do nothing 1007 } else { 1008 // Normally, we would rather check that this == 1009 // grabbed window, and focus is leaving it - 1010 // ungrab. But since we know about proxied 1011 // windows, we simply assume this is one of the 1012 // known cases. 1013 if (!m_grabbedWindow->IsOneOfOwnersOf((AwtWindow*)AwtComponent::GetComponent(opposite))) { 1014 m_grabbedWindow->Ungrab(); 1015 } 1016 } 1017 } 1018 CheckRetainActualFocusedWindow(opposite); 1019 1020 type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS; 1021 AwtComponent::SetFocusedWindow(NULL); 1022 sm_focusOwner = NULL; 1023 } 1024 } 1025 1026 SendWindowEvent(type, opposite); 1027 return mrConsume; 1028 } 1029 1030 BOOL AwtFrame::CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd) 1031 { 1032 if (m_actualFocusedWindow != NULL) { 1033 HWND hwnd = m_actualFocusedWindow->GetHWnd(); 1034 if (hwnd != NULL && ::IsWindowVisible(hwnd)) { 1035 SynthesizeWmActivate(TRUE, hwnd, deactivatedOpositeHWnd); 1036 return TRUE; 1037 } 1038 m_actualFocusedWindow = NULL; 1039 } 1040 return FALSE; 1041 } 1042 1043 void AwtFrame::CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd) 1044 { 1045 // If actual focused window is not this Frame 1046 if (AwtComponent::GetFocusedWindow() != GetHWnd()) { 1047 // Make sure the actual focused window is an owned window of this frame 1048 AwtWindow *focusedWindow = (AwtWindow *)AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 1049 if (focusedWindow != NULL && focusedWindow->GetOwningFrameOrDialog() == this) { 1050 1051 // Check that the opposite window is not this frame, nor an owned window of this frame 1052 if (activatedOpositeHWnd != NULL) { 1053 AwtWindow *oppositeWindow = (AwtWindow *)AwtComponent::GetComponent(activatedOpositeHWnd); 1054 if (oppositeWindow && oppositeWindow != this && 1055 oppositeWindow->GetOwningFrameOrDialog() != this) 1056 { 1057 m_actualFocusedWindow = focusedWindow; 1058 } 1059 } else { 1060 m_actualFocusedWindow = focusedWindow; 1061 } 1062 } 1063 } 1064 } 1065 1066 BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest) 1067 { 1068 if (hittest == HTCLIENT) { 1069 // Don't let the actualFocusedWindow to steal focus if: 1070 // a) the frame is clicked in its client area; 1071 // b) focus is requested to some of the frame's child. 1072 m_actualFocusedWindow = NULL; 1073 } 1074 if (IsLightweightFrame()) { 1075 return TRUE; 1076 } 1077 if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) { 1078 HWND hwndProxy = GetProxyFocusOwner(); 1079 // Do nothing if this frame is focused already 1080 if (::GetFocus() != hwndProxy) { 1081 // Fix for JDK-8056915: 1082 // If window activated with mouse, set focus to plugin control window 1083 // first to preserve focus owner inside browser window 1084 if (SetFocusToPluginControl(::GetParent(GetHWnd()))) { 1085 return TRUE; 1086 } 1087 // Plugin control window is already focused, so do normal processing 1088 } 1089 } 1090 return AwtWindow::AwtSetActiveWindow(isMouseEventCause); 1091 } 1092 1093 MsgRouting AwtFrame::WmEnterMenuLoop(BOOL isTrackPopupMenu) 1094 { 1095 if ( !isTrackPopupMenu ) { 1096 m_isMenuDropped = TRUE; 1097 } 1098 return mrDoDefault; 1099 } 1100 1101 MsgRouting AwtFrame::WmExitMenuLoop(BOOL isTrackPopupMenu) 1102 { 1103 if ( !isTrackPopupMenu ) { 1104 m_isMenuDropped = FALSE; 1105 } 1106 return mrDoDefault; 1107 } 1108 1109 AwtMenuBar* AwtFrame::GetMenuBar() 1110 { 1111 return menuBar; 1112 } 1113 1114 void AwtFrame::SetMenuBar(AwtMenuBar* mb) 1115 { 1116 if (menuBar) { 1117 menuBar->SetFrame(NULL); 1118 } 1119 menuBar = mb; 1120 if (mb == NULL) { 1121 // Remove existing menu bar, if any. 1122 ::SetMenu(GetHWnd(), NULL); 1123 } else { 1124 AwtFrame* oldFrame = menuBar->GetFrame(); 1125 if (oldFrame && oldFrame != this) { 1126 oldFrame->SetMenuBar(NULL); 1127 } 1128 menuBar->SetFrame(this); 1129 if (menuBar->GetHMenu() != NULL) { 1130 ::SetMenu(GetHWnd(), menuBar->GetHMenu()); 1131 } 1132 } 1133 } 1134 1135 MsgRouting AwtFrame::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo) 1136 { 1137 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1138 1139 // if the item to be redrawn is the menu bar, then do it 1140 AwtMenuBar* awtMenubar = GetMenuBar(); 1141 if (drawInfo.CtlType == ODT_MENU && (awtMenubar != NULL) && 1142 (::GetMenu( GetHWnd() ) == (HMENU)drawInfo.hwndItem) ) 1143 { 1144 awtMenubar->DrawItem(drawInfo); 1145 return mrConsume; 1146 } 1147 1148 return AwtComponent::WmDrawItem(ctrlId, drawInfo); 1149 } 1150 1151 MsgRouting AwtFrame::WmMeasureItem(UINT ctrlId, MEASUREITEMSTRUCT& measureInfo) 1152 { 1153 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1154 AwtMenuBar* awtMenubar = GetMenuBar(); 1155 if ((measureInfo.CtlType == ODT_MENU) && (awtMenubar != NULL)) 1156 { 1157 // AwtMenu instance is stored in itemData. Use it to check if this 1158 // menu is the menu bar. 1159 AwtMenu * pMenu = (AwtMenu *) measureInfo.itemData; 1160 DASSERT(pMenu != NULL); 1161 if ( pMenu == awtMenubar ) 1162 { 1163 HWND hWnd = GetHWnd(); 1164 HDC hDC = ::GetDC(hWnd); 1165 DASSERT(hDC != NULL); 1166 awtMenubar->MeasureItem(hDC, measureInfo); 1167 VERIFY(::ReleaseDC(hWnd, hDC)); 1168 return mrConsume; 1169 } 1170 } 1171 1172 return AwtComponent::WmMeasureItem(ctrlId, measureInfo); 1173 } 1174 1175 MsgRouting AwtFrame::WmGetIcon(WPARAM iconType, LRESULT& retVal) 1176 { 1177 //Workaround windows bug: 1178 //when reseting from specific icon to class icon 1179 //taskbar is not updated 1180 if (iconType <= 2 /*ICON_SMALL2*/) { 1181 retVal = (LRESULT)GetEffectiveIcon(iconType); 1182 return mrConsume; 1183 } else { 1184 return mrDoDefault; 1185 } 1186 } 1187 1188 void AwtFrame::DoUpdateIcon() 1189 { 1190 //Workaround windows bug: 1191 //when reseting from specific icon to class icon 1192 //taskbar is not updated 1193 HICON hIcon = GetEffectiveIcon(ICON_BIG); 1194 HICON hIconSm = GetEffectiveIcon(ICON_SMALL); 1195 SendMessage(WM_SETICON, ICON_BIG, (LPARAM)hIcon); 1196 SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); 1197 } 1198 1199 HICON AwtFrame::GetEffectiveIcon(int iconType) 1200 { 1201 BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/)); 1202 HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon(); 1203 if (hIcon == NULL) { 1204 hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() : 1205 AwtToolkit::GetInstance().GetAwtIcon(); 1206 } 1207 return hIcon; 1208 } 1209 1210 static BOOL keepOnMinimize(jobject peer) { 1211 static BOOL checked = FALSE; 1212 static BOOL keep = FALSE; 1213 if (!checked) { 1214 keep = (JNU_GetStaticFieldByName(AwtToolkit::GetEnv(), NULL, 1215 "sun/awt/windows/WFramePeer", "keepOnMinimize", "Z").z) == JNI_TRUE; 1216 checked = TRUE; 1217 } 1218 return keep; 1219 } 1220 1221 MsgRouting AwtFrame::WmSysCommand(UINT uCmdType, int xPos, int yPos) 1222 { 1223 // ignore any WM_SYSCOMMAND if this window is blocked by modal dialog 1224 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1225 return mrConsume; 1226 } 1227 1228 if (uCmdType == (SYSCOMMAND_IMM & 0xFFF0)){ 1229 JNIEnv* env = AwtToolkit::GetEnv(); 1230 JNU_CallMethodByName(env, NULL, m_peerObject, 1231 "notifyIMMOptionChange", "()V"); 1232 DASSERT(!safe_ExceptionOccurred(env)); 1233 return mrConsume; 1234 } 1235 if ((uCmdType == SC_MINIMIZE) && keepOnMinimize(m_peerObject)) { 1236 ::ShowWindow(GetHWnd(),SW_SHOWMINIMIZED); 1237 return mrConsume; 1238 } 1239 return AwtWindow::WmSysCommand(uCmdType, xPos, yPos); 1240 } 1241 1242 LRESULT AwtFrame::WinThreadExecProc(ExecuteArgs * args) 1243 { 1244 switch( args->cmdId ) { 1245 case FRAME_SETMENUBAR: 1246 { 1247 jobject mbPeer = (jobject)args->param1; 1248 1249 // cancel any currently dropped down menus 1250 if (m_isMenuDropped) { 1251 SendMessage(WM_CANCELMODE); 1252 } 1253 1254 if (mbPeer == NULL) { 1255 // Remove existing menu bar, if any 1256 SetMenuBar(NULL); 1257 } else { 1258 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1259 AwtMenuBar* menuBar = (AwtMenuBar *)JNI_GET_PDATA(mbPeer); 1260 SetMenuBar(menuBar); 1261 } 1262 DrawMenuBar(); 1263 break; 1264 } 1265 1266 default: 1267 AwtWindow::WinThreadExecProc(args); 1268 break; 1269 } 1270 1271 return 0L; 1272 } 1273 1274 void AwtFrame::_SynthesizeWmActivate(void *param) 1275 { 1276 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1277 1278 SynthesizeWmActivateStruct *sas = (SynthesizeWmActivateStruct *)param; 1279 jobject self = sas->frame; 1280 jboolean doActivate = sas->doActivate; 1281 1282 AwtFrame *frame = NULL; 1283 1284 PDATA pData; 1285 JNI_CHECK_PEER_GOTO(self, ret); 1286 frame = (AwtFrame *)pData; 1287 1288 SynthesizeWmActivate(doActivate, frame->GetHWnd(), NULL); 1289 ret: 1290 env->DeleteGlobalRef(self); 1291 1292 delete sas; 1293 } 1294 1295 jobject AwtFrame::_GetBoundsPrivate(void *param) 1296 { 1297 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1298 1299 jobject self = (jobject)param; 1300 1301 jobject result = NULL; 1302 AwtFrame *f = NULL; 1303 1304 PDATA pData; 1305 JNI_CHECK_PEER_GOTO(self, ret); 1306 f = (AwtFrame *)pData; 1307 if (::IsWindow(f->GetHWnd())) 1308 { 1309 RECT rect; 1310 ::GetWindowRect(f->GetHWnd(), &rect); 1311 HWND parent = ::GetParent(f->GetHWnd()); 1312 if (::IsWindow(parent)) 1313 { 1314 POINT zero; 1315 zero.x = 0; 1316 zero.y = 0; 1317 ::ClientToScreen(parent, &zero); 1318 ::OffsetRect(&rect, -zero.x, -zero.y); 1319 } 1320 1321 result = JNU_NewObjectByName(env, "java/awt/Rectangle", "(IIII)V", 1322 rect.left, rect.top, rect.bottom-rect.top, rect.right-rect.left); 1323 } 1324 ret: 1325 env->DeleteGlobalRef(self); 1326 1327 if (result != NULL) 1328 { 1329 jobject resultGlobalRef = env->NewGlobalRef(result); 1330 env->DeleteLocalRef(result); 1331 return resultGlobalRef; 1332 } 1333 else 1334 { 1335 return NULL; 1336 } 1337 } 1338 1339 void AwtFrame::_SetState(void *param) 1340 { 1341 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1342 1343 SetStateStruct *sss = (SetStateStruct *)param; 1344 jobject self = sss->frame; 1345 jint state = sss->state; 1346 1347 AwtFrame *f = NULL; 1348 1349 PDATA pData; 1350 JNI_CHECK_PEER_GOTO(self, ret); 1351 f = (AwtFrame *)pData; 1352 HWND hwnd = f->GetHWnd(); 1353 if (::IsWindow(hwnd)) 1354 { 1355 DASSERT(!IsBadReadPtr(f, sizeof(AwtFrame))); 1356 1357 BOOL iconify = (state & java_awt_Frame_ICONIFIED) != 0; 1358 BOOL zoom = (state & java_awt_Frame_MAXIMIZED_BOTH) 1359 == java_awt_Frame_MAXIMIZED_BOTH; 1360 1361 DTRACE_PRINTLN4("WFramePeer.setState:%s%s ->%s%s", 1362 f->isIconic() ? " iconic" : "", 1363 f->isZoomed() ? " zoomed" : "", 1364 iconify ? " iconic" : "", 1365 zoom ? " zoomed" : ""); 1366 1367 if (::IsWindowVisible(hwnd)) { 1368 BOOL focusable = f->IsFocusableWindow(); 1369 1370 WINDOWPLACEMENT wp; 1371 ::ZeroMemory(&wp, sizeof(wp)); 1372 wp.length = sizeof(wp); 1373 ::GetWindowPlacement(hwnd, &wp); 1374 1375 // Iconify first. 1376 // If both iconify & zoom are TRUE, handle this case 1377 // with wp.flags field below. 1378 if (iconify) { 1379 wp.showCmd = focusable ? SW_MINIMIZE : SW_SHOWMINNOACTIVE; 1380 } else if (zoom) { 1381 wp.showCmd = focusable ? SW_SHOWMAXIMIZED : SW_MAXIMIZE; 1382 } else { // zoom == iconify == FALSE 1383 wp.showCmd = focusable ? SW_RESTORE : SW_SHOWNOACTIVATE; 1384 } 1385 1386 if (zoom && iconify) { 1387 wp.flags |= WPF_RESTORETOMAXIMIZED; 1388 } else { 1389 wp.flags &= ~WPF_RESTORETOMAXIMIZED; 1390 } 1391 1392 if (!zoom) { 1393 f->m_forceResetZoomed = TRUE; 1394 } 1395 1396 // The SetWindowPlacement() causes the WmSize() invocation 1397 // which, in turn, actually updates the m_iconic & m_zoomed flags 1398 // as well as sends Java event (WINDOW_STATE_CHANGED.) 1399 ::SetWindowPlacement(hwnd, &wp); 1400 1401 f->m_forceResetZoomed = FALSE; 1402 } else { 1403 DTRACE_PRINTLN(" not visible, just recording the requested state"); 1404 1405 f->setIconic(iconify); 1406 f->setZoomed(zoom); 1407 } 1408 } 1409 ret: 1410 env->DeleteGlobalRef(self); 1411 1412 delete sss; 1413 } 1414 1415 jint AwtFrame::_GetState(void *param) 1416 { 1417 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1418 1419 jobject self = (jobject)param; 1420 1421 jint result = java_awt_Frame_NORMAL; 1422 AwtFrame *f = NULL; 1423 1424 PDATA pData; 1425 JNI_CHECK_PEER_GOTO(self, ret); 1426 f = (AwtFrame *)pData; 1427 if (::IsWindow(f->GetHWnd())) 1428 { 1429 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1430 if (f->isIconic()) { 1431 result |= java_awt_Frame_ICONIFIED; 1432 } 1433 if (f->isZoomed()) { 1434 result |= java_awt_Frame_MAXIMIZED_BOTH; 1435 } 1436 1437 DTRACE_PRINTLN2("WFramePeer.getState:%s%s", 1438 f->isIconic() ? " iconic" : "", 1439 f->isZoomed() ? " zoomed" : ""); 1440 } 1441 ret: 1442 env->DeleteGlobalRef(self); 1443 1444 return result; 1445 } 1446 1447 void AwtFrame::_SetMaximizedBounds(void *param) 1448 { 1449 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1450 1451 SetMaximizedBoundsStruct *smbs = (SetMaximizedBoundsStruct *)param; 1452 jobject self = smbs->frame; 1453 int x = smbs->x; 1454 int y = smbs->y; 1455 int width = smbs->width; 1456 int height = smbs->height; 1457 1458 AwtFrame *f = NULL; 1459 1460 PDATA pData; 1461 JNI_CHECK_PEER_GOTO(self, ret); 1462 f = (AwtFrame *)pData; 1463 if (::IsWindow(f->GetHWnd())) 1464 { 1465 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1466 f->SetMaximizedBounds(x, y, width, height); 1467 } 1468 ret: 1469 env->DeleteGlobalRef(self); 1470 1471 delete smbs; 1472 } 1473 1474 void AwtFrame::_ClearMaximizedBounds(void *param) 1475 { 1476 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1477 1478 jobject self = (jobject)param; 1479 1480 AwtFrame *f = NULL; 1481 1482 PDATA pData; 1483 JNI_CHECK_PEER_GOTO(self, ret); 1484 f = (AwtFrame *)pData; 1485 if (::IsWindow(f->GetHWnd())) 1486 { 1487 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1488 f->ClearMaximizedBounds(); 1489 } 1490 ret: 1491 env->DeleteGlobalRef(self); 1492 } 1493 1494 void AwtFrame::_SetMenuBar(void *param) 1495 { 1496 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1497 1498 SetMenuBarStruct *smbs = (SetMenuBarStruct *)param; 1499 jobject self = smbs->frame; 1500 jobject menubar = smbs->menubar; 1501 1502 AwtFrame *f = NULL; 1503 1504 PDATA pData; 1505 JNI_CHECK_PEER_GOTO(self, ret); 1506 f = (AwtFrame *)pData; 1507 if (::IsWindow(f->GetHWnd())) 1508 { 1509 ExecuteArgs args; 1510 args.cmdId = FRAME_SETMENUBAR; 1511 args.param1 = (LPARAM)menubar; 1512 f->WinThreadExecProc(&args); 1513 } 1514 ret: 1515 env->DeleteGlobalRef(self); 1516 env->DeleteGlobalRef(menubar); 1517 1518 delete smbs; 1519 } 1520 1521 void AwtFrame::_SetIMMOption(void *param) 1522 { 1523 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1524 1525 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; 1526 jobject self = sios->frame; 1527 jstring option = sios->option; 1528 1529 int badAlloc = 0; 1530 LPCTSTR coption; 1531 LPCTSTR empty = TEXT("InputMethod"); 1532 AwtFrame *f = NULL; 1533 1534 PDATA pData; 1535 JNI_CHECK_PEER_GOTO(self, ret); 1536 JNI_CHECK_NULL_GOTO(option, "IMMOption argument", ret); 1537 1538 f = (AwtFrame *)pData; 1539 if (::IsWindow(f->GetHWnd())) 1540 { 1541 coption = JNU_GetStringPlatformChars(env, option, NULL); 1542 if (coption == NULL) 1543 { 1544 badAlloc = 1; 1545 } 1546 if (!badAlloc) 1547 { 1548 HMENU hSysMenu = ::GetSystemMenu(f->GetHWnd(), FALSE); 1549 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); 1550 1551 if (coption != empty) 1552 { 1553 JNU_ReleaseStringPlatformChars(env, option, coption); 1554 } 1555 } 1556 } 1557 ret: 1558 env->DeleteGlobalRef(self); 1559 env->DeleteGlobalRef(option); 1560 1561 delete sios; 1562 1563 if (badAlloc) 1564 { 1565 throw std::bad_alloc(); 1566 } 1567 } 1568 1569 void AwtFrame::_NotifyModalBlocked(void *param) 1570 { 1571 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1572 1573 NotifyModalBlockedStruct *nmbs = (NotifyModalBlockedStruct *)param; 1574 jobject self = nmbs->frame; 1575 jobject peer = nmbs->peer; 1576 jobject blockerPeer = nmbs->blockerPeer; 1577 jboolean blocked = nmbs->blocked; 1578 1579 PDATA pData; 1580 1581 pData = JNI_GET_PDATA(peer); 1582 AwtFrame *f = (AwtFrame *)pData; 1583 1584 // dialog here may be NULL, for example, if the blocker is a native dialog 1585 // however, we need to install/unistall modal hooks anyway 1586 pData = JNI_GET_PDATA(blockerPeer); 1587 AwtDialog *d = (AwtDialog *)pData; 1588 1589 if ((f != NULL) && ::IsWindow(f->GetHWnd())) 1590 { 1591 // get an HWND of the toplevel window this embedded frame is within 1592 HWND fHWnd = f->GetHWnd(); 1593 while (::GetParent(fHWnd) != NULL) { 1594 fHWnd = ::GetParent(fHWnd); 1595 } 1596 // we must get a toplevel hwnd here, however due to some strange 1597 // behaviour of Java Plugin (a bug?) when running in IE at 1598 // this moment the embedded frame hasn't been placed into the 1599 // browser yet and fHWnd is not a toplevel, so we shouldn't install 1600 // the hook here 1601 if ((::GetWindowLong(fHWnd, GWL_STYLE) & WS_CHILD) == 0) { 1602 // if this toplevel is created in another thread, we should install 1603 // the modal hook into it to track window activation and mouse events 1604 DWORD fThread = ::GetWindowThreadProcessId(fHWnd, NULL); 1605 if (fThread != AwtToolkit::GetInstance().MainThread()) { 1606 // check if this thread has been already blocked 1607 BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)fThread); 1608 if (blocked) { 1609 if (blockedThread == NULL) { 1610 blockedThread = new BlockedThreadStruct; 1611 blockedThread->framesCount = 1; 1612 blockedThread->modalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtDialog::ModalFilterProc, 1613 0, fThread); 1614 blockedThread->mouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtDialog::MouseHookProc_NonTT, 1615 0, fThread); 1616 sm_BlockedThreads.put((void *)fThread, blockedThread); 1617 } else { 1618 blockedThread->framesCount++; 1619 } 1620 } else { 1621 // see the comment above: if Java Plugin behaviour when running in IE 1622 // was right, blockedThread would be always not NULL here 1623 if (blockedThread != NULL) { 1624 DASSERT(blockedThread->framesCount > 0); 1625 if ((blockedThread->framesCount) == 1) { 1626 ::UnhookWindowsHookEx(blockedThread->modalHook); 1627 ::UnhookWindowsHookEx(blockedThread->mouseHook); 1628 sm_BlockedThreads.remove((void *)fThread); 1629 delete blockedThread; 1630 } else { 1631 blockedThread->framesCount--; 1632 } 1633 } 1634 } 1635 } 1636 } 1637 } 1638 1639 env->DeleteGlobalRef(self); 1640 env->DeleteGlobalRef(peer); 1641 env->DeleteGlobalRef(blockerPeer); 1642 1643 delete nmbs; 1644 } 1645 1646 /************************************************************************ 1647 * WFramePeer native methods 1648 */ 1649 1650 extern "C" { 1651 1652 /* 1653 * Class: java_awt_Frame 1654 * Method: initIDs 1655 * Signature: ()V 1656 */ 1657 JNIEXPORT void JNICALL 1658 Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls) 1659 { 1660 TRY; 1661 1662 AwtFrame::undecoratedID = env->GetFieldID(cls,"undecorated","Z"); 1663 DASSERT(AwtFrame::undecoratedID != NULL); 1664 1665 CATCH_BAD_ALLOC; 1666 } 1667 1668 /* 1669 * Class: sun_awt_windows_WFramePeer 1670 * Method: initIDs 1671 * Signature: ()V 1672 */ 1673 JNIEXPORT void JNICALL 1674 Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls) 1675 { 1676 TRY; 1677 1678 AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V"); 1679 DASSERT(AwtFrame::setExtendedStateMID); 1680 CHECK_NULL(AwtFrame::setExtendedStateMID); 1681 1682 AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I"); 1683 DASSERT(AwtFrame::getExtendedStateMID); 1684 1685 CATCH_BAD_ALLOC; 1686 } 1687 1688 /* 1689 * Class: sun_awt_windows_WFramePeer 1690 * Method: setState 1691 * Signature: (I)V 1692 */ 1693 JNIEXPORT void JNICALL 1694 Java_sun_awt_windows_WFramePeer_setState(JNIEnv *env, jobject self, 1695 jint state) 1696 { 1697 TRY; 1698 1699 SetStateStruct *sss = new SetStateStruct; 1700 sss->frame = env->NewGlobalRef(self); 1701 sss->state = state; 1702 1703 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetState, sss); 1704 // global ref and sss are deleted in _SetState() 1705 1706 CATCH_BAD_ALLOC; 1707 } 1708 1709 /* 1710 * Class: sun_awt_windows_WFramePeer 1711 * Method: getState 1712 * Signature: ()I 1713 */ 1714 JNIEXPORT jint JNICALL 1715 Java_sun_awt_windows_WFramePeer_getState(JNIEnv *env, jobject self) 1716 { 1717 TRY; 1718 1719 jobject selfGlobalRef = env->NewGlobalRef(self); 1720 1721 return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall( 1722 (void*(*)(void*))AwtFrame::_GetState, 1723 (void *)selfGlobalRef))); 1724 // selfGlobalRef is deleted in _GetState() 1725 1726 CATCH_BAD_ALLOC_RET(java_awt_Frame_NORMAL); 1727 } 1728 1729 1730 /* 1731 * Class: sun_awt_windows_WFramePeer 1732 * Method: setMaximizedBounds 1733 * Signature: (IIII)V 1734 */ 1735 JNIEXPORT void JNICALL 1736 Java_sun_awt_windows_WFramePeer_setMaximizedBounds(JNIEnv *env, jobject self, 1737 jint x, jint y, jint width, jint height) 1738 { 1739 TRY; 1740 1741 SetMaximizedBoundsStruct *smbs = new SetMaximizedBoundsStruct; 1742 smbs->frame = env->NewGlobalRef(self); 1743 smbs->x = x; 1744 smbs->y = y; 1745 smbs->width = width; 1746 smbs->height = height; 1747 1748 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMaximizedBounds, smbs); 1749 // global ref and smbs are deleted in _SetMaximizedBounds() 1750 1751 CATCH_BAD_ALLOC; 1752 } 1753 1754 1755 /* 1756 * Class: sun_awt_windows_WFramePeer 1757 * Method: clearMaximizedBounds 1758 * Signature: ()V 1759 */ 1760 JNIEXPORT void JNICALL 1761 Java_sun_awt_windows_WFramePeer_clearMaximizedBounds(JNIEnv *env, jobject self) 1762 { 1763 TRY; 1764 1765 jobject selfGlobalRef = env->NewGlobalRef(self); 1766 1767 AwtToolkit::GetInstance().SyncCall(AwtFrame::_ClearMaximizedBounds, 1768 (void *)selfGlobalRef); 1769 // selfGlobalRef is deleted in _ClearMaximizedBounds() 1770 1771 CATCH_BAD_ALLOC; 1772 } 1773 1774 1775 /* 1776 * Class: sun_awt_windows_WFramePeer 1777 * Method: setMenuBar0 1778 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V 1779 */ 1780 JNIEXPORT void JNICALL 1781 Java_sun_awt_windows_WFramePeer_setMenuBar0(JNIEnv *env, jobject self, 1782 jobject mbPeer) 1783 { 1784 TRY; 1785 1786 SetMenuBarStruct *smbs = new SetMenuBarStruct; 1787 smbs->frame = env->NewGlobalRef(self); 1788 smbs->menubar = env->NewGlobalRef(mbPeer); 1789 1790 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMenuBar, smbs); 1791 // global refs ans smbs are deleted in _SetMenuBar() 1792 1793 CATCH_BAD_ALLOC; 1794 } 1795 1796 /* 1797 * Class: sun_awt_windows_WFramePeer 1798 * Method: create 1799 * Signature: (Lsun/awt/windows/WComponentPeer;)V 1800 */ 1801 JNIEXPORT void JNICALL 1802 Java_sun_awt_windows_WFramePeer_createAwtFrame(JNIEnv *env, jobject self, 1803 jobject parent) 1804 { 1805 TRY; 1806 1807 AwtToolkit::CreateComponent(self, parent, 1808 (AwtToolkit::ComponentFactory) 1809 AwtFrame::Create); 1810 PDATA pData; 1811 JNI_CHECK_PEER_CREATION_RETURN(self); 1812 1813 CATCH_BAD_ALLOC; 1814 } 1815 1816 /* 1817 * Class: sun_awt_windows_WFramePeer 1818 * Method: getSysMenuHeight 1819 * Signature: ()I 1820 */ 1821 JNIEXPORT jint JNICALL 1822 Java_sun_awt_windows_WFramePeer_getSysMenuHeight(JNIEnv *env, jclass self) 1823 { 1824 TRY; 1825 1826 return ::GetSystemMetrics(SM_CYMENUSIZE); 1827 1828 CATCH_BAD_ALLOC_RET(0); 1829 } 1830 1831 /* 1832 * Class: sun_awt_windows_WFramePeer 1833 * Method: pSetIMMOption 1834 * Signature: (Ljava/lang/String;)V 1835 */ 1836 JNIEXPORT void JNICALL 1837 Java_sun_awt_windows_WFramePeer_pSetIMMOption(JNIEnv *env, jobject self, 1838 jstring option) 1839 { 1840 TRY; 1841 1842 SetIMMOptionStruct *sios = new SetIMMOptionStruct; 1843 sios->frame = env->NewGlobalRef(self); 1844 sios->option = (jstring)env->NewGlobalRef(option); 1845 1846 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetIMMOption, sios); 1847 // global refs and sios are deleted in _SetIMMOption() 1848 1849 CATCH_BAD_ALLOC; 1850 } 1851 1852 } /* extern "C" */ 1853 1854 1855 /************************************************************************ 1856 * WEmbeddedFrame native methods 1857 */ 1858 1859 extern "C" { 1860 1861 /* 1862 * Class: sun_awt_windows_WFramePeer 1863 * Method: initIDs 1864 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V 1865 */ 1866 JNIEXPORT void JNICALL 1867 Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls) 1868 { 1869 TRY; 1870 1871 AwtFrame::handleID = env->GetFieldID(cls, "handle", "J"); 1872 DASSERT(AwtFrame::handleID != NULL); 1873 CHECK_NULL(AwtFrame::handleID); 1874 1875 AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V"); 1876 DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL); 1877 CHECK_NULL(AwtFrame::activateEmbeddingTopLevelMID); 1878 1879 AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z"); 1880 DASSERT(AwtFrame::isEmbeddedInIEID != NULL); 1881 1882 CATCH_BAD_ALLOC; 1883 } 1884 1885 JNIEXPORT void JNICALL 1886 Java_sun_awt_windows_WEmbeddedFrame_notifyModalBlockedImpl(JNIEnv *env, 1887 jobject self, 1888 jobject peer, 1889 jobject blockerPeer, 1890 jboolean blocked) 1891 { 1892 TRY; 1893 1894 NotifyModalBlockedStruct *nmbs = new NotifyModalBlockedStruct; 1895 nmbs->frame = env->NewGlobalRef(self); 1896 nmbs->peer = env->NewGlobalRef(peer); 1897 nmbs->blockerPeer = env->NewGlobalRef(blockerPeer); 1898 nmbs->blocked = blocked; 1899 1900 AwtToolkit::GetInstance().SyncCall(AwtFrame::_NotifyModalBlocked, nmbs); 1901 // global refs and nmbs are deleted in _NotifyModalBlocked() 1902 1903 CATCH_BAD_ALLOC; 1904 } 1905 1906 } /* extern "C" */ 1907 1908 1909 /************************************************************************ 1910 * WEmbeddedFramePeer native methods 1911 */ 1912 1913 extern "C" { 1914 1915 JNIEXPORT void JNICALL 1916 Java_sun_awt_windows_WEmbeddedFramePeer_create(JNIEnv *env, jobject self, 1917 jobject parent) 1918 { 1919 TRY; 1920 1921 JNI_CHECK_NULL_RETURN(self, "peer"); 1922 AwtToolkit::CreateComponent(self, parent, 1923 (AwtToolkit::ComponentFactory) 1924 AwtFrame::Create); 1925 PDATA pData; 1926 JNI_CHECK_PEER_CREATION_RETURN(self); 1927 1928 CATCH_BAD_ALLOC; 1929 } 1930 1931 JNIEXPORT jobject JNICALL 1932 Java_sun_awt_windows_WEmbeddedFramePeer_getBoundsPrivate(JNIEnv *env, jobject self) 1933 { 1934 TRY; 1935 1936 jobject result = (jobject)AwtToolkit::GetInstance().SyncCall( 1937 (void *(*)(void *))AwtFrame::_GetBoundsPrivate, 1938 env->NewGlobalRef(self)); 1939 // global ref is deleted in _GetBoundsPrivate 1940 1941 if (result != NULL) 1942 { 1943 jobject resultLocalRef = env->NewLocalRef(result); 1944 env->DeleteGlobalRef(result); 1945 return resultLocalRef; 1946 } 1947 else 1948 { 1949 return NULL; 1950 } 1951 1952 CATCH_BAD_ALLOC_RET(NULL); 1953 } 1954 1955 JNIEXPORT void JNICALL 1956 Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate) 1957 { 1958 TRY; 1959 1960 SynthesizeWmActivateStruct *sas = new SynthesizeWmActivateStruct; 1961 sas->frame = env->NewGlobalRef(self); 1962 sas->doActivate = doActivate; 1963 1964 /* 1965 * WARNING: invoking this function without synchronization by m_Sync CriticalSection. 1966 * Taking this lock results in a deadlock. 1967 */ 1968 AwtToolkit::GetInstance().InvokeFunction(AwtFrame::_SynthesizeWmActivate, sas); 1969 // global ref and sas are deleted in _SynthesizeWmActivate() 1970 1971 CATCH_BAD_ALLOC; 1972 } 1973 1974 } /* extern "C" */ 1975 1976 static bool SetFocusToPluginControl(HWND hwndPlugin) 1977 { 1978 HWND hwndFocus = ::GetFocus(); 1979 1980 if (hwndFocus == hwndPlugin) { 1981 return false; 1982 } 1983 1984 ::SetFocus(hwndPlugin); 1985 DWORD dwError = ::GetLastError(); 1986 if (dwError != ERROR_SUCCESS) { 1987 // If direct call failed, use a special message to set focus 1988 return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0); 1989 } 1990 return true; 1991 }