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