1 /*
   2  * Copyright (c) 1996, 2020, 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                 HWND oHWnd = parent->GetOverriddenHWnd();
 173                 hwndParent = oHWnd ? oHWnd : parent->GetHWnd();
 174             }
 175         }
 176 
 177         frame = new AwtFrame();
 178 
 179         {
 180             /*
 181              * A variation on Netscape's hack for embedded frames: the client
 182              * area of the browser is a Java Frame for parenting purposes, but
 183              * really a Windows child window
 184              */
 185             BOOL isEmbeddedInstance = FALSE;
 186             BOOL isEmbedded = FALSE;
 187             cls = env->FindClass("sun/awt/EmbeddedFrame");
 188 
 189             if (cls) {
 190                 isEmbeddedInstance = env->IsInstanceOf(target, cls);
 191             } else {
 192                 throw std::bad_alloc();
 193             }
 194             INT_PTR handle;
 195             if (isEmbeddedInstance) {
 196                 handle = static_cast<INT_PTR>(env->GetLongField(target, AwtFrame::handleID));
 197                 if (handle != 0) {
 198                     isEmbedded = TRUE;
 199                 }
 200             }
 201             frame->m_isEmbedded = isEmbedded;
 202 
 203             BOOL isLightweight = FALSE;
 204             cls = env->FindClass("sun/awt/LightweightFrame");
 205             if (cls) {
 206                 isLightweight = env->IsInstanceOf(target, cls);
 207             } else {
 208                 throw std::bad_alloc();
 209             }
 210             frame->m_isLightweight = isLightweight;
 211 
 212             if (isEmbedded) {
 213                 hwndParent = (HWND)handle;
 214 
 215                 // JDK-8056915: Handle focus communication between plugin and frame
 216                 frame->m_isEmbeddedInIE = IsEmbeddedInIE(hwndParent);
 217                 if (frame->m_isEmbeddedInIE) {
 218                     env->SetBooleanField(target, isEmbeddedInIEID, JNI_TRUE);
 219                 }
 220 
 221                 RECT rect;
 222                 ::GetClientRect(hwndParent, &rect);
 223                 //Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6
 224                 frame->m_isUndecorated = true;
 225                 /*
 226                  * Fix for BugTraq ID 4337754.
 227                  * Initialize m_peerObject before the first call
 228                  * to AwtFrame::GetClassName().
 229                  */
 230                 frame->m_peerObject = env->NewGlobalRef(self);
 231                 frame->RegisterClass();
 232                 DWORD exStyle = WS_EX_NOPARENTNOTIFY;
 233 
 234                 if (GetRTL()) {
 235                     exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
 236                     if (GetRTLReadingOrder())
 237                         exStyle |= WS_EX_RTLREADING;
 238                 }
 239 
 240                 frame->m_hwnd = ::CreateWindowEx(exStyle,
 241                                                  frame->GetClassName(), TEXT(""),
 242                                                  WS_CHILD | WS_CLIPCHILDREN,
 243                                                  0, 0,
 244                                                  rect.right, rect.bottom,
 245                                                  hwndParent, NULL,
 246                                                  AwtToolkit::GetInstance().GetModuleHandle(),
 247                                                  NULL);
 248                 frame->LinkObjects(env, self);
 249                 frame->SubclassHWND();
 250 
 251                 // Update target's dimensions to reflect this embedded window.
 252                 ::GetClientRect(frame->m_hwnd, &rect);
 253                 ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
 254 
 255                 env->SetIntField(target, AwtComponent::xID, rect.left);
 256                 env->SetIntField(target, AwtComponent::yID, rect.top);
 257                 env->SetIntField(target, AwtComponent::widthID,
 258                                  rect.right-rect.left);
 259                 env->SetIntField(target, AwtComponent::heightID,
 260                                  rect.bottom-rect.top);
 261                 frame->InitPeerGraphicsConfig(env, self);
 262                 AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
 263             } else if (isLightweight) {
 264                 frame->m_isUndecorated = true;
 265                 frame->m_peerObject = env->NewGlobalRef(self);
 266                 frame->RegisterClass();
 267 
 268                 DWORD exStyle = 0;
 269                 DWORD style = WS_POPUP;
 270 
 271                 frame->CreateHWnd(env, L"",
 272                                   style,
 273                                   exStyle,
 274                                   0, 0, 0, 0,
 275                                   0,
 276                                   NULL,
 277                                   ::GetSysColor(COLOR_WINDOWTEXT),
 278                                   ::GetSysColor(COLOR_WINDOWFRAME),
 279                                   self);
 280             } else {
 281                 jint state = env->CallIntMethod(self, AwtFrame::getExtendedStateMID);
 282                 DWORD exStyle;
 283                 DWORD style;
 284 
 285                // for input method windows, use minimal decorations
 286                inputMethodWindowCls = env->FindClass("sun/awt/im/InputMethodWindow");
 287                if (inputMethodWindowCls == NULL) {
 288                    throw std::bad_alloc();
 289                }
 290 
 291                if (env->IsInstanceOf(target, inputMethodWindowCls)) {
 292                    //for below-the-spot composition window, use no decoration
 293                    if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE){
 294                         exStyle = 0;
 295                         style = WS_POPUP|WS_CLIPCHILDREN;
 296                         frame->m_isUndecorated = TRUE;
 297                    } else {
 298                         exStyle = WS_EX_PALETTEWINDOW;
 299                         style = WS_CLIPCHILDREN;
 300                    }
 301                    frame->m_isInputMethodWindow = TRUE;
 302                 } else if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE) {
 303                     exStyle = 0;
 304                     style = WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN |
 305                         WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
 306                   if (state & java_awt_Frame_ICONIFIED) {
 307                       frame->setIconic(TRUE);
 308                   }
 309                     frame->m_isUndecorated = TRUE;
 310                 } else {
 311                     exStyle = WS_EX_WINDOWEDGE;
 312                     style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
 313                   if (state & java_awt_Frame_ICONIFIED) {
 314                       frame->setIconic(TRUE);
 315                   }
 316                 }
 317 
 318                 if (GetRTL()) {
 319                     exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
 320                     if (GetRTLReadingOrder())
 321                         exStyle |= WS_EX_RTLREADING;
 322                 }
 323 
 324                 jint x = env->GetIntField(target, AwtComponent::xID);
 325                 jint y = env->GetIntField(target, AwtComponent::yID);
 326                 jint width = env->GetIntField(target, AwtComponent::widthID);
 327                 jint height = env->GetIntField(target, AwtComponent::heightID);
 328 
 329                 frame->CreateHWnd(env, L"",
 330                                   style,
 331                                   exStyle,
 332                                   x, y, width, height,
 333                                   hwndParent,
 334                                   NULL,
 335                                   ::GetSysColor(COLOR_WINDOWTEXT),
 336                                   ::GetSysColor(COLOR_WINDOWFRAME),
 337                                   self);
 338                 frame->RecalcNonClient();
 339             }
 340         }
 341     } catch (...) {
 342         env->DeleteLocalRef(target);
 343         env->DeleteLocalRef(cls);
 344         env->DeleteLocalRef(inputMethodWindowCls);
 345         throw;
 346     }
 347 
 348 done:
 349     env->DeleteLocalRef(target);
 350     env->DeleteLocalRef(cls);
 351     env->DeleteLocalRef(inputMethodWindowCls);
 352 
 353     return frame;
 354 }
 355 
 356 /*
 357  * Returns true if the frame is embedded into Internet Explorer.
 358  * The function checks the class name of the parent window of the embedded frame.
 359  */
 360 BOOL AwtFrame::IsEmbeddedInIE(HWND hwndParent)
 361 {
 362     const char *pluginClass = "Java Plug-in Control Window";
 363     #define PARENT_CLASS_BUFFER_SIZE 64
 364     char parentClass[PARENT_CLASS_BUFFER_SIZE];
 365 
 366     return (::GetClassNameA(hwndParent, parentClass, PARENT_CLASS_BUFFER_SIZE) > 0)
 367            && (strncmp(parentClass, pluginClass, PARENT_CLASS_BUFFER_SIZE) == 0);
 368 }
 369 
 370 
 371 LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr)
 372 {
 373     LRESULT retValue = 0L;
 374 
 375     AwtComponent *focusOwner = NULL;
 376     AwtComponent *imeTargetComponent = NULL;
 377 
 378     // IME and input language related messages need to be sent to a window
 379     // which has the Java input focus
 380     switch (message) {
 381         case WM_IME_STARTCOMPOSITION:
 382         case WM_IME_ENDCOMPOSITION:
 383         case WM_IME_COMPOSITION:
 384         case WM_IME_SETCONTEXT:
 385         case WM_IME_NOTIFY:
 386         case WM_IME_CONTROL:
 387         case WM_IME_COMPOSITIONFULL:
 388         case WM_IME_SELECT:
 389         case WM_IME_CHAR:
 390         case WM_IME_REQUEST:
 391         case WM_IME_KEYDOWN:
 392         case WM_IME_KEYUP:
 393         case WM_INPUTLANGCHANGEREQUEST:
 394         case WM_INPUTLANGCHANGE:
 395             if (message == WM_IME_STARTCOMPOSITION) {
 396                 SetImeTargetComponent(sm_focusOwner);
 397             }
 398             imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent());
 399             if (imeTargetComponent != NULL &&
 400                 imeTargetComponent != this) // avoid recursive calls
 401             {
 402                 retValue = imeTargetComponent->WindowProc(message, wParam, lParam);
 403                 mr = mrConsume;
 404             }
 405             if (message == WM_IME_ENDCOMPOSITION) {
 406                 SetImeTargetComponent(NULL);
 407             }
 408             break;
 409         case WM_SETFOCUS:
 410             if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
 411 
 412             if (!sm_suppressFocusAndActivation) {
 413                 if (IsLightweightFrame() || IsEmbeddedFrame()) {
 414                     AwtSetActiveWindow();
 415                 }
 416             }
 417             mr = mrConsume;
 418             break;
 419         case WM_KILLFOCUS:
 420             if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
 421 
 422             if (!sm_suppressFocusAndActivation) {
 423                 if (IsLightweightFrame() || IsEmbeddedFrame()) {
 424                     HWND oppositeToplevelHWnd = AwtComponent::GetTopLevelParentForWindow((HWND)wParam);
 425                     if (oppositeToplevelHWnd != AwtComponent::GetFocusedWindow()) {
 426                         AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL);
 427                     }
 428                 }
 429             } else if (sm_restoreFocusAndActivation) {
 430                 if (AwtComponent::GetFocusedWindow() != NULL) {
 431                     AwtWindow *focusedWindow = (AwtWindow*)GetComponent(AwtComponent::GetFocusedWindow());
 432                     if (focusedWindow != NULL) {
 433                         // Will just silently restore native focus & activation.
 434                         focusedWindow->AwtSetActiveWindow();
 435                     }
 436                 }
 437             }
 438             mr = mrConsume;
 439             break;
 440         case 0x0127: // WM_CHANGEUISTATE
 441         case 0x0128: // WM_UPDATEUISTATE
 442             mr = mrConsume;
 443             break;
 444     }
 445 
 446     return retValue;
 447 }
 448 
 449 LRESULT AwtFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
 450 {
 451     MsgRouting mr = mrDoDefault;
 452     LRESULT retValue = 0L;
 453 
 454     retValue = ProxyWindowProc(message, wParam, lParam, mr);
 455 
 456     if (mr != mrConsume) {
 457         retValue = AwtWindow::WindowProc(message, wParam, lParam);
 458     }
 459     return retValue;
 460 }
 461 
 462 MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status)
 463 {
 464     /*
 465      * Fix for 6492970.
 466      * When a non-focusable toplevel is shown alone the Java process
 467      * is not foreground. If one shows another (focusable) toplevel
 468      * the native platform not always makes it foreground (see the CR).
 469      * Even worse, sometimes it sends the newly shown toplevel WM_ACTIVATE
 470      * message. This breaks Java focus. To workaround the problem we
 471      * set the toplevel being shown foreground programmatically.
 472      * The fix is localized to non-foreground process case only.
 473      * (See also: 6599270)
 474      */
 475     if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
 476         HWND fgHWnd = ::GetForegroundWindow();
 477         if (fgHWnd != NULL) {
 478             DWORD fgProcessID;
 479             ::GetWindowThreadProcessId(fgHWnd, &fgProcessID);
 480 
 481             if (fgProcessID != ::GetCurrentProcessId()) {
 482                 AwtWindow* window = (AwtWindow*)GetComponent(GetHWnd());
 483 
 484                 if (window != NULL &&
 485                     window->IsFocusableWindow() &&
 486                     window->IsAutoRequestFocus() &&
 487                     !::IsWindowVisible(GetHWnd()) && // the window is really showing
 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         HWND hWnd = GetHWnd();
 699         if (hWnd != NULL && ::IsWindowVisible(hWnd)) {
 700             LONG style = GetStyle();
 701             DASSERT(style & WS_MAXIMIZE);
 702             style ^= WS_MAXIMIZE;
 703             SetStyle(style);
 704         }
 705     }
 706 
 707     AwtWindow::Reshape(x, y, width, height);
 708 }
 709 
 710 
 711 /* Show the frame in it's current state */
 712 void
 713 AwtFrame::Show()
 714 {
 715     m_visible = true;
 716     HWND hwnd = GetHWnd();
 717     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 718 
 719     if (IsLightweightFrame()) {
 720         return;
 721     }
 722 
 723     DTRACE_PRINTLN3("AwtFrame::Show:%s%s%s",
 724                   m_iconic ? " iconic" : "",
 725                   m_zoomed ? " zoomed" : "",
 726                   m_iconic || m_zoomed ? "" : " normal");
 727 
 728     BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID);
 729 
 730     if (locationByPlatform) {
 731          moveToDefaultLocation();
 732     }
 733     EnableTranslucency(TRUE);
 734 
 735     BOOL autoRequestFocus = IsAutoRequestFocus();
 736 
 737     if (m_iconic) {
 738         if (m_zoomed) {
 739             // This whole function could probably be rewritten to use
 740             // ::SetWindowPlacement but MS docs doesn't tell if
 741             // ::SetWindowPlacement is a proper superset of
 742             // ::ShowWindow.  So let's be conservative and only use it
 743             // here, where we really do need it.
 744             DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED");
 745             WINDOWPLACEMENT wp;
 746             ::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
 747             wp.length = sizeof(WINDOWPLACEMENT);
 748             ::GetWindowPlacement(hwnd, &wp);
 749             if (!IsFocusableWindow() || !autoRequestFocus) {
 750                 wp.showCmd = SW_SHOWMINNOACTIVE;
 751             } else {
 752                 wp.showCmd = SW_SHOWMINIMIZED;
 753             }
 754             wp.flags |= WPF_RESTORETOMAXIMIZED;
 755             ::SetWindowPlacement(hwnd, &wp);
 756         }
 757         else {
 758             DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED)");
 759             if (!IsFocusableWindow() || !autoRequestFocus) {
 760                 ::ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
 761             } else {
 762                 ::ShowWindow(hwnd, SW_SHOWMINIMIZED);
 763             }
 764         }
 765     }
 766     else if (m_zoomed) {
 767         DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMAXIMIZED)");
 768         if (!autoRequestFocus) {
 769 
 770             m_filterFocusAndActivation = TRUE;
 771             ::ShowWindow(hwnd, SW_MAXIMIZE);
 772             m_filterFocusAndActivation = FALSE;
 773 
 774         } else if (!IsFocusableWindow()) {
 775             ::ShowWindow(hwnd, SW_MAXIMIZE);
 776         } else {
 777             ::ShowWindow(hwnd, SW_SHOWMAXIMIZED);
 778         }
 779     }
 780     else if (m_isInputMethodWindow) {
 781         // Don't activate input methow window
 782         DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWNA)");
 783         ::ShowWindow(hwnd, SW_SHOWNA);
 784 
 785         // After the input method window shown, we have to adjust the
 786         // IME candidate window position. Here is why.
 787         // Usually, when IMM opens the candidate window, it sends WM_IME_NOTIFY w/
 788         // IMN_OPENCANDIDATE message to the awt component window. The
 789         // awt component makes a Java call to acquire the text position
 790         // in order to show the candidate window just below the input method window.
 791         // However, by the time it acquires the position, the input method window
 792         // hasn't been displayed yet, the position returned is just below
 793         // the composed text and when the input method window is shown, it
 794         // will hide part of the candidate list. To fix this, we have to
 795         // adjust the candidate window position after the input method window
 796         // is shown. See bug 5012944.
 797         AdjustCandidateWindowPos();
 798     }
 799     else {
 800         // Nor iconic, nor zoomed (handled above) - so use SW_RESTORE
 801         // to show in "normal" state regardless of whatever stale
 802         // state might the invisible window still has.
 803         DTRACE_PRINTLN("AwtFrame::Show(SW_RESTORE)");
 804         if (!IsFocusableWindow() || !autoRequestFocus) {
 805             ::ShowWindow(hwnd, SW_SHOWNOACTIVATE);
 806         } else {
 807             ::ShowWindow(hwnd, SW_RESTORE);
 808         }
 809     }
 810 }
 811 
 812 void
 813 AwtFrame::SendWindowStateEvent(int oldState, int newState)
 814 {
 815     SendWindowEvent(java_awt_event_WindowEvent_WINDOW_STATE_CHANGED,
 816                     NULL, oldState, newState);
 817 }
 818 
 819 void
 820 AwtFrame::ClearMaximizedBounds()
 821 {
 822     m_maxBoundsSet = FALSE;
 823 }
 824 
 825 void AwtFrame::AdjustCandidateWindowPos()
 826 {
 827     // This method should only be called if the current frame
 828     // is the input method window frame.
 829     if (!m_isInputMethodWindow) {
 830         return;
 831     }
 832 
 833     RECT inputWinRec, focusWinRec;
 834     AwtComponent *comp = AwtComponent::GetComponent(AwtComponent::sm_focusOwner);
 835     if (comp == NULL) {
 836         return;
 837     }
 838 
 839     ::GetWindowRect(GetHWnd(), &inputWinRec);
 840     ::GetWindowRect(sm_focusOwner, &focusWinRec);
 841 
 842     LPARAM candType = comp->GetCandidateType();
 843     HWND defaultIMEWnd = ::ImmGetDefaultIMEWnd(GetHWnd());
 844     if (defaultIMEWnd == NULL) {
 845         return;
 846     }
 847     UINT bits = 1;
 848     // adjusts the candidate window position
 849     for (int iCandType = 0; iCandType < 32; iCandType++, bits<<=1) {
 850         if (candType & bits) {
 851             CANDIDATEFORM cf;
 852             cf.dwIndex = iCandType;
 853             cf.dwStyle = CFS_CANDIDATEPOS;
 854             // Since the coordinates are relative to the containing window,
 855             // we have to calculate the coordinates as below.
 856             cf.ptCurrentPos.x = inputWinRec.left - focusWinRec.left;
 857             cf.ptCurrentPos.y = inputWinRec.bottom - focusWinRec.top;
 858 
 859             // sends IMC_SETCANDIDATEPOS to IMM to move the candidate window.
 860             ::SendMessage(defaultIMEWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, (LPARAM)&cf);
 861         }
 862     }
 863 }
 864 
 865 void
 866 AwtFrame::SetMaximizedBounds(int x, int y, int w, int h)
 867 {
 868     m_maxPos.x  = x;
 869     m_maxPos.y  = y;
 870     m_maxSize.x = w;
 871     m_maxSize.y = h;
 872     m_maxBoundsSet = TRUE;
 873 }
 874 
 875 MsgRouting AwtFrame::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
 876 {
 877     //Firstly call AwtWindow's function
 878     MsgRouting r = AwtWindow::WmGetMinMaxInfo(lpmmi);
 879 
 880     //Then replace maxPos & maxSize if necessary
 881     if (!m_maxBoundsSet) {
 882         return r;
 883     }
 884 
 885     if (m_maxPos.x != java_lang_Integer_MAX_VALUE)
 886         lpmmi->ptMaxPosition.x = m_maxPos.x;
 887     if (m_maxPos.y != java_lang_Integer_MAX_VALUE)
 888         lpmmi->ptMaxPosition.y = m_maxPos.y;
 889     if (m_maxSize.x != java_lang_Integer_MAX_VALUE)
 890         lpmmi->ptMaxSize.x = m_maxSize.x;
 891     if (m_maxSize.y != java_lang_Integer_MAX_VALUE)
 892         lpmmi->ptMaxSize.y = m_maxSize.y;
 893     return mrConsume;
 894 }
 895 
 896 MsgRouting AwtFrame::WmWindowPosChanging(LPARAM windowPos) {
 897     if (::IsZoomed(GetHWnd()) && m_maxBoundsSet) {
 898         // Limits the size of the maximized window, effectively cuts the
 899         // adjustments added by the window manager
 900         WINDOWPOS *wp = (WINDOWPOS *) windowPos;
 901         if (m_maxSize.x < java_lang_Integer_MAX_VALUE && wp->cx > m_maxSize.x) {
 902             wp->cx = m_maxSize.x;
 903         }
 904         if (m_maxSize.y < java_lang_Integer_MAX_VALUE && wp->cy > m_maxSize.y) {
 905             wp->cy = m_maxSize.y;
 906         }
 907     }
 908     return AwtWindow::WmWindowPosChanging(windowPos);
 909 }
 910 
 911 MsgRouting AwtFrame::WmSize(UINT type, int w, int h)
 912 {
 913     currentWmSizeState = type;
 914     if (currentWmSizeState == SIZE_MINIMIZED) {
 915         UpdateSecurityWarningVisibility();
 916     }
 917 
 918     if (m_ignoreWmSize) {
 919         return mrDoDefault;
 920     }
 921 
 922     DTRACE_PRINTLN6("AwtFrame::WmSize: %dx%d,%s visible, state%s%s%s",
 923                   w, h,
 924                   ::IsWindowVisible(GetHWnd()) ? "" : " not",
 925                   m_iconic ? " iconic" : "",
 926                   m_zoomed ? " zoomed" : "",
 927                   m_iconic || m_zoomed ? "" : " normal");
 928 
 929     BOOL iconify = type == SIZE_MINIMIZED;
 930 
 931     // Note that zoom may be set to TRUE in several cases:
 932     //    1. type == SIZE_MAXIMIZED means that either the user or
 933     //       the developer (via setExtendedState(MAXIMIZED_BOTH)
 934     //       maximizes the frame.
 935     //    2. type == SIZE_MINIMIZED && isZoomed() means that a maximized
 936     //       frame is to be minimized. If the user minimizes a maximized
 937     //       frame, we need to keep the zoomed property TRUE. However,
 938     //       if the developer calls setExtendedState(ICONIFIED), i.e.
 939     //       w/o combining the ICONIFIED state with the MAXIMIZED state,
 940     //       we MUST RESET the zoomed property.
 941     //       The flag m_forceResetZoomed identifies the latter case.
 942     BOOL zoom =
 943         (
 944          type == SIZE_MAXIMIZED
 945          ||
 946          (type == SIZE_MINIMIZED && isZoomed())
 947         )
 948         && !m_forceResetZoomed;
 949 
 950     // Set the new state and send appropriate Java event
 951     jint oldState = java_awt_Frame_NORMAL;
 952     if (isIconic()) {
 953         oldState |= java_awt_Frame_ICONIFIED;
 954     }
 955     if (isZoomed()) {
 956         oldState |= java_awt_Frame_MAXIMIZED_BOTH;
 957     }
 958 
 959     jint newState = java_awt_Frame_NORMAL;
 960     if (iconify) {
 961         newState |= java_awt_Frame_ICONIFIED;
 962     }
 963     if (zoom) {
 964         newState |= java_awt_Frame_MAXIMIZED_BOTH;
 965     }
 966 
 967     setIconic(iconify);
 968     setZoomed(zoom);
 969 
 970     jint changed = oldState ^ newState;
 971     if (changed != 0) {
 972         DTRACE_PRINTLN2("AwtFrame::WmSize: reporting state change %x -> %x",
 973                 oldState, newState);
 974 
 975         // sync target with peer
 976         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 977         env->CallVoidMethod(GetPeer(env), AwtFrame::setExtendedStateMID, newState);
 978 
 979         // report (de)iconification to old clients
 980         if (changed & java_awt_Frame_ICONIFIED) {
 981             if (newState & java_awt_Frame_ICONIFIED) {
 982                 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_ICONIFIED);
 983             } else {
 984                 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_DEICONIFIED);
 985             }
 986         }
 987 
 988         // New (since 1.4) state change event
 989         SendWindowStateEvent(oldState, newState);
 990     }
 991 
 992     // If window is in iconic state, do not send COMPONENT_RESIZED event
 993     if (isIconic()) {
 994         return mrDoDefault;
 995     }
 996 
 997     return AwtWindow::WmSize(type, w, h);
 998 }
 999 
1000 MsgRouting AwtFrame::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
1001 {
1002     jint type;
1003 
1004     if (nState != WA_INACTIVE) {
1005         if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())) ||
1006             CheckActivateActualFocusedWindow(opposite))
1007         {
1008             return mrConsume;
1009         }
1010         type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
1011         AwtComponent::SetFocusedWindow(GetHWnd());
1012 
1013     } else {
1014         if (::IsWindow(AwtWindow::GetModalBlocker(opposite))) {
1015             return mrConsume;
1016         } else {
1017             // If deactivation happens because of press on grabbing
1018             // window - this is nonsense, since grabbing window is
1019             // assumed to have focus and watch for deactivation.  But
1020             // this can happen - if grabbing window is proxied Window,
1021             // with Frame keeping real focus for it.
1022             if (m_grabbedWindow != NULL) {
1023                 if (m_grabbedWindow->GetHWnd() == opposite) {
1024                     // Do nothing
1025                 } else {
1026                     // Normally, we would rather check that this ==
1027                     // grabbed window, and focus is leaving it -
1028                     // ungrab.  But since we know about proxied
1029                     // windows, we simply assume this is one of the
1030                     // known cases.
1031                     if (!m_grabbedWindow->IsOneOfOwnersOf((AwtWindow*)AwtComponent::GetComponent(opposite))) {
1032                         m_grabbedWindow->Ungrab();
1033                     }
1034                 }
1035             }
1036             CheckRetainActualFocusedWindow(opposite);
1037 
1038             type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
1039             AwtComponent::SetFocusedWindow(NULL);
1040             sm_focusOwner = NULL;
1041         }
1042     }
1043 
1044     SendWindowEvent(type, opposite);
1045     return mrConsume;
1046 }
1047 
1048 BOOL AwtFrame::CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd)
1049 {
1050     if (m_actualFocusedWindow != NULL) {
1051         HWND hwnd = m_actualFocusedWindow->GetHWnd();
1052         if (hwnd != NULL && ::IsWindowVisible(hwnd)) {
1053             SynthesizeWmActivate(TRUE, hwnd, deactivatedOpositeHWnd);
1054             return TRUE;
1055         }
1056         m_actualFocusedWindow = NULL;
1057     }
1058     return FALSE;
1059 }
1060 
1061 void AwtFrame::CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd)
1062 {
1063     // If actual focused window is not this Frame
1064     if (AwtComponent::GetFocusedWindow() != GetHWnd()) {
1065         // Make sure the actual focused window is an owned window of this frame
1066         AwtWindow *focusedWindow = (AwtWindow *)AwtComponent::GetComponent(AwtComponent::GetFocusedWindow());
1067         if (focusedWindow != NULL && focusedWindow->GetOwningFrameOrDialog() == this) {
1068 
1069             // Check that the opposite window is not this frame, nor an owned window of this frame
1070             if (activatedOpositeHWnd != NULL) {
1071                 AwtWindow *oppositeWindow = (AwtWindow *)AwtComponent::GetComponent(activatedOpositeHWnd);
1072                 if (oppositeWindow && oppositeWindow != this &&
1073                     oppositeWindow->GetOwningFrameOrDialog() != this)
1074                 {
1075                     m_actualFocusedWindow = focusedWindow;
1076                 }
1077             } else {
1078                  m_actualFocusedWindow = focusedWindow;
1079             }
1080         }
1081     }
1082 }
1083 
1084 BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
1085 {
1086     if (hittest == HTCLIENT) {
1087         // Don't let the actualFocusedWindow to steal focus if:
1088         // a) the frame is clicked in its client area;
1089         // b) focus is requested to some of the frame's child.
1090         m_actualFocusedWindow = NULL;
1091     }
1092     if (IsLightweightFrame()) {
1093         return TRUE;
1094     }
1095     if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) {
1096         HWND hwndProxy = GetProxyFocusOwner();
1097         // Do nothing if this frame is focused already
1098         if (::GetFocus() != hwndProxy) {
1099             // Fix for JDK-8056915:
1100             // If window activated with mouse, set focus to plugin control window
1101             // first to preserve focus owner inside browser window
1102             if (SetFocusToPluginControl(::GetParent(GetHWnd()))) {
1103                 return TRUE;
1104             }
1105             // Plugin control window is already focused, so do normal processing
1106         }
1107     }
1108     return AwtWindow::AwtSetActiveWindow(isMouseEventCause);
1109 }
1110 
1111 MsgRouting AwtFrame::WmEnterMenuLoop(BOOL isTrackPopupMenu)
1112 {
1113     if ( !isTrackPopupMenu ) {
1114         m_isMenuDropped = TRUE;
1115     }
1116     return mrDoDefault;
1117 }
1118 
1119 MsgRouting AwtFrame::WmExitMenuLoop(BOOL isTrackPopupMenu)
1120 {
1121     if ( !isTrackPopupMenu ) {
1122         m_isMenuDropped = FALSE;
1123     }
1124     return mrDoDefault;
1125 }
1126 
1127 AwtMenuBar* AwtFrame::GetMenuBar()
1128 {
1129     return menuBar;
1130 }
1131 
1132 void AwtFrame::SetMenuBar(AwtMenuBar* mb)
1133 {
1134     if (menuBar) {
1135         menuBar->SetFrame(NULL);
1136     }
1137     menuBar = mb;
1138     if (mb == NULL) {
1139         // Remove existing menu bar, if any.
1140         ::SetMenu(GetHWnd(), NULL);
1141     } else {
1142         AwtFrame* oldFrame = menuBar->GetFrame();
1143         if (oldFrame && oldFrame != this) {
1144             oldFrame->SetMenuBar(NULL);
1145         }
1146         menuBar->SetFrame(this);
1147         if (menuBar->GetHMenu() != NULL) {
1148             ::SetMenu(GetHWnd(), menuBar->GetHMenu());
1149         }
1150     }
1151 }
1152 
1153 MsgRouting AwtFrame::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo)
1154 {
1155     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1156 
1157     // if the item to be redrawn is the menu bar, then do it
1158     AwtMenuBar* awtMenubar = GetMenuBar();
1159     if (drawInfo.CtlType == ODT_MENU && (awtMenubar != NULL) &&
1160         (::GetMenu( GetHWnd() ) == (HMENU)drawInfo.hwndItem) )
1161         {
1162                 awtMenubar->DrawItem(drawInfo);
1163                 return mrConsume;
1164     }
1165 
1166         return AwtComponent::WmDrawItem(ctrlId, drawInfo);
1167 }
1168 
1169 MsgRouting AwtFrame::WmMeasureItem(UINT ctrlId, MEASUREITEMSTRUCT& measureInfo)
1170 {
1171         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1172         AwtMenuBar* awtMenubar = GetMenuBar();
1173         if ((measureInfo.CtlType == ODT_MENU) && (awtMenubar != NULL))
1174         {
1175                 // AwtMenu instance is stored in itemData. Use it to check if this
1176                 // menu is the menu bar.
1177                 AwtMenu * pMenu = (AwtMenu *) measureInfo.itemData;
1178                 DASSERT(pMenu != NULL);
1179                 if ( pMenu == awtMenubar )
1180                 {
1181                         HWND hWnd = GetHWnd();
1182                         HDC hDC = ::GetDC(hWnd);
1183                         DASSERT(hDC != NULL);
1184                         awtMenubar->MeasureItem(hDC, measureInfo);
1185                         VERIFY(::ReleaseDC(hWnd, hDC));
1186                         return mrConsume;
1187                 }
1188         }
1189 
1190         return AwtComponent::WmMeasureItem(ctrlId, measureInfo);
1191 }
1192 
1193 MsgRouting AwtFrame::WmGetIcon(WPARAM iconType, LRESULT& retVal)
1194 {
1195     //Workaround windows bug:
1196     //when reseting from specific icon to class icon
1197     //taskbar is not updated
1198     if (iconType <= 2 /*ICON_SMALL2*/) {
1199         retVal = (LRESULT)GetEffectiveIcon(iconType);
1200         return mrConsume;
1201     } else {
1202         return mrDoDefault;
1203     }
1204 }
1205 
1206 void AwtFrame::DoUpdateIcon()
1207 {
1208     //Workaround windows bug:
1209     //when reseting from specific icon to class icon
1210     //taskbar is not updated
1211     HICON hIcon = GetEffectiveIcon(ICON_BIG);
1212     HICON hIconSm = GetEffectiveIcon(ICON_SMALL);
1213     SendMessage(WM_SETICON, ICON_BIG,   (LPARAM)hIcon);
1214     SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
1215 }
1216 
1217 HICON AwtFrame::GetEffectiveIcon(int iconType)
1218 {
1219     BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/));
1220     HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon();
1221     if (hIcon == NULL) {
1222         hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() :
1223             AwtToolkit::GetInstance().GetAwtIcon();
1224     }
1225     return hIcon;
1226 }
1227 
1228 static BOOL keepOnMinimize(jobject peer) {
1229     static BOOL checked = FALSE;
1230     static BOOL keep = FALSE;
1231     if (!checked) {
1232         keep = (JNU_GetStaticFieldByName(AwtToolkit::GetEnv(), NULL,
1233             "sun/awt/windows/WFramePeer", "keepOnMinimize", "Z").z) == JNI_TRUE;
1234         checked = TRUE;
1235     }
1236     return keep;
1237 }
1238 
1239 MsgRouting AwtFrame::WmSysCommand(UINT uCmdType, int xPos, int yPos)
1240 {
1241     // ignore any WM_SYSCOMMAND if this window is blocked by modal dialog
1242     if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
1243         return mrConsume;
1244     }
1245 
1246     if (uCmdType == (SYSCOMMAND_IMM & 0xFFF0)){
1247         JNIEnv* env = AwtToolkit::GetEnv();
1248         JNU_CallMethodByName(env, NULL, m_peerObject,
1249             "notifyIMMOptionChange", "()V");
1250         DASSERT(!safe_ExceptionOccurred(env));
1251         return mrConsume;
1252     }
1253     if ((uCmdType == SC_MINIMIZE) && keepOnMinimize(m_peerObject)) {
1254         ::ShowWindow(GetHWnd(),SW_SHOWMINIMIZED);
1255         return mrConsume;
1256     }
1257     return AwtWindow::WmSysCommand(uCmdType, xPos, yPos);
1258 }
1259 
1260 LRESULT AwtFrame::WinThreadExecProc(ExecuteArgs * args)
1261 {
1262     switch( args->cmdId ) {
1263         case FRAME_SETMENUBAR:
1264         {
1265             jobject  mbPeer = (jobject)args->param1;
1266 
1267             // cancel any currently dropped down menus
1268             if (m_isMenuDropped) {
1269                 SendMessage(WM_CANCELMODE);
1270             }
1271 
1272             if (mbPeer == NULL) {
1273                 // Remove existing menu bar, if any
1274                 SetMenuBar(NULL);
1275             } else {
1276                 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1277                 AwtMenuBar* menuBar = (AwtMenuBar *)JNI_GET_PDATA(mbPeer);
1278                 SetMenuBar(menuBar);
1279             }
1280             DrawMenuBar();
1281             break;
1282         }
1283 
1284         default:
1285             AwtWindow::WinThreadExecProc(args);
1286             break;
1287     }
1288 
1289     return 0L;
1290 }
1291 
1292 void AwtFrame::_SynthesizeWmActivate(void *param)
1293 {
1294     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1295 
1296     SynthesizeWmActivateStruct *sas = (SynthesizeWmActivateStruct *)param;
1297     jobject self = sas->frame;
1298     jboolean doActivate = sas->doActivate;
1299 
1300     AwtFrame *frame = NULL;
1301 
1302     PDATA pData;
1303     JNI_CHECK_PEER_GOTO(self, ret);
1304     frame = (AwtFrame *)pData;
1305 
1306     SynthesizeWmActivate(doActivate, frame->GetHWnd(), NULL);
1307 ret:
1308     env->DeleteGlobalRef(self);
1309 
1310     delete sas;
1311 }
1312 
1313 jobject AwtFrame::_GetBoundsPrivate(void *param)
1314 {
1315     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1316 
1317     jobject self = (jobject)param;
1318 
1319     jobject result = NULL;
1320     AwtFrame *f = NULL;
1321 
1322     PDATA pData;
1323     JNI_CHECK_PEER_GOTO(self, ret);
1324     f = (AwtFrame *)pData;
1325     if (::IsWindow(f->GetHWnd()))
1326     {
1327         RECT rect;
1328         ::GetWindowRect(f->GetHWnd(), &rect);
1329         HWND parent = ::GetParent(f->GetHWnd());
1330         if (::IsWindow(parent))
1331         {
1332             POINT zero;
1333             zero.x = 0;
1334             zero.y = 0;
1335             ::ClientToScreen(parent, &zero);
1336             ::OffsetRect(&rect, -zero.x, -zero.y);
1337         }
1338 
1339         result = JNU_NewObjectByName(env, "java/awt/Rectangle", "(IIII)V",
1340             rect.left, rect.top, rect.bottom-rect.top, rect.right-rect.left);
1341     }
1342 ret:
1343     env->DeleteGlobalRef(self);
1344 
1345     if (result != NULL)
1346     {
1347         jobject resultGlobalRef = env->NewGlobalRef(result);
1348         env->DeleteLocalRef(result);
1349         return resultGlobalRef;
1350     }
1351     else
1352     {
1353         return NULL;
1354     }
1355 }
1356 
1357 void AwtFrame::_SetState(void *param)
1358 {
1359     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1360 
1361     SetStateStruct *sss = (SetStateStruct *)param;
1362     jobject self = sss->frame;
1363     jint state = sss->state;
1364 
1365     AwtFrame *f = NULL;
1366 
1367     PDATA pData;
1368     JNI_CHECK_PEER_GOTO(self, ret);
1369     f = (AwtFrame *)pData;
1370     HWND hwnd = f->GetHWnd();
1371     if (::IsWindow(hwnd))
1372     {
1373         DASSERT(!IsBadReadPtr(f, sizeof(AwtFrame)));
1374 
1375         BOOL iconify = (state & java_awt_Frame_ICONIFIED) != 0;
1376         BOOL zoom = (state & java_awt_Frame_MAXIMIZED_BOTH)
1377                         == java_awt_Frame_MAXIMIZED_BOTH;
1378 
1379         DTRACE_PRINTLN4("WFramePeer.setState:%s%s ->%s%s",
1380                   f->isIconic() ? " iconic" : "",
1381                   f->isZoomed() ? " zoomed" : "",
1382                   iconify       ? " iconic" : "",
1383                   zoom          ? " zoomed" : "");
1384 
1385         if (::IsWindowVisible(hwnd)) {
1386             BOOL focusable = f->IsFocusableWindow();
1387 
1388             WINDOWPLACEMENT wp;
1389             ::ZeroMemory(&wp, sizeof(wp));
1390             wp.length = sizeof(wp);
1391             ::GetWindowPlacement(hwnd, &wp);
1392 
1393             // Iconify first.
1394             // If both iconify & zoom are TRUE, handle this case
1395             // with wp.flags field below.
1396             if (iconify) {
1397                 wp.showCmd = focusable ? SW_MINIMIZE : SW_SHOWMINNOACTIVE;
1398             } else if (zoom) {
1399                 wp.showCmd = focusable ? SW_SHOWMAXIMIZED : SW_MAXIMIZE;
1400             } else { // zoom == iconify == FALSE
1401                 wp.showCmd = focusable ? SW_RESTORE : SW_SHOWNOACTIVATE;
1402             }
1403             if (zoom && iconify) {
1404                 wp.flags |= WPF_RESTORETOMAXIMIZED;
1405             } else {
1406                 wp.flags &= ~WPF_RESTORETOMAXIMIZED;
1407             }
1408 
1409             if (!zoom) {
1410                 f->m_forceResetZoomed = TRUE;
1411             }
1412 
1413             // The SetWindowPlacement() causes the WmSize() invocation
1414             //  which, in turn, actually updates the m_iconic & m_zoomed flags
1415             //  as well as sends Java event (WINDOW_STATE_CHANGED.)
1416             ::SetWindowPlacement(hwnd, &wp);
1417 
1418             f->m_forceResetZoomed = FALSE;
1419         } else {
1420             DTRACE_PRINTLN("  not visible, just recording the requested state");
1421 
1422             f->setIconic(iconify);
1423             f->setZoomed(zoom);
1424         }
1425     }
1426 ret:
1427     env->DeleteGlobalRef(self);
1428 
1429     delete sss;
1430 }
1431 
1432 jint AwtFrame::_GetState(void *param)
1433 {
1434     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1435 
1436     jobject self = (jobject)param;
1437 
1438     jint result = java_awt_Frame_NORMAL;
1439     AwtFrame *f = NULL;
1440 
1441     PDATA pData;
1442     JNI_CHECK_PEER_GOTO(self, ret);
1443     f = (AwtFrame *)pData;
1444     if (::IsWindow(f->GetHWnd()))
1445     {
1446         DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame)));
1447         if (f->isIconic()) {
1448             result |= java_awt_Frame_ICONIFIED;
1449         }
1450         if (f->isZoomed()) {
1451             result |= java_awt_Frame_MAXIMIZED_BOTH;
1452         }
1453 
1454         DTRACE_PRINTLN2("WFramePeer.getState:%s%s",
1455                   f->isIconic() ? " iconic" : "",
1456                   f->isZoomed() ? " zoomed" : "");
1457     }
1458 ret:
1459     env->DeleteGlobalRef(self);
1460 
1461     return result;
1462 }
1463 
1464 void AwtFrame::_SetMaximizedBounds(void *param)
1465 {
1466     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1467 
1468     SetMaximizedBoundsStruct *smbs = (SetMaximizedBoundsStruct *)param;
1469     jobject self = smbs->frame;
1470     int x = smbs->x;
1471     int y = smbs->y;
1472     int width = smbs->width;
1473     int height = smbs->height;
1474 
1475     AwtFrame *f = NULL;
1476 
1477     PDATA pData;
1478     JNI_CHECK_PEER_GOTO(self, ret);
1479     f = (AwtFrame *)pData;
1480     if (::IsWindow(f->GetHWnd()))
1481     {
1482         DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame)));
1483         f->SetMaximizedBounds(x, y, width, height);
1484     }
1485 ret:
1486     env->DeleteGlobalRef(self);
1487 
1488     delete smbs;
1489 }
1490 
1491 void AwtFrame::_ClearMaximizedBounds(void *param)
1492 {
1493     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1494 
1495     jobject self = (jobject)param;
1496 
1497     AwtFrame *f = NULL;
1498 
1499     PDATA pData;
1500     JNI_CHECK_PEER_GOTO(self, ret);
1501     f = (AwtFrame *)pData;
1502     if (::IsWindow(f->GetHWnd()))
1503     {
1504         DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame)));
1505         f->ClearMaximizedBounds();
1506     }
1507 ret:
1508     env->DeleteGlobalRef(self);
1509 }
1510 
1511 void AwtFrame::_SetMenuBar(void *param)
1512 {
1513     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1514 
1515     SetMenuBarStruct *smbs = (SetMenuBarStruct *)param;
1516     jobject self = smbs->frame;
1517     jobject menubar = smbs->menubar;
1518 
1519     AwtFrame *f = NULL;
1520 
1521     PDATA pData;
1522     JNI_CHECK_PEER_GOTO(self, ret);
1523     f = (AwtFrame *)pData;
1524     if (::IsWindow(f->GetHWnd()))
1525     {
1526         ExecuteArgs args;
1527         args.cmdId = FRAME_SETMENUBAR;
1528         args.param1 = (LPARAM)menubar;
1529         f->WinThreadExecProc(&args);
1530     }
1531 ret:
1532     env->DeleteGlobalRef(self);
1533     env->DeleteGlobalRef(menubar);
1534 
1535     delete smbs;
1536 }
1537 
1538 void AwtFrame::_SetIMMOption(void *param)
1539 {
1540     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1541 
1542     SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param;
1543     jobject self = sios->frame;
1544     jstring option = sios->option;
1545 
1546     int badAlloc = 0;
1547     LPCTSTR coption;
1548     LPCTSTR empty = TEXT("InputMethod");
1549     AwtFrame *f = NULL;
1550 
1551     PDATA pData;
1552     JNI_CHECK_PEER_GOTO(self, ret);
1553     JNI_CHECK_NULL_GOTO(option, "IMMOption argument", ret);
1554 
1555     f = (AwtFrame *)pData;
1556     if (::IsWindow(f->GetHWnd()))
1557     {
1558         coption = JNU_GetStringPlatformChars(env, option, NULL);
1559         if (coption == NULL)
1560         {
1561             badAlloc = 1;
1562         }
1563         if (!badAlloc)
1564         {
1565             HMENU hSysMenu = ::GetSystemMenu(f->GetHWnd(), FALSE);
1566             ::AppendMenu(hSysMenu,  MF_STRING, SYSCOMMAND_IMM, coption);
1567 
1568             if (coption != empty)
1569             {
1570                 JNU_ReleaseStringPlatformChars(env, option, coption);
1571             }
1572         }
1573     }
1574 ret:
1575     env->DeleteGlobalRef(self);
1576     env->DeleteGlobalRef(option);
1577 
1578     delete sios;
1579 
1580     if (badAlloc)
1581     {
1582         throw std::bad_alloc();
1583     }
1584 }
1585 
1586 void AwtFrame::_NotifyModalBlocked(void *param)
1587 {
1588     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
1589 
1590     NotifyModalBlockedStruct *nmbs = (NotifyModalBlockedStruct *)param;
1591     jobject self = nmbs->frame;
1592     jobject peer = nmbs->peer;
1593     jobject blockerPeer = nmbs->blockerPeer;
1594     jboolean blocked = nmbs->blocked;
1595 
1596     PDATA pData;
1597 
1598     JNI_CHECK_PEER_GOTO(peer, ret);
1599     AwtFrame *f = (AwtFrame *)pData;
1600 
1601     // dialog here may be NULL, for example, if the blocker is a native dialog
1602     // however, we need to install/unistall modal hooks anyway
1603     JNI_CHECK_PEER_GOTO(blockerPeer, ret);
1604     AwtDialog *d = (AwtDialog *)pData;
1605 
1606     if ((f != NULL) && ::IsWindow(f->GetHWnd()))
1607     {
1608         // get an HWND of the toplevel window this embedded frame is within
1609         HWND fHWnd = f->GetHWnd();
1610         while (::GetParent(fHWnd) != NULL) {
1611             fHWnd = ::GetParent(fHWnd);
1612         }
1613         // we must get a toplevel hwnd here, however due to some strange
1614         // behaviour of Java Plugin (a bug?) when running in IE at
1615         // this moment the embedded frame hasn't been placed into the
1616         // browser yet and fHWnd is not a toplevel, so we shouldn't install
1617         // the hook here
1618         if ((::GetWindowLong(fHWnd, GWL_STYLE) & WS_CHILD) == 0) {
1619             // if this toplevel is created in another thread, we should install
1620             // the modal hook into it to track window activation and mouse events
1621             DWORD fThread = ::GetWindowThreadProcessId(fHWnd, NULL);
1622             if (fThread != AwtToolkit::GetInstance().MainThread()) {
1623                 // check if this thread has been already blocked
1624                 BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)((intptr_t)fThread));
1625                 if (blocked) {
1626                     if (blockedThread == NULL) {
1627                         blockedThread = new BlockedThreadStruct;
1628                         blockedThread->framesCount = 1;
1629                         blockedThread->modalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtDialog::ModalFilterProc,
1630                                                                       0, fThread);
1631                         blockedThread->mouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtDialog::MouseHookProc_NonTT,
1632                                                                       0, fThread);
1633                         sm_BlockedThreads.put((void *)((intptr_t)fThread), blockedThread);
1634                     } else {
1635                         blockedThread->framesCount++;
1636                     }
1637                 } else {
1638                     // see the comment above: if Java Plugin behaviour when running in IE
1639                     // was right, blockedThread would be always not NULL here
1640                     if (blockedThread != NULL) {
1641                         DASSERT(blockedThread->framesCount > 0);
1642                         if ((blockedThread->framesCount) == 1) {
1643                             ::UnhookWindowsHookEx(blockedThread->modalHook);
1644                             ::UnhookWindowsHookEx(blockedThread->mouseHook);
1645                             sm_BlockedThreads.remove((void *)((intptr_t)fThread));
1646                             delete blockedThread;
1647                         } else {
1648                             blockedThread->framesCount--;
1649                         }
1650                     }
1651                 }
1652             }
1653         }
1654     }
1655 ret:
1656     env->DeleteGlobalRef(self);
1657     env->DeleteGlobalRef(peer);
1658     env->DeleteGlobalRef(blockerPeer);
1659 
1660     delete nmbs;
1661 }
1662 
1663 /************************************************************************
1664  * WFramePeer native methods
1665  */
1666 
1667 extern "C" {
1668 
1669 /*
1670  * Class:     java_awt_Frame
1671  * Method:    initIDs
1672  * Signature: ()V
1673  */
1674 JNIEXPORT void JNICALL
1675 Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls)
1676 {
1677     TRY;
1678 
1679     AwtFrame::undecoratedID = env->GetFieldID(cls,"undecorated","Z");
1680     DASSERT(AwtFrame::undecoratedID != NULL);
1681 
1682     CATCH_BAD_ALLOC;
1683 }
1684 
1685 /*
1686  * Class:     sun_awt_windows_WFramePeer
1687  * Method:    initIDs
1688  * Signature: ()V
1689  */
1690 JNIEXPORT void JNICALL
1691 Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls)
1692 {
1693     TRY;
1694 
1695     AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V");
1696     DASSERT(AwtFrame::setExtendedStateMID);
1697     CHECK_NULL(AwtFrame::setExtendedStateMID);
1698 
1699     AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I");
1700     DASSERT(AwtFrame::getExtendedStateMID);
1701 
1702     CATCH_BAD_ALLOC;
1703 }
1704 
1705 /*
1706  * Class:     sun_awt_windows_WFramePeer
1707  * Method:    setState
1708  * Signature: (I)V
1709  */
1710 JNIEXPORT void JNICALL
1711 Java_sun_awt_windows_WFramePeer_setState(JNIEnv *env, jobject self,
1712     jint state)
1713 {
1714     TRY;
1715 
1716     SetStateStruct *sss = new SetStateStruct;
1717     sss->frame = env->NewGlobalRef(self);
1718     sss->state = state;
1719 
1720     AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetState, sss);
1721     // global ref and sss are deleted in _SetState()
1722 
1723     CATCH_BAD_ALLOC;
1724 }
1725 
1726 /*
1727  * Class:     sun_awt_windows_WFramePeer
1728  * Method:    getState
1729  * Signature: ()I
1730  */
1731 JNIEXPORT jint JNICALL
1732 Java_sun_awt_windows_WFramePeer_getState(JNIEnv *env, jobject self)
1733 {
1734     TRY;
1735 
1736     jobject selfGlobalRef = env->NewGlobalRef(self);
1737 
1738     return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall(
1739         (void*(*)(void*))AwtFrame::_GetState,
1740         (void *)selfGlobalRef)));
1741     // selfGlobalRef is deleted in _GetState()
1742 
1743     CATCH_BAD_ALLOC_RET(java_awt_Frame_NORMAL);
1744 }
1745 
1746 
1747 /*
1748  * Class:     sun_awt_windows_WFramePeer
1749  * Method:    setMaximizedBounds
1750  * Signature: (IIII)V
1751  */
1752 JNIEXPORT void JNICALL
1753 Java_sun_awt_windows_WFramePeer_setMaximizedBounds(JNIEnv *env, jobject self,
1754     jint x, jint y, jint width, jint height)
1755 {
1756     TRY;
1757 
1758     SetMaximizedBoundsStruct *smbs = new SetMaximizedBoundsStruct;
1759     smbs->frame = env->NewGlobalRef(self);
1760     smbs->x = x;
1761     smbs->y = y;
1762     smbs->width = width;
1763     smbs->height = height;
1764 
1765     AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMaximizedBounds, smbs);
1766     // global ref and smbs are deleted in _SetMaximizedBounds()
1767 
1768     CATCH_BAD_ALLOC;
1769 }
1770 
1771 
1772 /*
1773  * Class:     sun_awt_windows_WFramePeer
1774  * Method:    clearMaximizedBounds
1775  * Signature: ()V
1776  */
1777 JNIEXPORT void JNICALL
1778 Java_sun_awt_windows_WFramePeer_clearMaximizedBounds(JNIEnv *env, jobject self)
1779 {
1780     TRY;
1781 
1782     jobject selfGlobalRef = env->NewGlobalRef(self);
1783 
1784     AwtToolkit::GetInstance().SyncCall(AwtFrame::_ClearMaximizedBounds,
1785         (void *)selfGlobalRef);
1786     // selfGlobalRef is deleted in _ClearMaximizedBounds()
1787 
1788     CATCH_BAD_ALLOC;
1789 }
1790 
1791 
1792 /*
1793  * Class:     sun_awt_windows_WFramePeer
1794  * Method:    setMenuBar0
1795  * Signature: (Lsun/awt/windows/WMenuBarPeer;)V
1796  */
1797 JNIEXPORT void JNICALL
1798 Java_sun_awt_windows_WFramePeer_setMenuBar0(JNIEnv *env, jobject self,
1799                                             jobject mbPeer)
1800 {
1801     TRY;
1802 
1803     SetMenuBarStruct *smbs = new SetMenuBarStruct;
1804     smbs->frame = env->NewGlobalRef(self);
1805     smbs->menubar = env->NewGlobalRef(mbPeer);
1806 
1807     AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMenuBar, smbs);
1808     // global refs ans smbs are deleted in _SetMenuBar()
1809 
1810     CATCH_BAD_ALLOC;
1811 }
1812 
1813 /*
1814  * Class:     sun_awt_windows_WFramePeer
1815  * Method:    create
1816  * Signature: (Lsun/awt/windows/WComponentPeer;)V
1817  */
1818 JNIEXPORT void JNICALL
1819 Java_sun_awt_windows_WFramePeer_createAwtFrame(JNIEnv *env, jobject self,
1820                                                jobject parent)
1821 {
1822     TRY;
1823 
1824     AwtToolkit::CreateComponent(self, parent,
1825                                 (AwtToolkit::ComponentFactory)
1826                                 AwtFrame::Create);
1827 
1828     CATCH_BAD_ALLOC;
1829 }
1830 
1831 /*
1832  * Class:     sun_awt_windows_WFramePeer
1833  * Method:    getSysMenuHeight
1834  * Signature: ()I
1835  */
1836 JNIEXPORT jint JNICALL
1837 Java_sun_awt_windows_WFramePeer_getSysMenuHeight(JNIEnv *env, jclass self)
1838 {
1839     TRY;
1840 
1841     return ::GetSystemMetrics(SM_CYMENUSIZE);
1842 
1843     CATCH_BAD_ALLOC_RET(0);
1844 }
1845 
1846 /*
1847  * Class:     sun_awt_windows_WFramePeer
1848  * Method:    pSetIMMOption
1849  * Signature: (Ljava/lang/String;)V
1850  */
1851 JNIEXPORT void JNICALL
1852 Java_sun_awt_windows_WFramePeer_pSetIMMOption(JNIEnv *env, jobject self,
1853                                                jstring option)
1854 {
1855     TRY;
1856 
1857     SetIMMOptionStruct *sios = new SetIMMOptionStruct;
1858     sios->frame = env->NewGlobalRef(self);
1859     sios->option = (jstring)env->NewGlobalRef(option);
1860 
1861     AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetIMMOption, sios);
1862     // global refs and sios are deleted in _SetIMMOption()
1863 
1864     CATCH_BAD_ALLOC;
1865 }
1866 
1867 } /* extern "C" */
1868 
1869 
1870 /************************************************************************
1871  * WEmbeddedFrame native methods
1872  */
1873 
1874 extern "C" {
1875 
1876 /*
1877  * Class:     sun_awt_windows_WFramePeer
1878  * Method:    initIDs
1879  * Signature: (Lsun/awt/windows/WMenuBarPeer;)V
1880  */
1881 JNIEXPORT void JNICALL
1882 Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls)
1883 {
1884     TRY;
1885 
1886     AwtFrame::handleID = env->GetFieldID(cls, "handle", "J");
1887     DASSERT(AwtFrame::handleID != NULL);
1888     CHECK_NULL(AwtFrame::handleID);
1889 
1890     AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V");
1891     DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL);
1892     CHECK_NULL(AwtFrame::activateEmbeddingTopLevelMID);
1893 
1894     AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z");
1895     DASSERT(AwtFrame::isEmbeddedInIEID != NULL);
1896 
1897     CATCH_BAD_ALLOC;
1898 }
1899 
1900 JNIEXPORT void JNICALL
1901 Java_sun_awt_windows_WEmbeddedFrame_notifyModalBlockedImpl(JNIEnv *env,
1902                                                            jobject self,
1903                                                            jobject peer,
1904                                                            jobject blockerPeer,
1905                                                            jboolean blocked)
1906 {
1907     TRY;
1908 
1909     NotifyModalBlockedStruct *nmbs = new NotifyModalBlockedStruct;
1910     nmbs->frame = env->NewGlobalRef(self);
1911     nmbs->peer = env->NewGlobalRef(peer);
1912     nmbs->blockerPeer = env->NewGlobalRef(blockerPeer);
1913     nmbs->blocked = blocked;
1914 
1915     AwtToolkit::GetInstance().SyncCall(AwtFrame::_NotifyModalBlocked, nmbs);
1916     // global refs and nmbs are deleted in _NotifyModalBlocked()
1917 
1918     CATCH_BAD_ALLOC;
1919 }
1920 
1921 } /* extern "C" */
1922 
1923 
1924 /************************************************************************
1925  * WEmbeddedFramePeer native methods
1926  */
1927 
1928 extern "C" {
1929 
1930 JNIEXPORT void JNICALL
1931 Java_sun_awt_windows_WEmbeddedFramePeer_create(JNIEnv *env, jobject self,
1932                                                jobject parent)
1933 {
1934     TRY;
1935 
1936     JNI_CHECK_NULL_RETURN(self, "peer");
1937     AwtToolkit::CreateComponent(self, parent,
1938                                 (AwtToolkit::ComponentFactory)
1939                                 AwtFrame::Create);
1940 
1941     CATCH_BAD_ALLOC;
1942 }
1943 
1944 JNIEXPORT jobject JNICALL
1945 Java_sun_awt_windows_WEmbeddedFramePeer_getBoundsPrivate(JNIEnv *env, jobject self)
1946 {
1947     TRY;
1948 
1949     jobject result = (jobject)AwtToolkit::GetInstance().SyncCall(
1950         (void *(*)(void *))AwtFrame::_GetBoundsPrivate,
1951         env->NewGlobalRef(self));
1952     // global ref is deleted in _GetBoundsPrivate
1953 
1954     if (result != NULL)
1955     {
1956         jobject resultLocalRef = env->NewLocalRef(result);
1957         env->DeleteGlobalRef(result);
1958         return resultLocalRef;
1959     }
1960     else
1961     {
1962         return NULL;
1963     }
1964 
1965     CATCH_BAD_ALLOC_RET(NULL);
1966 }
1967 
1968 JNIEXPORT void JNICALL
1969 Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate)
1970 {
1971     TRY;
1972 
1973     SynthesizeWmActivateStruct *sas = new SynthesizeWmActivateStruct;
1974     sas->frame = env->NewGlobalRef(self);
1975     sas->doActivate = doActivate;
1976 
1977     /*
1978      * WARNING: invoking this function without synchronization by m_Sync CriticalSection.
1979      * Taking this lock results in a deadlock.
1980      */
1981     AwtToolkit::GetInstance().InvokeFunction(AwtFrame::_SynthesizeWmActivate, sas);
1982     // global ref and sas are deleted in _SynthesizeWmActivate()
1983 
1984     CATCH_BAD_ALLOC;
1985 }
1986 
1987 } /* extern "C" */
1988 
1989 static bool SetFocusToPluginControl(HWND hwndPlugin)
1990 {
1991     HWND hwndFocus = ::GetFocus();
1992 
1993     if (hwndFocus == hwndPlugin) {
1994         return false;
1995     }
1996 
1997     ::SetFocus(hwndPlugin);
1998     DWORD dwError = ::GetLastError();
1999     if (dwError != ERROR_SUCCESS) {
2000         // If direct call failed, use a special message to set focus
2001         return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0);
2002     }
2003     return true;
2004 }