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