view src/java.desktop/windows/native/libawt/windows/awt_Window.cpp @ 13220:a8e9ad77ac81

8073320: Windows HiDPI Graphics support Reviewed-by: flar, serb
author alexsch
date Fri, 13 Nov 2015 05:02:26 -0800
parents e66f69113b89
children d74d0c07410f
line wrap: on
line source
/*
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "awt.h"

#include <jlong.h>

#include "awt_Component.h"
#include "awt_Container.h"
#include "awt_Frame.h"
#include "awt_Dialog.h"
#include "awt_Insets.h"
#include "awt_Panel.h"
#include "awt_Toolkit.h"
#include "awt_Window.h"
#include "awt_Win32GraphicsDevice.h"
#include "awt_BitmapUtil.h"
#include "awt_IconCursor.h"
#include "ComCtl32Util.h"

#include "java_awt_Insets.h"
#include <java_awt_Container.h>
#include <java_awt_event_ComponentEvent.h>
#include "sun_awt_windows_WCanvasPeer.h"

#include <windowsx.h>

#if !defined(__int3264)
typedef __int32 LONG_PTR;
#endif // __int3264

// Used for Swing's Menu/Tooltip animation Support
const int UNSPECIFIED = 0;
const int TOOLTIP = 1;
const int MENU = 2;
const int SUBMENU = 3;
const int POPUPMENU = 4;
const int COMBOBOX_POPUP = 5;
const int TYPES_COUNT = 6;
jint windowTYPES[TYPES_COUNT];


/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
 */

/***********************************************************************/
// struct for _SetAlwaysOnTop() method
struct SetAlwaysOnTopStruct {
    jobject window;
    jboolean value;
};
// struct for _SetTitle() method
struct SetTitleStruct {
    jobject window;
    jstring title;
};
// struct for _SetResizable() method
struct SetResizableStruct {
    jobject window;
    jboolean resizable;
};
// struct for _UpdateInsets() method
struct UpdateInsetsStruct {
    jobject window;
    jobject insets;
};
// struct for _ReshapeFrame() method
struct ReshapeFrameStruct {
    jobject frame;
    jint x, y;
    jint w, h;
};
// struct for _SetIconImagesData
struct SetIconImagesDataStruct {
    jobject window;
    jintArray iconRaster;
    jint w, h;
    jintArray smallIconRaster;
    jint smw, smh;
};
// struct for _SetMinSize() method
// and other methods setting sizes
struct SizeStruct {
    jobject window;
    jint w, h;
};
// struct for _SetFocusableWindow() method
struct SetFocusableWindowStruct {
    jobject window;
    jboolean isFocusableWindow;
};
// struct for _ModalDisable() method
struct ModalDisableStruct {
    jobject window;
    jlong blockerHWnd;
};
// struct for _SetOpacity() method
struct OpacityStruct {
    jobject window;
    jint iOpacity;
};
// struct for _SetOpaque() method
struct OpaqueStruct {
    jobject window;
    jboolean isOpaque;
};
// struct for _UpdateWindow() method
struct UpdateWindowStruct {
    jobject window;
    jintArray data;
    HBITMAP hBitmap;
    jint width, height;
};
// Struct for _RequestWindowFocus() method
struct RequestWindowFocusStruct {
    jobject component;
    jboolean isMouseEventCause;
};
// struct for _RepositionSecurityWarning() method
struct RepositionSecurityWarningStruct {
    jobject window;
};

struct SetFullScreenExclusiveModeStateStruct {
    jobject window;
    jboolean isFSEMState;
};


/************************************************************************
 * AwtWindow fields
 */

jfieldID AwtWindow::warningStringID;
jfieldID AwtWindow::locationByPlatformID;
jfieldID AwtWindow::autoRequestFocusID;
jfieldID AwtWindow::securityWarningWidthID;
jfieldID AwtWindow::securityWarningHeightID;

jfieldID AwtWindow::sysXID;
jfieldID AwtWindow::sysYID;
jfieldID AwtWindow::sysWID;
jfieldID AwtWindow::sysHID;
jfieldID AwtWindow::windowTypeID;

jmethodID AwtWindow::getWarningStringMID;
jmethodID AwtWindow::calculateSecurityWarningPositionMID;
jmethodID AwtWindow::windowTypeNameMID;

int AwtWindow::ms_instanceCounter = 0;
HHOOK AwtWindow::ms_hCBTFilter;
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
BOOL AwtWindow::sm_resizing = FALSE;
UINT AwtWindow::untrustedWindowsCounter = 0;

/************************************************************************
 * AwtWindow class methods
 */

AwtWindow::AwtWindow() {
    m_sizePt.x = m_sizePt.y = 0;
    m_owningFrameDialog = NULL;
    m_isResizable = FALSE;//Default value is replaced after construction
    m_minSize.x = m_minSize.y = 0;
    m_hIcon = NULL;
    m_hIconSm = NULL;
    m_iconInherited = FALSE;
    VERIFY(::SetRectEmpty(&m_insets));
    VERIFY(::SetRectEmpty(&m_old_insets));
    VERIFY(::SetRectEmpty(&m_warningRect));

    // what's the best initial value?
    m_screenNum = -1;
    ms_instanceCounter++;
    m_grabbed = FALSE;
    m_isFocusableWindow = TRUE;
    m_isRetainingHierarchyZOrder = FALSE;
    m_filterFocusAndActivation = FALSE;

    if (AwtWindow::ms_instanceCounter == 1) {
        AwtWindow::ms_hCBTFilter =
            ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtWindow::CBTFilter,
                               0, AwtToolkit::MainThread());
    }

    m_opaque = TRUE;
    m_opacity = 0xff;


    warningString = NULL;
    warningWindow = NULL;
    securityTooltipWindow = NULL;
    securityWarningAnimationStage = 0;
    currentWmSizeState = SIZE_RESTORED;

    hContentBitmap = NULL;

    ::InitializeCriticalSection(&contentBitmapCS);

    m_windowType = NORMAL;
    m_alwaysOnTop = false;

    fullScreenExclusiveModeState = FALSE;
}

AwtWindow::~AwtWindow()
{
    if (warningString != NULL) {
        delete [] warningString;
    }
    DeleteContentBitmap();
    ::DeleteCriticalSection(&contentBitmapCS);
}

void AwtWindow::Dispose()
{
    // Fix 4745575 GDI Resource Leak
    // MSDN
    // Before a window is destroyed (that is, before it returns from processing
    // the WM_NCDESTROY message), an application must remove all entries it has
    // added to the property list. The application must use the RemoveProp function
    // to remove the entries.

    if (--AwtWindow::ms_instanceCounter == 0) {
        ::UnhookWindowsHookEx(AwtWindow::ms_hCBTFilter);
    }

    ::RemoveProp(GetHWnd(), ModalBlockerProp);

    if (m_grabbedWindow == this) {
        Ungrab();
    }
    if ((m_hIcon != NULL) && !m_iconInherited) {
        ::DestroyIcon(m_hIcon);
    }
    if ((m_hIconSm != NULL) && !m_iconInherited) {
        ::DestroyIcon(m_hIconSm);
    }

    AwtCanvas::Dispose();
}

void
AwtWindow::Grab() {
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (m_grabbedWindow != NULL) {
        m_grabbedWindow->Ungrab();
    }
    m_grabbed = TRUE;
    m_grabbedWindow = this;
    if (AwtComponent::GetFocusedWindow() == NULL && IsFocusableWindow()) {
        // we shouldn't perform grab in this case (see 4841881 & 6539458)
        Ungrab();
    } else if (GetHWnd() != AwtComponent::GetFocusedWindow()) {
        _ToFront(env->NewGlobalRef(GetPeer(env)));
        // Global ref was deleted in _ToFront
    }
}

void
AwtWindow::Ungrab(BOOL doPost) {
    if (m_grabbed && m_grabbedWindow == this) {
        if (doPost) {
            PostUngrabEvent();
        }
        m_grabbedWindow = NULL;
        m_grabbed = FALSE;
    }
}

void
AwtWindow::Ungrab() {
    Ungrab(TRUE);
}

void AwtWindow::_Grab(void * param) {
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    if (env->EnsureLocalCapacity(1) < 0)
    {
        env->DeleteGlobalRef(self);
        return;
    }

    AwtWindow *p = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    p = (AwtWindow *)pData;
    p->Grab();

  ret:
    env->DeleteGlobalRef(self);
}

void AwtWindow::_Ungrab(void * param) {
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    if (env->EnsureLocalCapacity(1) < 0)
    {
        env->DeleteGlobalRef(self);
        return;
    }

    AwtWindow *p = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    p = (AwtWindow *)pData;
    p->Ungrab(FALSE);

  ret:
    env->DeleteGlobalRef(self);
}

MsgRouting AwtWindow::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
    if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
        m_grabbedWindow->Ungrab();
    }
    return AwtCanvas::WmNcMouseDown(hitTest, x, y, button);
}

MsgRouting AwtWindow::WmWindowPosChanging(LPARAM windowPos) {
    return mrDoDefault;
}

void AwtWindow::RepositionSecurityWarning(JNIEnv *env)
{
    RECT rect;
    CalculateWarningWindowBounds(env, &rect);

    ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
            rect.left, rect.top,
            rect.right - rect.left, rect.bottom - rect.top,
            SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |
            SWP_NOOWNERZORDER
            );
}

MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) {
    WINDOWPOS * wp = (WINDOWPOS *)windowPos;

    // Reposition the warning window
    if (IsUntrusted() && warningWindow != NULL) {
        if (wp->flags & SWP_HIDEWINDOW) {
            UpdateSecurityWarningVisibility();
        }

        RepositionSecurityWarning((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2));

        if (wp->flags & SWP_SHOWWINDOW) {
            UpdateSecurityWarningVisibility();
        }
    }

    if (wp->flags & SWP_HIDEWINDOW) {
        EnableTranslucency(FALSE);
    }

    return mrDoDefault;
}

LPCTSTR AwtWindow::GetClassName() {
  return TEXT("SunAwtWindow");
}

void AwtWindow::FillClassInfo(WNDCLASSEX *lpwc)
{
    AwtComponent::FillClassInfo(lpwc);
    /*
     * This line causes bug #4189244 (Swing Popup menu is not being refreshed (cleared) under a Dialog)
     * so it's comment out (son@sparc.spb.su)
     *
     * lpwc->style     |= CS_SAVEBITS; // improve pull-down menu performance
     */
    lpwc->cbWndExtra = DLGWINDOWEXTRA;
}

bool AwtWindow::IsWarningWindow(HWND hWnd)
{
    const UINT len = 128;
    TCHAR windowClassName[len];

    ::RealGetWindowClass(hWnd, windowClassName, len);
    return 0 == _tcsncmp(windowClassName,
            AwtWindow::GetWarningWindowClassName(), len);
}

LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
        HWND hWnd = (HWND)wParam;
        AwtComponent *comp = AwtComponent::GetComponent(hWnd);

        if (comp == NULL) {
            // Check if it's a security warning icon
            // See: 5091224, 6181725, 6732583
            if (AwtWindow::IsWarningWindow(hWnd)) {
                return 1;
            }
        } else {
            if (comp->IsTopLevel()) {
                AwtWindow* win = (AwtWindow*)comp;

                if (!win->IsFocusableWindow() ||
                        win->m_filterFocusAndActivation)
                {
                    return 1; // Don't change focus/activation.
                }
            }
        }
    }
    return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
}

void AwtWindow::InitSecurityWarningSize(JNIEnv *env)
{
    warningWindowWidth = ::GetSystemMetrics(SM_CXSMICON);
    warningWindowHeight = ::GetSystemMetrics(SM_CYSMICON);

    jobject target = GetTarget(env);

    env->SetIntField(target, AwtWindow::securityWarningWidthID,
            warningWindowWidth);
    env->SetIntField(target, AwtWindow::securityWarningHeightID,
            warningWindowHeight);

    env->DeleteLocalRef(target);
}

void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title,
        DWORD windowStyle,
        DWORD windowExStyle,
        int x, int y, int w, int h,
        HWND hWndParent, HMENU hMenu,
        COLORREF colorForeground,
        COLORREF colorBackground,
        jobject peer)
{
    // Retrieve the warning string
    // Note: we need to get it before CreateHWnd() happens because
    // the isUntrusted() method may be invoked while the HWND
    // is being created in response to some window messages.
    jobject target = env->GetObjectField(peer, AwtObject::targetID);
    jstring javaWarningString =
        (jstring)env->CallObjectMethod(target, AwtWindow::getWarningStringMID);

    if (javaWarningString != NULL) {
        size_t length = env->GetStringLength(javaWarningString) + 1;
        warningString = new WCHAR[length];
        env->GetStringRegion(javaWarningString, 0,
                static_cast<jsize>(length - 1), reinterpret_cast<jchar*>(warningString));
        warningString[length-1] = L'\0';

        env->DeleteLocalRef(javaWarningString);
    }
    env->DeleteLocalRef(target);

    InitType(env, peer);
    JNU_CHECK_EXCEPTION(env);

    TweakStyle(windowStyle, windowExStyle);

    AwtCanvas::CreateHWnd(env, title,
            windowStyle,
            windowExStyle,
            x, y, w, h,
            hWndParent, hMenu,
            colorForeground,
            colorBackground,
            peer);

    // Now we need to create the warning window.
    CreateWarningWindow(env);
}

void AwtWindow::CreateWarningWindow(JNIEnv *env)
{
    if (!IsUntrusted()) {
        return;
    }

    if (++AwtWindow::untrustedWindowsCounter == 1) {
        AwtToolkit::GetInstance().InstallMouseLowLevelHook();
    }

    InitSecurityWarningSize(env);

    RECT rect;
    CalculateWarningWindowBounds(env, &rect);

    RegisterWarningWindowClass();
    warningWindow = ::CreateWindowEx(
            WS_EX_NOACTIVATE,
            GetWarningWindowClassName(),
            warningString,
            WS_POPUP,
            rect.left, rect.top,
            rect.right - rect.left, rect.bottom - rect.top,
            GetHWnd(), // owner
            NULL, // menu
            AwtToolkit::GetInstance().GetModuleHandle(),
            NULL // lParam
            );
    if (warningWindow == NULL) {
        //XXX: actually this is bad... We didn't manage to create the window.
        return;
    }

    HICON hIcon = GetSecurityWarningIcon();

    ICONINFO ii;
    ::GetIconInfo(hIcon, &ii);

    //Note: we assume that every security icon has exactly the same shape.
    HRGN rgn = BitmapUtil::BitmapToRgn(ii.hbmColor);
    if (rgn) {
        ::SetWindowRgn(warningWindow, rgn, TRUE);
    }

    // Now we need to create the tooltip control for this window.
    if (!ComCtl32Util::GetInstance().IsToolTipControlInitialized()) {
        return;
    }

    securityTooltipWindow = ::CreateWindowEx(
            WS_EX_TOPMOST,
            TOOLTIPS_CLASS,
            NULL,
            WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            warningWindow,
            NULL,
            AwtToolkit::GetInstance().GetModuleHandle(),
            NULL
            );

    ::SetWindowPos(securityTooltipWindow,
            HWND_TOPMOST, 0, 0, 0, 0,
            SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);


    // We currently don't expect changing the size of the window,
    // hence we may not care of updating the TOOL position/size.
    ::GetClientRect(warningWindow, &rect);

    TOOLINFO ti;

    ti.cbSize = sizeof(ti);
    ti.uFlags = TTF_SUBCLASS;
    ti.hwnd = warningWindow;
    ti.hinst = AwtToolkit::GetInstance().GetModuleHandle();
    ti.uId = 0;
    ti.lpszText = warningString;
    ti.rect.left = rect.left;
    ti.rect.top = rect.top;
    ti.rect.right = rect.right;
    ti.rect.bottom = rect.bottom;

    ::SendMessage(securityTooltipWindow, TTM_ADDTOOL,
            0, (LPARAM) (LPTOOLINFO) &ti);
}

void AwtWindow::DestroyWarningWindow()
{
    if (!IsUntrusted()) {
        return;
    }
    if (--AwtWindow::untrustedWindowsCounter == 0) {
        AwtToolkit::GetInstance().UninstallMouseLowLevelHook();
    }
    if (warningWindow != NULL) {
        // Note that the warningWindow is an owned window, and hence
        // it would be destroyed automatically. However, the window
        // class may only be unregistered if there's no any single
        // window left using this class. Thus, we're destroying the
        // warning window manually. Note that the tooltip window
        // will be destroyed automatically because it's an owned
        // window as well.
        ::DestroyWindow(warningWindow);
        warningWindow = NULL;
        securityTooltipWindow = NULL;
        UnregisterWarningWindowClass();
    }
}

void AwtWindow::DestroyHWnd()
{
    DestroyWarningWindow();
    AwtCanvas::DestroyHWnd();
}

LPCTSTR AwtWindow::GetWarningWindowClassName()
{
    return TEXT("SunAwtWarningWindow");
}

void AwtWindow::FillWarningWindowClassInfo(WNDCLASS *lpwc)
{
    lpwc->style         = 0L;
    lpwc->lpfnWndProc   = (WNDPROC)WarningWindowProc;
    lpwc->cbClsExtra    = 0;
    lpwc->cbWndExtra    = 0;
    lpwc->hInstance     = AwtToolkit::GetInstance().GetModuleHandle(),
    lpwc->hIcon         = AwtToolkit::GetInstance().GetAwtIcon();
    lpwc->hCursor       = ::LoadCursor(NULL, IDC_ARROW);
    lpwc->hbrBackground = NULL;
    lpwc->lpszMenuName  = NULL;
    lpwc->lpszClassName = AwtWindow::GetWarningWindowClassName();
}

void AwtWindow::RegisterWarningWindowClass()
{
    WNDCLASS  wc;

    ::ZeroMemory(&wc, sizeof(wc));

    if (!::GetClassInfo(AwtToolkit::GetInstance().GetModuleHandle(),
                        AwtWindow::GetWarningWindowClassName(), &wc))
    {
        AwtWindow::FillWarningWindowClassInfo(&wc);
        ATOM atom = ::RegisterClass(&wc);
        DASSERT(atom != 0);
    }
}

void AwtWindow::UnregisterWarningWindowClass()
{
    ::UnregisterClass(AwtWindow::GetWarningWindowClassName(), AwtToolkit::GetInstance().GetModuleHandle());
}

HICON AwtWindow::GetSecurityWarningIcon()
{
    // It is assumed that the icon at index 0 is gray
    const UINT index = securityAnimationKind == akShow ?
        securityWarningAnimationStage : 0;
    HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(index,
            warningWindowWidth, warningWindowHeight);
    return ico;
}

// This function calculates the bounds of the warning window and stores them
// into the RECT structure pointed by the argument rect.
void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect)
{
    RECT windowBounds;
    AwtToolkit::GetWindowRect(GetHWnd(), &windowBounds);

    jobject target = GetTarget(env);
    jobject point2D = env->CallObjectMethod(target,
            calculateSecurityWarningPositionMID,
            (jdouble)windowBounds.left, (jdouble)windowBounds.top,
            (jdouble)(windowBounds.right - windowBounds.left),
            (jdouble)(windowBounds.bottom - windowBounds.top));
    env->DeleteLocalRef(target);

    static jclass point2DClassID = NULL;
    static jmethodID point2DGetXMID = NULL;
    static jmethodID point2DGetYMID = NULL;

    if (point2DClassID == NULL) {
        jclass point2DClassIDLocal = env->FindClass("java/awt/geom/Point2D");
        if (point2DClassIDLocal == NULL) {
            env->DeleteLocalRef(point2D);
            return;
        }
        point2DClassID = (jclass)env->NewGlobalRef(point2DClassIDLocal);
        env->DeleteLocalRef(point2DClassIDLocal);
    }

    if (point2DGetXMID == NULL) {
        point2DGetXMID = env->GetMethodID(point2DClassID, "getX", "()D");
        if (point2DGetXMID == NULL) {
            env->DeleteLocalRef(point2D);
            return;
        }
    }
    if (point2DGetYMID == NULL) {
        point2DGetYMID = env->GetMethodID(point2DClassID, "getY", "()D");
        if (point2DGetYMID == NULL) {
            env->DeleteLocalRef(point2D);
            return;
        }
    }


    int x = (int)env->CallDoubleMethod(point2D, point2DGetXMID);
    int y = (int)env->CallDoubleMethod(point2D, point2DGetYMID);

    env->DeleteLocalRef(point2D);

    rect->left = x;
    rect->top = y;
    rect->right = rect->left + warningWindowWidth;
    rect->bottom = rect->top + warningWindowHeight;
}

LRESULT CALLBACK AwtWindow::WarningWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg) {
        case WM_PAINT:
            PaintWarningWindow(hwnd);
            return 0;

        case WM_MOUSEACTIVATE:
            {
                // Retrive the owner of the warning window.
                HWND javaWindow = ::GetParent(hwnd);
                if (javaWindow) {
                    // If the window is blocked by a modal dialog, substitute
                    // its handle with the topmost blocker.
                    HWND topmostBlocker = GetTopmostModalBlocker(javaWindow);
                    if (::IsWindow(topmostBlocker)) {
                        javaWindow = topmostBlocker;
                    }

                    ::BringWindowToTop(javaWindow);

                    AwtWindow * window =
                        (AwtWindow*)AwtComponent::GetComponent(javaWindow);
                    if (window == NULL) {
                        // Quite unlikely to go into here, but it's way better
                        // than getting a crash.
                        ::SetForegroundWindow(javaWindow);
                    } else {
                        // Activate the window if it is focusable and inactive
                        if (window->IsFocusableWindow() &&
                                javaWindow != ::GetActiveWindow()) {
                            ::SetForegroundWindow(javaWindow);
                        } else {
                            // ...otherwise just start the animation.
                            window->StartSecurityAnimation(akShow);
                        }
                    }

                    // In every case if there's a top-most blocker, we need to
                    // enable modal animation.
                    if (::IsWindow(topmostBlocker)) {
                        AwtDialog::AnimateModalBlocker(topmostBlocker);
                    }
                }
                return MA_NOACTIVATEANDEAT;
            }
    }
    return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}

void AwtWindow::PaintWarningWindow(HWND warningWindow)
{
    RECT updateRect;

    if (!::GetUpdateRect(warningWindow, &updateRect, FALSE)) {
        // got nothing to update
        return;
    }

    PAINTSTRUCT ps;
    HDC hdc = ::BeginPaint(warningWindow, &ps);
    if (hdc == NULL) {
        // indicates an error
        return;
    }

    PaintWarningWindow(warningWindow, hdc);

    ::EndPaint(warningWindow, &ps);
}

void AwtWindow::PaintWarningWindow(HWND warningWindow, HDC hdc)
{
    HWND javaWindow = ::GetParent(warningWindow);

    AwtWindow * window = (AwtWindow*)AwtComponent::GetComponent(javaWindow);
    if (window == NULL) {
        return;
    }

    ::DrawIconEx(hdc, 0, 0, window->GetSecurityWarningIcon(),
            window->warningWindowWidth, window->warningWindowHeight,
            0, NULL, DI_NORMAL);
}

static const UINT_PTR IDT_AWT_SECURITYANIMATION = 0x102;

// Approximately 6 times a second. 0.75 seconds total.
static const UINT securityAnimationTimerElapse = 150;
static const UINT securityAnimationMaxIterations = 5;

void AwtWindow::RepaintWarningWindow()
{
    HDC hdc = ::GetDC(warningWindow);
    PaintWarningWindow(warningWindow, hdc);
    ::ReleaseDC(warningWindow, hdc);
}

void AwtWindow::SetLayered(HWND window, bool layered)
{
    const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE);
    ::SetWindowLong(window, GWL_EXSTYLE, layered ?
            ex_style | WS_EX_LAYERED : ex_style & ~WS_EX_LAYERED);
}

bool AwtWindow::IsLayered(HWND window)
{
    const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE);
    return ex_style & WS_EX_LAYERED;
}

void AwtWindow::StartSecurityAnimation(AnimationKind kind)
{
    if (!IsUntrusted()) {
        return;
    }
    if (warningWindow == NULL) {
        return;
    }

    securityAnimationKind = kind;

    securityWarningAnimationStage = 1;
    ::SetTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION,
            securityAnimationTimerElapse, NULL);

    if (securityAnimationKind == akShow) {
        ::SetWindowPos(warningWindow,
                IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
                0, 0, 0, 0,
                SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
                SWP_SHOWWINDOW | SWP_NOOWNERZORDER);

        ::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0),
                0xFF, LWA_ALPHA);
        AwtWindow::SetLayered(warningWindow, false);
        ::RedrawWindow(warningWindow, NULL, NULL,
                RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
    } else if (securityAnimationKind == akPreHide) {
        // Pre-hiding means fading-out. We have to make the window layered.
        // Note: Some VNC clients do not support layered windows, hence
        // we dynamically turn it on and off. See 6805231.
        AwtWindow::SetLayered(warningWindow, true);
    }
}

void AwtWindow::StopSecurityAnimation()
{
    if (!IsUntrusted()) {
        return;
    }
    if (warningWindow == NULL) {
        return;
    }

    securityWarningAnimationStage = 0;
    ::KillTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION);

    switch (securityAnimationKind) {
        case akHide:
        case akPreHide:
            ::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0,
                    SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
                    SWP_HIDEWINDOW | SWP_NOOWNERZORDER);
            break;
        case akShow:
            RepaintWarningWindow();
            break;
    }

    securityAnimationKind = akNone;
}

MsgRouting AwtWindow::WmTimer(UINT_PTR timerID)
{
    if (timerID != IDT_AWT_SECURITYANIMATION) {
        return mrPassAlong;
    }

    if (securityWarningAnimationStage == 0) {
        return mrConsume;
    }

    securityWarningAnimationStage++;
    if (securityWarningAnimationStage >= securityAnimationMaxIterations) {
        if (securityAnimationKind == akPreHide) {
            // chain real hiding
            StartSecurityAnimation(akHide);
        } else {
            StopSecurityAnimation();
        }
    } else {
        switch (securityAnimationKind) {
            case akHide:
                {
                    BYTE opacity = ((int)0xFF *
                            (securityAnimationMaxIterations -
                             securityWarningAnimationStage)) /
                        securityAnimationMaxIterations;
                    ::SetLayeredWindowAttributes(warningWindow,
                            RGB(0, 0, 0), opacity, LWA_ALPHA);
                }
                break;
            case akShow:
            case akNone: // quite unlikely, but quite safe
                RepaintWarningWindow();
                break;
        }
    }

    return mrConsume;
}

// The security warning is visible if:
//    1. The window has the keyboard window focus, OR
//    2. The mouse pointer is located within the window bounds,
//       or within the security warning icon.
void AwtWindow::UpdateSecurityWarningVisibility()
{
    if (!IsUntrusted()) {
        return;
    }
    if (warningWindow == NULL) {
        return;
    }

    bool show = false;

    if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED &&
            !isFullScreenExclusiveMode())
    {
        if (AwtComponent::GetFocusedWindow() == GetHWnd()) {
            show = true;
        }

        HWND hwnd = AwtToolkit::GetInstance().GetWindowUnderMouse();
        if (hwnd == GetHWnd()) {
            show = true;
        }
        if (hwnd == warningWindow) {
            show = true;
        }
    }

    if (show && (!::IsWindowVisible(warningWindow) ||
                securityAnimationKind == akHide ||
                securityAnimationKind == akPreHide)) {
        StartSecurityAnimation(akShow);
    }
    if (!show && ::IsWindowVisible(warningWindow)) {
        StartSecurityAnimation(akPreHide);
    }
}

void AwtWindow::FocusedWindowChanged(HWND from, HWND to)
{
    AwtWindow * fw = (AwtWindow *)AwtComponent::GetComponent(from);
    AwtWindow * tw = (AwtWindow *)AwtComponent::GetComponent(to);

    if (fw != NULL) {
        fw->UpdateSecurityWarningVisibility();
    }
    if (tw != NULL) {
        tw->UpdateSecurityWarningVisibility();

        // Flash on receiving the keyboard focus even if the warning
        // has already been shown (e.g. by hovering with the mouse)
        tw->StartSecurityAnimation(akShow);
    }
}

void AwtWindow::_RepositionSecurityWarning(void* param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    RepositionSecurityWarningStruct *rsws =
        (RepositionSecurityWarningStruct *)param;
    jobject self = rsws->window;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    AwtWindow *window = (AwtWindow *)pData;

    window->RepositionSecurityWarning(env);

  ret:
    env->DeleteGlobalRef(self);
    delete rsws;
}

void AwtWindow::InitType(JNIEnv *env, jobject peer)
{
    jobject type = env->GetObjectField(peer, windowTypeID);
    if (type == NULL) {
        return;
    }

    jstring value = (jstring)env->CallObjectMethod(type, windowTypeNameMID);
    if (value == NULL) {
        env->DeleteLocalRef(type);
        return;
    }

    const char* valueNative = env->GetStringUTFChars(value, 0);
    if (valueNative == NULL) {
        env->DeleteLocalRef(value);
        env->DeleteLocalRef(type);
        return;
    }

    if (strcmp(valueNative, "UTILITY") == 0) {
        m_windowType = UTILITY;
    } else if (strcmp(valueNative, "POPUP") == 0) {
        m_windowType = POPUP;
    }

    env->ReleaseStringUTFChars(value, valueNative);
    env->DeleteLocalRef(value);
    env->DeleteLocalRef(type);
}

void AwtWindow::TweakStyle(DWORD & style, DWORD & exStyle)
{
    switch (GetType()) {
        case UTILITY:
            exStyle |= WS_EX_TOOLWINDOW;
            break;
        case POPUP:
            style &= ~WS_OVERLAPPED;
            style |= WS_POPUP;
            break;
    }
}

/* Create a new AwtWindow object and window.   */
AwtWindow* AwtWindow::Create(jobject self, jobject parent)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject target = NULL;
    AwtWindow* window = NULL;

    try {
        if (env->EnsureLocalCapacity(1) < 0) {
            return NULL;
        }

        AwtWindow* awtParent = NULL;

        PDATA pData;
        if (parent != NULL) {
            JNI_CHECK_PEER_GOTO(parent, done);
            awtParent = (AwtWindow *)pData;
        }

        target = env->GetObjectField(self, AwtObject::targetID);
        JNI_CHECK_NULL_GOTO(target, "null target", done);

        window = new AwtWindow();

        {
            if (JNU_IsInstanceOfByName(env, target, "javax/swing/Popup$HeavyWeightWindow") > 0) {
                window->m_isRetainingHierarchyZOrder = TRUE;
            }
            if (env->ExceptionCheck()) goto done;
            DWORD style = WS_CLIPCHILDREN | WS_POPUP;
            DWORD exStyle = WS_EX_NOACTIVATE;
            if (GetRTL()) {
                exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
                if (GetRTLReadingOrder())
                    exStyle |= WS_EX_RTLREADING;
            }
            if (awtParent != NULL) {
                window->InitOwner(awtParent);
            } else {
                // specify WS_EX_TOOLWINDOW to remove parentless windows from taskbar
                exStyle |= WS_EX_TOOLWINDOW;
            }
            window->CreateHWnd(env, L"",
                               style, exStyle,
                               0, 0, 0, 0,
                               (awtParent != NULL) ? awtParent->GetHWnd() : NULL,
                               NULL,
                               ::GetSysColor(COLOR_WINDOWTEXT),
                               ::GetSysColor(COLOR_WINDOW),
                               self);

            jint x = env->GetIntField(target, AwtComponent::xID);
            jint y = env->GetIntField(target, AwtComponent::yID);
            jint width = env->GetIntField(target, AwtComponent::widthID);
            jint height = env->GetIntField(target, AwtComponent::heightID);

            /*
             * Initialize icon as inherited from parent if it exists
             */
            if (parent != NULL) {
                window->m_hIcon = awtParent->GetHIcon();
                window->m_hIconSm = awtParent->GetHIconSm();
                window->m_iconInherited = TRUE;
            }
            window->DoUpdateIcon();


            /*
             * Reshape here instead of during create, so that a WM_NCCALCSIZE
             * is sent.
             */
            window->Reshape(x, y, width, height);
        }
    } catch (...) {
        env->DeleteLocalRef(target);
        throw;
    }

done:
    env->DeleteLocalRef(target);
    return window;
}

BOOL AwtWindow::IsOneOfOwnersOf(AwtWindow * wnd) {
    while (wnd != NULL) {
        if (wnd == this || wnd->GetOwningFrameOrDialog() == this) return TRUE;
        wnd = (AwtWindow*)GetComponent(::GetWindow(wnd->GetHWnd(), GW_OWNER));
    }
    return FALSE;
}

void AwtWindow::InitOwner(AwtWindow *owner)
{
    DASSERT(owner != NULL);
    while (owner != NULL && owner->IsSimpleWindow()) {

        HWND ownerOwnerHWND = ::GetWindow(owner->GetHWnd(), GW_OWNER);
        if (ownerOwnerHWND == NULL) {
            owner = NULL;
            break;
        }
        owner = (AwtWindow *)AwtComponent::GetComponent(ownerOwnerHWND);
    }
    m_owningFrameDialog = (AwtFrame *)owner;
}

void AwtWindow::moveToDefaultLocation() {
    HWND boggy = ::CreateWindow(GetClassName(), L"BOGGY", WS_OVERLAPPED, CW_USEDEFAULT, 0 ,0, 0,
        NULL, NULL, NULL, NULL);
    RECT defLoc;

    // Fixed 6477497: Windows drawn off-screen on Win98, even when java.awt.Window.locationByPlatform is set
    //    Win9x does not position a window until the window is shown.
    //    The behavior is slightly opposite to the WinNT (and up), where
    //    Windows will position the window upon creation of the window.
    //    That's why we have to manually set the left & top values of
    //    the defLoc to 0 if the GetWindowRect function returns FALSE.
    BOOL result = ::GetWindowRect(boggy, &defLoc);
    if (!result) {
        defLoc.left = defLoc.top = 0;
    }
    VERIFY(::DestroyWindow(boggy));
    VERIFY(::SetWindowPos(GetHWnd(), NULL, defLoc.left, defLoc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER));
}

void AwtWindow::Show()
{
    m_visible = true;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    BOOL  done = false;
    HWND hWnd = GetHWnd();

    if (env->EnsureLocalCapacity(2) < 0) {
        return;
    }
    jobject target = GetTarget(env);
    INT nCmdShow;

    AwtFrame* owningFrame = GetOwningFrameOrDialog();
    if (IsFocusableWindow() && IsAutoRequestFocus() && owningFrame != NULL &&
        ::GetForegroundWindow() == owningFrame->GetHWnd())
    {
        nCmdShow = SW_SHOW;
    } else {
        nCmdShow = SW_SHOWNA;
    }

    BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID);

    if (locationByPlatform) {
         moveToDefaultLocation();
    }

    EnableTranslucency(TRUE);

    // The following block exists to support Menu/Tooltip animation for
    // Swing programs in a way which avoids introducing any new public api into
    // AWT or Swing.
    // This code should eventually be replaced by a better longterm solution
    // which might involve tagging java.awt.Window instances with a semantic
    // property so platforms can animate/decorate/etc accordingly.
    //
    if (JNU_IsInstanceOfByName(env, target, "com/sun/java/swing/plaf/windows/WindowsPopupWindow") > 0)
    {
        // need this global ref to make the class unloadable (see 6500204)
        static jclass windowsPopupWindowCls;
        static jfieldID windowTypeFID = NULL;
        jint windowType = 0;
        BOOL  animateflag = FALSE;
        BOOL  fadeflag = FALSE;
        DWORD animateStyle = 0;

        if (windowTypeFID == NULL) {
            // Initialize Window type constants ONCE...

            jfieldID windowTYPESFID[TYPES_COUNT];
            jclass cls = env->GetObjectClass(target);
            windowTypeFID = env->GetFieldID(cls, "windowType", "I");

            windowTYPESFID[UNSPECIFIED] = env->GetStaticFieldID(cls, "UNDEFINED_WINDOW_TYPE", "I");
            windowTYPESFID[TOOLTIP] = env->GetStaticFieldID(cls, "TOOLTIP_WINDOW_TYPE", "I");
            windowTYPESFID[MENU] = env->GetStaticFieldID(cls, "MENU_WINDOW_TYPE", "I");
            windowTYPESFID[SUBMENU] = env->GetStaticFieldID(cls, "SUBMENU_WINDOW_TYPE", "I");
            windowTYPESFID[POPUPMENU] = env->GetStaticFieldID(cls, "POPUPMENU_WINDOW_TYPE", "I");
            windowTYPESFID[COMBOBOX_POPUP] = env->GetStaticFieldID(cls, "COMBOBOX_POPUP_WINDOW_TYPE", "I");

            for (int i=0; i < 6; i++) {
                windowTYPES[i] = env->GetStaticIntField(cls, windowTYPESFID[i]);
            }
            windowsPopupWindowCls = (jclass) env->NewGlobalRef(cls);
            env->DeleteLocalRef(cls);
        }
        windowType = env->GetIntField(target, windowTypeFID);

        if (windowType == windowTYPES[TOOLTIP]) {
            SystemParametersInfo(SPI_GETTOOLTIPANIMATION, 0, &animateflag, 0);
            SystemParametersInfo(SPI_GETTOOLTIPFADE, 0, &fadeflag, 0);
            if (animateflag) {
              // AW_BLEND currently produces runtime parameter error
              // animateStyle = fadeflag? AW_BLEND : AW_SLIDE | AW_VER_POSITIVE;
                 animateStyle = fadeflag? 0 : AW_SLIDE | AW_VER_POSITIVE;
            }
        } else if (windowType == windowTYPES[MENU] || windowType == windowTYPES[SUBMENU] ||
                   windowType == windowTYPES[POPUPMENU]) {
            SystemParametersInfo(SPI_GETMENUANIMATION, 0, &animateflag, 0);
            if (animateflag) {
                SystemParametersInfo(SPI_GETMENUFADE, 0, &fadeflag, 0);
                if (fadeflag) {
                    // AW_BLEND currently produces runtime parameter error
                    //animateStyle = AW_BLEND;
                }
                if (animateStyle == 0 && !fadeflag) {
                    animateStyle = AW_SLIDE;
                    if (windowType == windowTYPES[MENU]) {
                      animateStyle |= AW_VER_POSITIVE;
                    } else if (windowType == windowTYPES[SUBMENU]) {
                      animateStyle |= AW_HOR_POSITIVE;
                    } else { /* POPUPMENU */
                      animateStyle |= (AW_VER_POSITIVE | AW_HOR_POSITIVE);
                    }
                }
            }
        } else if (windowType == windowTYPES[COMBOBOX_POPUP]) {
            SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animateflag, 0);
            if (animateflag) {
                 animateStyle = AW_SLIDE | AW_VER_POSITIVE;
            }
        }

        if (animateStyle != 0) {
            BOOL result = ::AnimateWindow(hWnd, (DWORD)200, animateStyle);
            if (!result) {
                // TODO: log message
            } else {
                // WM_PAINT is not automatically sent when invoking AnimateWindow,
                // so force an expose event
                RECT rect;
                ::GetWindowRect(hWnd,&rect);
                ::ScreenToClient(hWnd, (LPPOINT)&rect);
                ::InvalidateRect(hWnd, &rect, TRUE);
                ::UpdateWindow(hWnd);
                done = TRUE;
            }
        }
    }
    if (!done) {
        // transient windows shouldn't change the owner window's position in the z-order
        if (IsRetainingHierarchyZOrder()){
            UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER;
            if (nCmdShow == SW_SHOWNA) {
                flags |= SWP_NOACTIVATE;
            }
            ::SetWindowPos(GetHWnd(), HWND_TOPMOST, 0, 0, 0, 0, flags);
        } else {
            ::ShowWindow(GetHWnd(), nCmdShow);
        }
    }
    env->DeleteLocalRef(target);
}

/*
 * Get and return the insets for this window (container, really).
 * Calculate & cache them while we're at it, for use by AwtGraphics
 */
BOOL AwtWindow::UpdateInsets(jobject insets)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    DASSERT(GetPeer(env) != NULL);
    if (env->EnsureLocalCapacity(2) < 0) {
        return FALSE;
    }

    // fix 4167248 : don't update insets when frame is iconified
    // to avoid bizarre window/client rectangles
    if (::IsIconic(GetHWnd())) {
        return FALSE;
    }

    /*
     * Code to calculate insets. Stores results in frame's data
     * members, and in the peer's Inset object.
     */
    RECT outside;
    RECT inside;
    int extraBottomInsets = 0;

    ::GetClientRect(GetHWnd(), &inside);
    ::GetWindowRect(GetHWnd(), &outside);

    /* Update our inset member */
    if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
        ::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&inside, 2);
        m_insets.top = inside.top - outside.top;
        m_insets.bottom = outside.bottom - inside.bottom + extraBottomInsets;
        m_insets.left = inside.left - outside.left;
        m_insets.right = outside.right - inside.right;
    } else {
        m_insets.top = -1;
    }
    if (m_insets.left < 0 || m_insets.top < 0 ||
        m_insets.right < 0 || m_insets.bottom < 0)
    {
        /* This window hasn't been sized yet -- use system metrics. */
        jobject target = GetTarget(env);
        if (IsUndecorated() == FALSE) {
            /* Get outer frame sizes. */
            LONG style = GetStyle();
            if (style & WS_THICKFRAME) {
                m_insets.left = m_insets.right =
                    ::GetSystemMetrics(SM_CXSIZEFRAME);
                m_insets.top = m_insets.bottom =
                    ::GetSystemMetrics(SM_CYSIZEFRAME);
            } else {
                m_insets.left = m_insets.right =
                    ::GetSystemMetrics(SM_CXDLGFRAME);
                m_insets.top = m_insets.bottom =
                    ::GetSystemMetrics(SM_CYDLGFRAME);
            }


            /* Add in title. */
            m_insets.top += ::GetSystemMetrics(SM_CYCAPTION);
        }
        else {
            /* fix for 4418125: Undecorated frames are off by one */
            /* undo the -1 set above */
            /* Additional fix for 5059656 */
                /* Also, 5089312: Window insets should be 0. */
            ::memset(&m_insets, 0, sizeof(m_insets));
        }

        /* Add in menuBar, if any. */
        if (JNU_IsInstanceOfByName(env, target, "java/awt/Frame") > 0 &&
            ((AwtFrame*)this)->GetMenuBar()) {
            m_insets.top += ::GetSystemMetrics(SM_CYMENU);
        }
        if (env->ExceptionCheck()) {
            env->DeleteLocalRef(target);
            return FALSE;
        }
        m_insets.bottom += extraBottomInsets;
        env->DeleteLocalRef(target);
    }

    BOOL insetsChanged = FALSE;

    jobject peer = GetPeer(env);
    /* Get insets into our peer directly */
    jobject peerInsets = (env)->GetObjectField(peer, AwtPanel::insets_ID);
    DASSERT(!safe_ExceptionOccurred(env));

    if (peerInsets != NULL) { // may have been called during creation
        (env)->SetIntField(peerInsets, AwtInsets::topID, ScaleDownY(m_insets.top));
        (env)->SetIntField(peerInsets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
        (env)->SetIntField(peerInsets, AwtInsets::leftID, ScaleDownX(m_insets.left));
        (env)->SetIntField(peerInsets, AwtInsets::rightID, ScaleDownX(m_insets.right));
    }
    /* Get insets into the Inset object (if any) that was passed */
    if (insets != NULL) {
        (env)->SetIntField(insets, AwtInsets::topID, ScaleDownY(m_insets.top));
        (env)->SetIntField(insets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
        (env)->SetIntField(insets, AwtInsets::leftID, ScaleDownX(m_insets.left));
        (env)->SetIntField(insets, AwtInsets::rightID, ScaleDownX(m_insets.right));
    }
    env->DeleteLocalRef(peerInsets);

    insetsChanged = !::EqualRect( &m_old_insets, &m_insets );
    ::CopyRect( &m_old_insets, &m_insets );

    if (insetsChanged) {
        // Since insets are changed we need to update the surfaceData object
        // to reflect that change
        env->CallVoidMethod(peer, AwtComponent::replaceSurfaceDataLaterMID);
    }

    return insetsChanged;
}

/**
 * Sometimes we need the hWnd that actually owns this Window's hWnd (if
 * there is an owner).
 */
HWND AwtWindow::GetTopLevelHWnd()
{
    return m_owningFrameDialog ? m_owningFrameDialog->GetHWnd() :
                                 GetHWnd();
}

/*
 * Although this function sends ComponentEvents, it needs to be defined
 * here because only top-level windows need to have move and resize
 * events fired from native code.  All contained windows have these events
 * fired from common Java code.
 */
void AwtWindow::SendComponentEvent(jint eventId)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    static jclass classEvent = NULL;
    if (classEvent == NULL) {
        if (env->PushLocalFrame(1) < 0)
            return;
        classEvent = env->FindClass("java/awt/event/ComponentEvent");
        if (classEvent != NULL) {
            classEvent = (jclass)env->NewGlobalRef(classEvent);
        }
        env->PopLocalFrame(0);
        CHECK_NULL(classEvent);
    }
    static jmethodID eventInitMID = NULL;
    if (eventInitMID == NULL) {
        eventInitMID = env->GetMethodID(classEvent, "<init>",
                                        "(Ljava/awt/Component;I)V");
        CHECK_NULL(eventInitMID);
    }
    if (env->EnsureLocalCapacity(2) < 0) {
        return;
    }
    jobject target = GetTarget(env);
    jobject event = env->NewObject(classEvent, eventInitMID,
                                   target, eventId);
    DASSERT(!safe_ExceptionOccurred(env));
    DASSERT(event != NULL);
    if (event == NULL) {
        env->DeleteLocalRef(target);
        return;
    }
    SendEvent(event);

    env->DeleteLocalRef(target);
    env->DeleteLocalRef(event);
}

void AwtWindow::SendWindowEvent(jint id, HWND opposite,
                                jint oldState, jint newState)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    static jclass wClassEvent;
    if (wClassEvent == NULL) {
        if (env->PushLocalFrame(1) < 0)
            return;
        wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
        if (wClassEvent != NULL) {
            wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
        }
        env->PopLocalFrame(0);
        if (wClassEvent == NULL) {
            return;
        }
    }

    static jmethodID wEventInitMID;
    if (wEventInitMID == NULL) {
        wEventInitMID =
            env->GetMethodID(wClassEvent, "<init>",
                             "(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
        DASSERT(wEventInitMID);
        if (wEventInitMID == NULL) {
            return;
        }
    }

    static jclass sequencedEventCls;
    if (sequencedEventCls == NULL) {
        jclass sequencedEventClsLocal
            = env->FindClass("java/awt/SequencedEvent");
        DASSERT(sequencedEventClsLocal);
        CHECK_NULL(sequencedEventClsLocal);
        sequencedEventCls =
            (jclass)env->NewGlobalRef(sequencedEventClsLocal);
        env->DeleteLocalRef(sequencedEventClsLocal);
    }

    static jmethodID sequencedEventConst;
    if (sequencedEventConst == NULL) {
        sequencedEventConst =
            env->GetMethodID(sequencedEventCls, "<init>",
                             "(Ljava/awt/AWTEvent;)V");
        CHECK_NULL(sequencedEventConst);
    }

    if (env->EnsureLocalCapacity(3) < 0) {
        return;
    }

    jobject target = GetTarget(env);
    jobject jOpposite = NULL;
    if (opposite != NULL) {
        AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
        if (awtOpposite != NULL) {
            jOpposite = awtOpposite->GetTarget(env);
        }
    }
    jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
                                   jOpposite, oldState, newState, ::JVM_CurrentTimeMillis(NULL, 0));
    DASSERT(!safe_ExceptionOccurred(env));
    DASSERT(event != NULL);
    if (jOpposite != NULL) {
        env->DeleteLocalRef(jOpposite); jOpposite = NULL;
    }
    env->DeleteLocalRef(target); target = NULL;
    CHECK_NULL(event);

    if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
        id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS)
    {
        jobject sequencedEvent = env->NewObject(sequencedEventCls,
                                                sequencedEventConst,
                                                event);
        DASSERT(!safe_ExceptionOccurred(env));
        DASSERT(sequencedEvent != NULL);
        env->DeleteLocalRef(event);
        event = sequencedEvent;
    }

    SendEvent(event);

    env->DeleteLocalRef(event);
}

BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
{
    // We used to reject non mouse window activation if our app wasn't active.
    // This code since has been removed as the fix for 7185280

    HWND proxyContainerHWnd = GetProxyToplevelContainer();
    HWND proxyHWnd = GetProxyFocusOwner();

    if (proxyContainerHWnd == NULL || proxyHWnd == NULL) {
        return FALSE;
    }

    // Activate the proxy toplevel container
    if (::GetActiveWindow() != proxyContainerHWnd) {
        sm_suppressFocusAndActivation = TRUE;
        ::BringWindowToTop(proxyContainerHWnd);
        ::SetForegroundWindow(proxyContainerHWnd);
        sm_suppressFocusAndActivation = FALSE;

        if (::GetActiveWindow() != proxyContainerHWnd) {
            return FALSE; // activation has been rejected
        }
    }

    // Focus the proxy itself
    if (::GetFocus() != proxyHWnd) {
        sm_suppressFocusAndActivation = TRUE;
        ::SetFocus(proxyHWnd);
        sm_suppressFocusAndActivation = FALSE;

        if (::GetFocus() != proxyHWnd) {
            return FALSE; // focus has been rejected (that is unlikely)
        }
    }

    const HWND focusedWindow = AwtComponent::GetFocusedWindow();
    if (focusedWindow != GetHWnd()) {
        if (focusedWindow != NULL) {
            // Deactivate the old focused window
            AwtWindow::SynthesizeWmActivate(FALSE, focusedWindow, GetHWnd());
        }
        // Activate the new focused window.
        AwtWindow::SynthesizeWmActivate(TRUE, GetHWnd(), focusedWindow);
    }
    return TRUE;
}

MsgRouting AwtWindow::WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{
    jint type;

    if (nState != WA_INACTIVE) {
        type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS;
        AwtComponent::SetFocusedWindow(GetHWnd());
    } else {
        // The owner is not necassarily getting WM_ACTIVATE(WA_INACTIVE).
        // So, initiate retaining the actualFocusedWindow.
        AwtFrame *owner = GetOwningFrameOrDialog();
        if (owner) {
            owner->CheckRetainActualFocusedWindow(opposite);
        }

        if (m_grabbedWindow != NULL && !m_grabbedWindow->IsOneOfOwnersOf(this)) {
            m_grabbedWindow->Ungrab();
        }
        type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS;
        AwtComponent::SetFocusedWindow(NULL);
        sm_focusOwner = NULL;
    }

    SendWindowEvent(type, opposite);
    return mrConsume;
}

MsgRouting AwtWindow::WmCreate()
{
    return mrDoDefault;
}

MsgRouting AwtWindow::WmClose()
{
    SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSING);

    /* Rely on above notification to handle quitting as needed */
    return mrConsume;
}

MsgRouting AwtWindow::WmDestroy()
{
    SendWindowEvent(java_awt_event_WindowEvent_WINDOW_CLOSED);
    return AwtComponent::WmDestroy();
}

MsgRouting AwtWindow::WmShowWindow(BOOL show, UINT status)
{
    /*
     * Original fix for 4810575. Modified for 6386592.
     * If a simple window gets disposed we should synthesize
     * WM_ACTIVATE for its nearest owner. This is not performed by default because
     * the owner frame/dialog is natively active.
     */
    HWND hwndSelf = GetHWnd();
    HWND hwndOwner = ::GetParent(hwndSelf);

    if (!show && IsSimpleWindow() && hwndSelf == AwtComponent::GetFocusedWindow() &&
        hwndOwner != NULL && ::IsWindowVisible(hwndOwner))
    {
        AwtFrame *owner = (AwtFrame*)AwtComponent::GetComponent(hwndOwner);
        if (owner != NULL) {
            owner->AwtSetActiveWindow();
        }
    }

    //Fixed 4842599: REGRESSION: JPopupMenu not Hidden Properly After Iconified and Deiconified
    if (show && (status == SW_PARENTOPENING)) {
        if (!IsVisible()) {
            return mrConsume;
        }
    }
    return AwtCanvas::WmShowWindow(show, status);
}

/*
 * Override AwtComponent's move handling to first update the
 * java AWT target's position fields directly, since Windows
 * and below can be resized from outside of java (by user)
 */
MsgRouting AwtWindow::WmMove(int x, int y)
{
    if ( ::IsIconic(GetHWnd()) ) {
    // fixes 4065534 (robi.khan@eng)
    // if a window is iconified we don't want to update
    // it's target's position since minimized Win32 windows
    // move to -32000, -32000 for whatever reason
    // NOTE: See also AwtWindow::Reshape
        return mrDoDefault;
    }

    if (m_screenNum == -1) {
    // Set initial value
        m_screenNum = GetScreenImOn();
    }
    else {
        CheckIfOnNewScreen();
    }

    /* Update the java AWT target component's fields directly */
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (env->EnsureLocalCapacity(1) < 0) {
        return mrConsume;
    }
    jobject peer = GetPeer(env);
    jobject target = env->GetObjectField(peer, AwtObject::targetID);

    RECT rect;
    ::GetWindowRect(GetHWnd(), &rect);

    (env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left));
    (env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top));
    (env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left));
    (env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top));
    SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);

    env->DeleteLocalRef(target);
    return AwtComponent::WmMove(x, y);
}

MsgRouting AwtWindow::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
{
    MsgRouting r = AwtCanvas::WmGetMinMaxInfo(lpmmi);
    if ((m_minSize.x == 0) && (m_minSize.y == 0)) {
        return r;
    }
    lpmmi->ptMinTrackSize.x = m_minSize.x;
    lpmmi->ptMinTrackSize.y = m_minSize.y;
    return mrConsume;
}

MsgRouting AwtWindow::WmSizing()
{
    if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) {
        return mrDoDefault;
    }

    DTRACE_PRINTLN("AwtWindow::WmSizing  fullWindowDragEnabled");

    SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED);

    HWND thisHwnd = GetHWnd();
    if (thisHwnd == NULL) {
        return mrDoDefault;
    }

    // Call WComponentPeer::dynamicallyLayoutContainer()
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jobject peer = GetPeer(env);
    JNU_CallMethodByName(env, NULL, peer, "dynamicallyLayoutContainer", "()V");
    DASSERT(!safe_ExceptionOccurred(env));

    return mrDoDefault;
}

/*
 * Override AwtComponent's size handling to first update the
 * java AWT target's dimension fields directly, since Windows
 * and below can be resized from outside of java (by user)
 */
MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
{
    currentWmSizeState = type;

    if (type == SIZE_MINIMIZED) {
        UpdateSecurityWarningVisibility();
        return mrDoDefault;
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (env->EnsureLocalCapacity(1) < 0)
        return mrDoDefault;
    jobject target = GetTarget(env);
    // fix 4167248 : ensure the insets are up-to-date before using
    BOOL insetsChanged = UpdateInsets(NULL);
    int newWidth = w + m_insets.left + m_insets.right;
    int newHeight = h + m_insets.top + m_insets.bottom;

    (env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth));
    (env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight));

    jobject peer = GetPeer(env);
    (env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth));
    (env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight));

    if (!AwtWindow::IsResizing()) {
        WindowResized();
    }

    env->DeleteLocalRef(target);
    return AwtComponent::WmSize(type, w, h);
}

MsgRouting AwtWindow::WmPaint(HDC)
{
    PaintUpdateRgn(&m_insets);
    return mrConsume;
}

MsgRouting AwtWindow::WmSettingChange(UINT wFlag, LPCTSTR pszSection)
{
    if (wFlag == SPI_SETNONCLIENTMETRICS) {
    // user changed window metrics in
    // Control Panel->Display->Appearance
    // which may cause window insets to change
        UpdateInsets(NULL);

    // [rray] fix for 4407329 - Changing Active Window Border width in display
    //  settings causes problems
        WindowResized();
        Invalidate(NULL);

        return mrConsume;
    }
    return mrDoDefault;
}

MsgRouting AwtWindow::WmNcCalcSize(BOOL fCalcValidRects,
                                   LPNCCALCSIZE_PARAMS lpncsp, LRESULT& retVal)
{
    MsgRouting mrRetVal = mrDoDefault;

    if (fCalcValidRects == FALSE) {
        return mrDoDefault;
    }
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (env->EnsureLocalCapacity(2) < 0) {
        return mrConsume;
    }
    // WM_NCCALCSIZE is usually in response to a resize, but
    // also can be triggered by SetWindowPos(SWP_FRAMECHANGED),
    // which means the insets will have changed - rnk 4/7/1998
    retVal = static_cast<UINT>(DefWindowProc(
                WM_NCCALCSIZE, fCalcValidRects, reinterpret_cast<LPARAM>(lpncsp)));
    if (HasValidRect()) {
        UpdateInsets(NULL);
    }
    mrRetVal = mrConsume;
    return mrRetVal;
}

MsgRouting AwtWindow::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
    // If this window is blocked by modal dialog, return HTCLIENT for any point of it.
    // That prevents it to be moved or resized using the mouse. Disabling these
    // actions to be launched from sysmenu is implemented by ignoring WM_SYSCOMMAND
    if (::IsWindow(GetModalBlocker(GetHWnd()))) {
        retVal = HTCLIENT;
    } else {
        retVal = DefWindowProc(WM_NCHITTEST, 0, MAKELPARAM(x, y));
    }
    return mrConsume;
}

MsgRouting AwtWindow::WmGetIcon(WPARAM iconType, LRESULT& retValue)
{
    return mrDoDefault;
}

LRESULT AwtWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    MsgRouting mr = mrDoDefault;
    LRESULT retValue = 0L;

    switch(message) {
        case WM_GETICON:
            mr = WmGetIcon(wParam, retValue);
            break;
        case WM_SYSCOMMAND:
            //Fixed 6355340: Contents of frame are not layed out properly on maximize
            if ((wParam & 0xFFF0) == SC_SIZE) {
                AwtWindow::sm_resizing = TRUE;
                mr = WmSysCommand(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
                if (mr != mrConsume) {
                    // Perform size-move loop here
                    AwtWindow::DefWindowProc(message, wParam, lParam);
                }
                AwtWindow::sm_resizing = FALSE;
                if (!AwtToolkit::GetInstance().IsDynamicLayoutActive()) {
                    WindowResized();
                } else {
                    /*
                     * 8016356: check whether window snapping occurred after
                     * resizing, i.e. GetWindowRect() returns the real
                     * (snapped) window rectangle, e.g. (179, 0)-(483, 1040),
                     * but GetWindowPlacement() returns the rectangle of
                     * normal window position, e.g. (179, 189)-(483, 445) and
                     * they are different. If so, send ComponentResized event.
                     */
                    WINDOWPLACEMENT wp;
                    ::GetWindowPlacement(GetHWnd(), &wp);
                    RECT rc;
                    ::GetWindowRect(GetHWnd(), &rc);
                    if (!::EqualRect(&rc, &wp.rcNormalPosition)) {
                        WindowResized();
                    }
                }
                mr = mrConsume;
            }
            break;
    }

    if (mr != mrConsume) {
        retValue = AwtCanvas::WindowProc(message, wParam, lParam);
    }
    return retValue;
}

/*
 * Fix for BugTraq ID 4041703: keyDown not being invoked.
 * This method overrides AwtCanvas::HandleEvent() since
 * an empty Window always receives the focus on the activation
 * so we don't have to modify the behavior.
 */
MsgRouting AwtWindow::HandleEvent(MSG *msg, BOOL synthetic)
{
    return AwtComponent::HandleEvent(msg, synthetic);
}

void AwtWindow::WindowResized()
{
    SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_RESIZED);
    // Need to replace surfaceData on resize to catch changes to
    // various component-related values, such as insets
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    env->CallVoidMethod(m_peerObject, AwtComponent::replaceSurfaceDataLaterMID);
}

BOOL CALLBACK InvalidateChildRect(HWND hWnd, LPARAM)
{
    TRY;

    ::InvalidateRect(hWnd, NULL, TRUE);
    return TRUE;

    CATCH_BAD_ALLOC_RET(FALSE);
}

void AwtWindow::Invalidate(RECT* r)
{
    ::InvalidateRect(GetHWnd(), NULL, TRUE);
    ::EnumChildWindows(GetHWnd(), (WNDENUMPROC)InvalidateChildRect, 0);
}

BOOL AwtWindow::IsResizable() {
    return m_isResizable;
}

void AwtWindow::SetResizable(BOOL isResizable)
{
    m_isResizable = isResizable;
    if (IsEmbeddedFrame()) {
        return;
    }
    LONG style = GetStyle();
    LONG resizeStyle = WS_MAXIMIZEBOX;

    if (IsUndecorated() == FALSE) {
        resizeStyle |= WS_THICKFRAME;
    }

    if (isResizable) {
        style |= resizeStyle;
    } else {
        style &= ~resizeStyle;
    }
    SetStyle(style);
    RedrawNonClient();
}

// SetWindowPos flags to cause frame edge to be recalculated
static const UINT SwpFrameChangeFlags =
    SWP_FRAMECHANGED | /* causes WM_NCCALCSIZE to be called */
    SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
    SWP_NOACTIVATE | SWP_NOCOPYBITS |
    SWP_NOREPOSITION | SWP_NOSENDCHANGING;

//
// Forces WM_NCCALCSIZE to be called to recalculate
// window border (updates insets) without redrawing it
//
void AwtWindow::RecalcNonClient()
{
    ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_NOREDRAW);
}

//
// Forces WM_NCCALCSIZE to be called to recalculate
// window border (updates insets) and redraws border to match
//
void AwtWindow::RedrawNonClient()
{
    ::SetWindowPos(GetHWnd(), (HWND) NULL, 0, 0, 0, 0, SwpFrameChangeFlags|SWP_ASYNCWINDOWPOS);
}

int AwtWindow::GetScreenImOn() {
    HMONITOR hmon;
    int scrnNum;

    hmon = ::MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY);
    DASSERT(hmon != NULL);

    scrnNum = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hmon);
    DASSERT(scrnNum > -1);

    return scrnNum;
}

/* Check to see if we've been moved onto another screen.
 * If so, update internal data, surfaces, etc.
 */

void AwtWindow::CheckIfOnNewScreen() {
    int curScrn = GetScreenImOn();

    if (curScrn != m_screenNum) {  // we've been moved
        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

        jclass peerCls = env->GetObjectClass(m_peerObject);
        DASSERT(peerCls);
        CHECK_NULL(peerCls);

        jmethodID draggedID = env->GetMethodID(peerCls, "draggedToNewScreen",
                                               "()V");
        DASSERT(draggedID);
        if (draggedID == NULL) {
            env->DeleteLocalRef(peerCls);
            return;
        }

        env->CallVoidMethod(m_peerObject, draggedID);
        m_screenNum = curScrn;

        env->DeleteLocalRef(peerCls);
    }
}

BOOL AwtWindow::IsFocusableWindow() {
    /*
     * For Window/Frame/Dialog to accept focus it should:
     * - be focusable;
     * - be not blocked by any modal blocker.
     */
    BOOL focusable = m_isFocusableWindow && !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
    AwtFrame *owner = GetOwningFrameOrDialog(); // NULL for Frame and Dialog

    if (owner != NULL) {
        /*
         * Also for Window (not Frame/Dialog) to accept focus:
         * - its decorated parent should accept focus;
         */
        focusable = focusable && owner->IsFocusableWindow();
    }
    return focusable;
}

void AwtWindow::SetModalBlocker(HWND window, HWND blocker) {
    if (!::IsWindow(window)) {
        return;
    }

    if (::IsWindow(blocker)) {
        ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
        ::EnableWindow(window, FALSE);
    } else {
        ::RemoveProp(window, ModalBlockerProp);
         AwtComponent *comp = AwtComponent::GetComponent(window);
         // we don't expect to be called with non-java HWNDs
         DASSERT(comp && comp->IsTopLevel());
         // we should not unblock disabled toplevels
         ::EnableWindow(window, comp->isEnabled());
    }
}

void AwtWindow::SetAndActivateModalBlocker(HWND window, HWND blocker) {
    if (!::IsWindow(window)) {
        return;
    }
    AwtWindow::SetModalBlocker(window, blocker);
    if (::IsWindow(blocker)) {
        // We must check for visibility. Otherwise invisible dialog will receive WM_ACTIVATE.
        if (::IsWindowVisible(blocker)) {
            ::BringWindowToTop(blocker);
            ::SetForegroundWindow(blocker);
        }
    }
}

HWND AwtWindow::GetTopmostModalBlocker(HWND window)
{
    HWND ret, blocker = NULL;

    do {
        ret = blocker;
        blocker = AwtWindow::GetModalBlocker(window);
        window = blocker;
    } while (::IsWindow(blocker));

    return ret;
}

void AwtWindow::FlashWindowEx(HWND hWnd, UINT count, DWORD timeout, DWORD flags) {
    FLASHWINFO fi;
    fi.cbSize = sizeof(fi);
    fi.hwnd = hWnd;
    fi.dwFlags = flags;
    fi.uCount = count;
    fi.dwTimeout = timeout;
    ::FlashWindowEx(&fi);
}

jboolean
AwtWindow::_RequestWindowFocus(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    RequestWindowFocusStruct *rfs = (RequestWindowFocusStruct *)param;
    jobject self = rfs->component;
    jboolean isMouseEventCause = rfs->isMouseEventCause;

    jboolean result = JNI_FALSE;
    AwtWindow *window = NULL;

    PDATA pData;
    JNI_CHECK_NULL_GOTO(self, "peer", ret);
    pData = JNI_GET_PDATA(self);
    if (pData == NULL) {
        // do nothing just return false
        goto ret;
    }

    window = (AwtWindow *)pData;
    if (::IsWindow(window->GetHWnd())) {
        result = (jboolean)window->SendMessage(WM_AWT_WINDOW_SETACTIVE, (WPARAM)isMouseEventCause, 0);
    }
ret:
    env->DeleteGlobalRef(self);

    delete rfs;

    return result;
}

void AwtWindow::_ToFront(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        UINT flags = SWP_NOMOVE|SWP_NOSIZE;
        BOOL focusable = w->IsFocusableWindow();
        BOOL autoRequestFocus = w->IsAutoRequestFocus();

        if (!focusable || !autoRequestFocus)
        {
            flags = flags|SWP_NOACTIVATE;
        }
        ::SetWindowPos(w->GetHWnd(), HWND_TOP, 0, 0, 0, 0, flags);
        if (focusable && autoRequestFocus)
        {
            ::SetForegroundWindow(w->GetHWnd());
        }
    }
ret:
    env->DeleteGlobalRef(self);
}

void AwtWindow::_ToBack(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        HWND hwnd = w->GetHWnd();
//        if (AwtComponent::GetComponent(hwnd) == NULL) {
//            // Window was disposed. Don't bother.
//            return;
//        }

        ::SetWindowPos(hwnd, HWND_BOTTOM, 0, 0 ,0, 0,
            SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);

        // If hwnd is the foreground window or if *any* of its owners are, then
        // we have to reset the foreground window. The reason is that when we send
        // hwnd to back, all of its owners are sent to back as well. If any one of
        // them is the foreground window, then it's possible that we could end up
        // with a foreground window behind a window of another application.
        HWND foregroundWindow = ::GetForegroundWindow();
        BOOL adjustForegroundWindow;
        HWND toTest = hwnd;
        do
        {
            adjustForegroundWindow = (toTest == foregroundWindow);
            if (adjustForegroundWindow)
            {
                break;
            }
            toTest = ::GetWindow(toTest, GW_OWNER);
        }
        while (toTest != NULL);

        if (adjustForegroundWindow)
        {
            HWND foregroundSearch = hwnd, newForegroundWindow = NULL;
                while (1)
                {
                foregroundSearch = ::GetNextWindow(foregroundSearch, GW_HWNDPREV);
                if (foregroundSearch == NULL)
                {
                    break;
                }
                LONG style = static_cast<LONG>(::GetWindowLongPtr(foregroundSearch, GWL_STYLE));
                if ((style & WS_CHILD) || !(style & WS_VISIBLE))
                {
                    continue;
                }

                AwtComponent *c = AwtComponent::GetComponent(foregroundSearch);
                if ((c != NULL) && !::IsWindow(AwtWindow::GetModalBlocker(c->GetHWnd())))
                {
                    newForegroundWindow = foregroundSearch;
                }
            }
            if (newForegroundWindow != NULL)
            {
                ::SetWindowPos(newForegroundWindow, HWND_TOP, 0, 0, 0, 0,
                    SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
                if (((AwtWindow*)AwtComponent::GetComponent(newForegroundWindow))->IsFocusableWindow())
                {
                    ::SetForegroundWindow(newForegroundWindow);
                }
            }
            else
            {
                // We *have* to set the active HWND to something new. We simply
                // cannot risk having an active Java HWND which is behind an HWND
                // of a native application. This really violates the Windows user
                // experience.
                //
                // Windows won't allow us to set the foreground window to NULL,
                // so we use the desktop window instead. To the user, it appears
                // that there is no foreground window system-wide.
                ::SetForegroundWindow(::GetDesktopWindow());
            }
        }
    }
ret:
    env->DeleteGlobalRef(self);
}

void AwtWindow::_SetAlwaysOnTop(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetAlwaysOnTopStruct *sas = (SetAlwaysOnTopStruct *)param;
    jobject self = sas->window;
    jboolean value = sas->value;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        w->SendMessage(WM_AWT_SETALWAYSONTOP, (WPARAM)value, (LPARAM)w);
        w->m_alwaysOnTop = (bool)value;
    }
ret:
    env->DeleteGlobalRef(self);

    delete sas;
}

void AwtWindow::_SetTitle(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetTitleStruct *sts = (SetTitleStruct *)param;
    jobject self = sts->window;
    jstring title = sts->title;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    JNI_CHECK_NULL_GOTO(title, "null title", ret);

    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        int length = env->GetStringLength(title);
        TCHAR *buffer = new TCHAR[length + 1];
        env->GetStringRegion(title, 0, length, reinterpret_cast<jchar*>(buffer));
        buffer[length] = L'\0';
        VERIFY(::SetWindowText(w->GetHWnd(), buffer));
        delete[] buffer;
    }
ret:
    env->DeleteGlobalRef(self);
    if (title != NULL) {
        env->DeleteGlobalRef(title);
    }

    delete sts;
}

void AwtWindow::_SetResizable(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetResizableStruct *srs = (SetResizableStruct *)param;
    jobject self = srs->window;
    jboolean resizable = srs->resizable;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        DASSERT(!IsBadReadPtr(w, sizeof(AwtWindow)));
        w->SetResizable(resizable != 0);
    }
ret:
    env->DeleteGlobalRef(self);

    delete srs;
}

void AwtWindow::_UpdateInsets(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    UpdateInsetsStruct *uis = (UpdateInsetsStruct *)param;
    jobject self = uis->window;
    jobject insets = uis->insets;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    JNI_CHECK_NULL_GOTO(insets, "null insets", ret);
    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        w->UpdateInsets(insets);
    }
ret:
    env->DeleteGlobalRef(self);
    env->DeleteGlobalRef(insets);

    delete uis;
}

void AwtWindow::_ReshapeFrame(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    ReshapeFrameStruct *rfs = (ReshapeFrameStruct *)param;
    jobject self = rfs->frame;
    jint x = rfs->x;
    jint y = rfs->y;
    jint w = rfs->w;
    jint h = rfs->h;

    if (env->EnsureLocalCapacity(1) < 0)
    {
        env->DeleteGlobalRef(self);
        delete rfs;
        return;
    }

    AwtFrame *p = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    p = (AwtFrame *)pData;
    if (::IsWindow(p->GetHWnd()))
    {
        jobject target = env->GetObjectField(self, AwtObject::targetID);
        if (target != NULL)
        {
            // enforce tresholds before sending the event
            // Fix for 4459064 : do not enforce thresholds for embedded frames
            if (!p->IsEmbeddedFrame())
            {
                jobject peer = p->GetPeer(env);
                int minWidth = ::GetSystemMetrics(SM_CXMIN);
                int minHeight = ::GetSystemMetrics(SM_CYMIN);
                if (w < minWidth)
                {
                    env->SetIntField(target, AwtComponent::widthID,
                        w = minWidth);
                    env->SetIntField(peer, AwtWindow::sysWID,
                        w);
                }
                if (h < minHeight)
                {
                    env->SetIntField(target, AwtComponent::heightID,
                        h = minHeight);
                    env->SetIntField(peer, AwtWindow::sysHID,
                        h);
                }
            }
            env->DeleteLocalRef(target);

            RECT *r = new RECT;
            ::SetRect(r, x, y, x + w, y + h);
            p->SendMessage(WM_AWT_RESHAPE_COMPONENT, 0, (LPARAM)r);
            // r is deleted in message handler

            // After the input method window shown, the dimension & position may not
            // be valid until this method is called. So we need to adjust the
            // IME candidate window position for the same reason as commented on
            // awt_Frame.cpp Show() method.
            if (p->isInputMethodWindow() && ::IsWindowVisible(p->GetHWnd())) {
              p->AdjustCandidateWindowPos();
            }
        }
        else
        {
            JNU_ThrowNullPointerException(env, "null target");
        }
    }
ret:
   env->DeleteGlobalRef(self);

   delete rfs;
}

/*
 * This is AwtWindow-specific function that is not intended for reusing
 */
HICON CreateIconFromRaster(JNIEnv* env, jintArray iconRaster, jint w, jint h)
{
    HBITMAP mask = NULL;
    HBITMAP image = NULL;
    HICON icon = NULL;
    if (iconRaster != NULL) {
        int* iconRasterBuffer = NULL;
        try {
            iconRasterBuffer = (int *)env->GetPrimitiveArrayCritical(iconRaster, 0);

            JNI_CHECK_NULL_GOTO(iconRasterBuffer, "iconRaster data", done);

            mask = BitmapUtil::CreateTransparencyMaskFromARGB(w, h, iconRasterBuffer);
            image = BitmapUtil::CreateV4BitmapFromARGB(w, h, iconRasterBuffer);
        } catch (...) {
            if (iconRasterBuffer != NULL) {
                env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0);
            }
            throw;
        }
        if (iconRasterBuffer != NULL) {
            env->ReleasePrimitiveArrayCritical(iconRaster, iconRasterBuffer, 0);
        }
    }
    if (mask && image) {
        ICONINFO icnInfo;
        memset(&icnInfo, 0, sizeof(ICONINFO));
        icnInfo.hbmMask = mask;
        icnInfo.hbmColor = image;
        icnInfo.fIcon = TRUE;
        icon = ::CreateIconIndirect(&icnInfo);
    }
    if (image) {
        destroy_BMP(image);
    }
    if (mask) {
        destroy_BMP(mask);
    }
done:
    return icon;
}

void AwtWindow::SetIconData(JNIEnv* env, jintArray iconRaster, jint w, jint h,
                             jintArray smallIconRaster, jint smw, jint smh)
{
    HICON hOldIcon = NULL;
    HICON hOldIconSm = NULL;
    //Destroy previous icon if it isn't inherited
    if ((m_hIcon != NULL) && !m_iconInherited) {
        hOldIcon = m_hIcon;
    }
    m_hIcon = NULL;
    if ((m_hIconSm != NULL) && !m_iconInherited) {
        hOldIconSm = m_hIconSm;
    }
    m_hIconSm = NULL;
    m_hIcon = CreateIconFromRaster(env, iconRaster, w, h);
    JNU_CHECK_EXCEPTION(env);
    m_hIconSm = CreateIconFromRaster(env, smallIconRaster, smw, smh);

    m_iconInherited = (m_hIcon == NULL);
    if (m_iconInherited) {
        HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER);
        AwtWindow* owner = (AwtWindow *)AwtComponent::GetComponent(hOwner);
        if (owner != NULL) {
            m_hIcon = owner->GetHIcon();
            m_hIconSm = owner->GetHIconSm();
        } else {
            m_iconInherited = FALSE;
        }
    }
    DoUpdateIcon();
    EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)this);
    if (hOldIcon != NULL) {
        DestroyIcon(hOldIcon);
    }
    if (hOldIconSm != NULL) {
        DestroyIcon(hOldIconSm);
    }
}

BOOL AwtWindow::UpdateOwnedIconCallback(HWND hWndOwned, LPARAM lParam)
{
    HWND hWndOwner = ::GetWindow(hWndOwned, GW_OWNER);
    AwtWindow* owner = (AwtWindow*)lParam;
    if (hWndOwner == owner->GetHWnd()) {
        AwtComponent* comp = AwtComponent::GetComponent(hWndOwned);
        if (comp != NULL && comp->IsTopLevel()) {
            AwtWindow* owned = (AwtWindow *)comp;
            if (owned->m_iconInherited) {
                owned->m_hIcon = owner->m_hIcon;
                owned->m_hIconSm = owner->m_hIconSm;
                owned->DoUpdateIcon();
                EnumThreadWindows(AwtToolkit::MainThread(), UpdateOwnedIconCallback, (LPARAM)owned);
            }
        }
    }
    return TRUE;
}

void AwtWindow::DoUpdateIcon()
{
    //Does nothing for windows, is overriden for frames and dialogs
}

void AwtWindow::RedrawWindow()
{
    if (isOpaque()) {
        ::RedrawWindow(GetHWnd(), NULL, NULL,
                RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
    } else {
        ::EnterCriticalSection(&contentBitmapCS);
        if (hContentBitmap != NULL) {
            UpdateWindowImpl(contentWidth, contentHeight, hContentBitmap);
        }
        ::LeaveCriticalSection(&contentBitmapCS);
    }
}

// Deletes the hContentBitmap if it is non-null
void AwtWindow::DeleteContentBitmap()
{
    ::EnterCriticalSection(&contentBitmapCS);
    if (hContentBitmap != NULL) {
        ::DeleteObject(hContentBitmap);
        hContentBitmap = NULL;
    }
    ::LeaveCriticalSection(&contentBitmapCS);
}

// The effects are enabled only upon showing the window.
// See 6780496 for details.
void AwtWindow::EnableTranslucency(BOOL enable)
{
    if (enable) {
        SetTranslucency(getOpacity(), isOpaque(), FALSE, TRUE);
    } else {
        SetTranslucency(0xFF, TRUE, FALSE);
    }
}

/**
 * Sets the translucency effects.
 *
 * This method is used to:
 *
 * 1. Apply the translucency effects upon showing the window
 *    (setValues == FALSE, useDefaultForOldValues == TRUE);
 * 2. Turn off the effects upon hiding the window
 *    (setValues == FALSE, useDefaultForOldValues == FALSE);
 * 3. Set the effects per user's request
 *    (setValues == TRUE, useDefaultForOldValues == FALSE);
 *
 * In case #3 the effects may or may not be applied immediately depending on
 * the current visibility status of the window.
 *
 * The setValues argument indicates if we need to preserve the passed values
 * in local fields for further use.
 * The useDefaultForOldValues argument indicates whether we should consider
 * the window as if it has not any effects applied at the moment.
 */
void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque, BOOL setValues,
        BOOL useDefaultForOldValues)
{
    BYTE old_opacity = useDefaultForOldValues ? 0xFF : getOpacity();
    BOOL old_opaque = useDefaultForOldValues ? TRUE : isOpaque();

    if (opacity == old_opacity && opaque == old_opaque) {
        return;
    }

    if (setValues) {
       m_opacity = opacity;
       m_opaque = opaque;
    }

    // If we're invisible and are storing the values, return
    // Otherwise, apply the effects immediately
    if (!IsVisible() && setValues) {
        return;
    }

    HWND hwnd = GetHWnd();

    if (opaque != old_opaque) {
        DeleteContentBitmap();
    }

    if (opaque && opacity == 0xff) {
        // Turn off all the effects
        AwtWindow::SetLayered(hwnd, false);

        // Ask the window to repaint itself and all the children
        RedrawWindow();
    } else {
        // We're going to enable some effects
        if (!AwtWindow::IsLayered(hwnd)) {
            AwtWindow::SetLayered(hwnd, true);
        } else {
            if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) {
                // _One_ of the modes uses the SetLayeredWindowAttributes.
                // Need to reset the style in this case.
                // If both modes are simple (i.e. just changing the opacity level),
                // no need to reset the style.
                AwtWindow::SetLayered(hwnd, false);
                AwtWindow::SetLayered(hwnd, true);
            }
        }

        if (opaque) {
            // Simple opacity mode
            ::SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), opacity, LWA_ALPHA);
        }
    }
}

static HBITMAP CreateBitmapFromRaster(JNIEnv* env, jintArray raster, jint w, jint h)
{
    HBITMAP image = NULL;
    if (raster != NULL) {
        int* rasterBuffer = NULL;
        try {
            rasterBuffer = (int *)env->GetPrimitiveArrayCritical(raster, 0);
            JNI_CHECK_NULL_GOTO(rasterBuffer, "raster data", done);
            image = BitmapUtil::CreateBitmapFromARGBPre(w, h, w*4, rasterBuffer);
        } catch (...) {
            if (rasterBuffer != NULL) {
                env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
            }
            throw;
        }
        if (rasterBuffer != NULL) {
            env->ReleasePrimitiveArrayCritical(raster, rasterBuffer, 0);
        }
    }
done:
    return image;
}

void AwtWindow::UpdateWindowImpl(int width, int height, HBITMAP hBitmap)
{
    if (isOpaque()) {
        return;
    }

    HWND hWnd = GetHWnd();
    HDC hdcDst = ::GetDC(NULL);
    HDC hdcSrc = ::CreateCompatibleDC(NULL);
    HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcSrc, hBitmap);

    //XXX: this code doesn't paint the children (say, the java.awt.Button)!
    //So, if we ever want to support HWs here, we need to repaint them
    //in some other way...
    //::SendMessage(hWnd, WM_PRINT, (WPARAM)hdcSrc, /*PRF_CHECKVISIBLE |*/
    //      PRF_CHILDREN /*| PRF_CLIENT | PRF_NONCLIENT*/);

    POINT ptSrc;
    ptSrc.x = ptSrc.y = 0;

    RECT rect;
    POINT ptDst;
    SIZE size;

    ::GetWindowRect(hWnd, &rect);
    ptDst.x = rect.left;
    ptDst.y = rect.top;
    size.cx = width;
    size.cy = height;

    BLENDFUNCTION bf;

    bf.SourceConstantAlpha = getOpacity();
    bf.AlphaFormat = AC_SRC_ALPHA;
    bf.BlendOp = AC_SRC_OVER;
    bf.BlendFlags = 0;

    ::UpdateLayeredWindow(hWnd, hdcDst, &ptDst, &size, hdcSrc, &ptSrc,
            RGB(0, 0, 0), &bf, ULW_ALPHA);

    ::ReleaseDC(NULL, hdcDst);
    ::SelectObject(hdcSrc, hOldBitmap);
    ::DeleteDC(hdcSrc);
}

void AwtWindow::UpdateWindow(JNIEnv* env, jintArray data, int width, int height,
                             HBITMAP hNewBitmap)
{
    if (isOpaque()) {
        return;
    }

    HBITMAP hBitmap;
    if (hNewBitmap == NULL) {
        if (data == NULL) {
            return;
        }
        hBitmap = CreateBitmapFromRaster(env, data, width, height);
        if (hBitmap == NULL) {
            return;
        }
    } else {
        hBitmap = hNewBitmap;
    }

    ::EnterCriticalSection(&contentBitmapCS);
    DeleteContentBitmap();
    hContentBitmap = hBitmap;
    contentWidth = width;
    contentHeight = height;
    UpdateWindowImpl(width, height, hBitmap);
    ::LeaveCriticalSection(&contentBitmapCS);
}

/*
 * Fixed 6353381: it's improved fix for 4792958
 * which was backed-out to avoid 5059656
 */
BOOL AwtWindow::HasValidRect()
{
    RECT inside;
    RECT outside;

    if (::IsIconic(GetHWnd())) {
        return FALSE;
    }

    ::GetClientRect(GetHWnd(), &inside);
    ::GetWindowRect(GetHWnd(), &outside);

    BOOL isZeroClientArea = (inside.right == 0 && inside.bottom == 0);
    BOOL isInvalidLocation = ((outside.left == -32000 && outside.top == -32000) || // Win2k && WinXP
                              (outside.left == 32000 && outside.top == 32000) || // Win95 && Win98
                              (outside.left == 3000 && outside.top == 3000)); // Win95 && Win98

    // the bounds correspond to iconic state
    if (isZeroClientArea && isInvalidLocation)
    {
        return FALSE;
    }

    return TRUE;
}


void AwtWindow::_SetIconImagesData(void * param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetIconImagesDataStruct* s = (SetIconImagesDataStruct*)param;
    jobject self = s->window;

    jintArray iconRaster = s->iconRaster;
    jintArray smallIconRaster = s->smallIconRaster;

    AwtWindow *window = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    // ok to pass null raster: default AWT icon

    window = (AwtWindow*)pData;
    if (::IsWindow(window->GetHWnd()))
    {
        window->SetIconData(env, iconRaster, s->w, s->h, smallIconRaster, s->smw, s->smh);

    }

ret:
    env->DeleteGlobalRef(self);
    env->DeleteGlobalRef(iconRaster);
    env->DeleteGlobalRef(smallIconRaster);
    delete s;
}

void AwtWindow::_SetMinSize(void* param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SizeStruct *ss = (SizeStruct *)param;
    jobject self = ss->window;
    jint w = ss->w;
    jint h = ss->h;
    //Perform size setting
    AwtWindow *window = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    window = (AwtWindow *)pData;
    window->m_minSize.x = w;
    window->m_minSize.y = h;
  ret:
    env->DeleteGlobalRef(self);
    delete ss;
}

jint AwtWindow::_GetScreenImOn(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    // It's entirely possible that our native resources have been destroyed
    // before our java peer - if we're dispose()d, for instance.
    // Alert caller w/ IllegalComponentStateException.
    if (self == NULL) {
        JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
                        "Peer null in JNI");
        return 0;
    }
    PDATA pData = JNI_GET_PDATA(self);
    if (pData == NULL) {
        JNU_ThrowByName(env, "java/awt/IllegalComponentStateException",
                        "Native resources unavailable");
        env->DeleteGlobalRef(self);
        return 0;
    }

    jint result = 0;
    AwtWindow *w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        result = (jint)w->GetScreenImOn();
    }

    env->DeleteGlobalRef(self);

    return result;
}

void AwtWindow::_SetFocusableWindow(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetFocusableWindowStruct *sfws = (SetFocusableWindowStruct *)param;
    jobject self = sfws->window;
    jboolean isFocusableWindow = sfws->isFocusableWindow;

    AwtWindow *window = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    window = (AwtWindow *)pData;

    window->m_isFocusableWindow = isFocusableWindow;

    // A simple window is permanently set to WS_EX_NOACTIVATE
    if (!window->IsSimpleWindow()) {
        if (!window->m_isFocusableWindow) {
            LONG isPopup = window->GetStyle() & WS_POPUP;
            window->SetStyleEx(window->GetStyleEx() | (isPopup ? 0 : WS_EX_APPWINDOW) | WS_EX_NOACTIVATE);
        } else {
            window->SetStyleEx(window->GetStyleEx() & ~WS_EX_APPWINDOW & ~WS_EX_NOACTIVATE);
        }
    }

  ret:
    env->DeleteGlobalRef(self);
    delete sfws;
}

void AwtWindow::_ModalDisable(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    ModalDisableStruct *mds = (ModalDisableStruct *)param;
    jobject self = mds->window;
    HWND blockerHWnd = (HWND)mds->blockerHWnd;

    AwtWindow *window = NULL;
    HWND windowHWnd = 0;

    JNI_CHECK_NULL_GOTO(self, "peer", ret);
    PDATA pData = JNI_GET_PDATA(self);
    if (pData == NULL) {
        env->DeleteGlobalRef(self);
        delete mds;
        return;
    }

    window = (AwtWindow *)pData;
    windowHWnd = window->GetHWnd();
    if (::IsWindow(windowHWnd)) {
        AwtWindow::SetAndActivateModalBlocker(windowHWnd, blockerHWnd);
    }

ret:
    env->DeleteGlobalRef(self);

    delete mds;
}

void AwtWindow::_ModalEnable(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    AwtWindow *window = NULL;
    HWND windowHWnd = 0;

    JNI_CHECK_NULL_GOTO(self, "peer", ret);
    PDATA pData = JNI_GET_PDATA(self);
    if (pData == NULL) {
        env->DeleteGlobalRef(self);
        return;
    }

    window = (AwtWindow *)pData;
    windowHWnd = window->GetHWnd();
    if (::IsWindow(windowHWnd)) {
        AwtWindow::SetModalBlocker(windowHWnd, NULL);
    }

  ret:
    env->DeleteGlobalRef(self);
}

void AwtWindow::_SetOpacity(void* param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    OpacityStruct *os = (OpacityStruct *)param;
    jobject self = os->window;
    BYTE iOpacity = (BYTE)os->iOpacity;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    AwtWindow *window = (AwtWindow *)pData;

    window->SetTranslucency(iOpacity, window->isOpaque());

  ret:
    env->DeleteGlobalRef(self);
    delete os;
}

void AwtWindow::_SetOpaque(void* param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    OpaqueStruct *os = (OpaqueStruct *)param;
    jobject self = os->window;
    BOOL isOpaque = (BOOL)os->isOpaque;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    AwtWindow *window = (AwtWindow *)pData;

    window->SetTranslucency(window->getOpacity(), isOpaque);

  ret:
    env->DeleteGlobalRef(self);
    delete os;
}

void AwtWindow::_UpdateWindow(void* param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    UpdateWindowStruct *uws = (UpdateWindowStruct *)param;
    jobject self = uws->window;
    jintArray data = uws->data;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    AwtWindow *window = (AwtWindow *)pData;

    window->UpdateWindow(env, data, (int)uws->width, (int)uws->height,
                         uws->hBitmap);

  ret:
    env->DeleteGlobalRef(self);
    if (data != NULL) {
        env->DeleteGlobalRef(data);
    }
    delete uws;
}

void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetFullScreenExclusiveModeStateStruct * data =
        (SetFullScreenExclusiveModeStateStruct*)param;
    jobject self = data->window;
    jboolean state = data->isFSEMState;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    AwtWindow *window = (AwtWindow *)pData;

    window->setFullScreenExclusiveModeState(state != 0);

  ret:
    env->DeleteGlobalRef(self);
    delete data;
}

void AwtWindow::_GetNativeWindowSize(void* param) {

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SizeStruct *ss = (SizeStruct *)param;
    jobject self = ss->window;
    AwtWindow *window = NULL;
    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    window = (AwtWindow *)pData;

    RECT rc;
    ::GetWindowRect(window->GetHWnd(), &rc);
    ss->w = rc.right - rc.left;
    ss->h = rc.bottom - rc.top;

    env->DeleteGlobalRef(self);
}

extern "C" {

/*
 * Class:     java_awt_Window
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_awt_Window_initIDs(JNIEnv *env, jclass cls)
{
    TRY;

    CHECK_NULL(AwtWindow::warningStringID =
        env->GetFieldID(cls, "warningString", "Ljava/lang/String;"));
    CHECK_NULL(AwtWindow::locationByPlatformID =
        env->GetFieldID(cls, "locationByPlatform", "Z"));
    CHECK_NULL(AwtWindow::securityWarningWidthID =
        env->GetFieldID(cls, "securityWarningWidth", "I"));
    CHECK_NULL(AwtWindow::securityWarningHeightID =
        env->GetFieldID(cls, "securityWarningHeight", "I"));
    CHECK_NULL(AwtWindow::getWarningStringMID =
        env->GetMethodID(cls, "getWarningString", "()Ljava/lang/String;"));
    CHECK_NULL(AwtWindow::autoRequestFocusID =
        env->GetFieldID(cls, "autoRequestFocus", "Z"));
    CHECK_NULL(AwtWindow::calculateSecurityWarningPositionMID =
        env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;"));

    jclass windowTypeClass = env->FindClass("java/awt/Window$Type");
    CHECK_NULL(windowTypeClass);
    AwtWindow::windowTypeNameMID =
        env->GetMethodID(windowTypeClass, "name", "()Ljava/lang/String;");
    env->DeleteLocalRef(windowTypeClass);

    CATCH_BAD_ALLOC;
}

} /* extern "C" */


/************************************************************************
 * WindowPeer native methods
 */

extern "C" {

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
{
    TRY;

    CHECK_NULL(AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I"));
    CHECK_NULL(AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I"));
    CHECK_NULL(AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"));
    CHECK_NULL(AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"));

    AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType",
            "Ljava/awt/Window$Type;");

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    toFront
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1toFront(JNIEnv *env, jobject self)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToFront,
        env->NewGlobalRef(self));
    // global ref is deleted in _ToFront()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    toBack
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_toBack(JNIEnv *env, jobject self)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_ToBack,
        env->NewGlobalRef(self));
    // global ref is deleted in _ToBack()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setAlwaysOnTop
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setAlwaysOnTopNative(JNIEnv *env, jobject self,
                                                jboolean value)
{
    TRY;

    SetAlwaysOnTopStruct *sas = new SetAlwaysOnTopStruct;
    sas->window = env->NewGlobalRef(self);
    sas->value = value;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetAlwaysOnTop, sas);
    // global ref and sas are deleted in _SetAlwaysOnTop

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    _setTitle
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1setTitle(JNIEnv *env, jobject self,
                                            jstring title)
{
    TRY;

    SetTitleStruct *sts = new SetTitleStruct;
    sts->window = env->NewGlobalRef(self);
    sts->title = (jstring)env->NewGlobalRef(title);

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetTitle, sts);
    /// global refs and sts are deleted in _SetTitle()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    _setResizable
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer__1setResizable(JNIEnv *env, jobject self,
                                                jboolean resizable)
{
    TRY;

    SetResizableStruct *srs = new SetResizableStruct;
    srs->window = env->NewGlobalRef(self);
    srs->resizable = resizable;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetResizable, srs);
    // global ref and srs are deleted in _SetResizable

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    create
 * Signature: (Lsun/awt/windows/WComponentPeer;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_createAwtWindow(JNIEnv *env, jobject self,
                                                 jobject parent)
{
    TRY;

    PDATA pData;
//    JNI_CHECK_PEER_RETURN(parent);
    AwtToolkit::CreateComponent(self, parent,
                                (AwtToolkit::ComponentFactory)
                                AwtWindow::Create);
    JNI_CHECK_PEER_CREATION_RETURN(self);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    updateInsets
 * Signature: (Ljava/awt/Insets;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateInsets(JNIEnv *env, jobject self,
                                              jobject insets)
{
    TRY;

    UpdateInsetsStruct *uis = new UpdateInsetsStruct;
    uis->window = env->NewGlobalRef(self);
    uis->insets = env->NewGlobalRef(insets);

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_UpdateInsets, uis);
    // global refs and uis are deleted in _UpdateInsets()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    reshapeFrame
 * Signature: (IIII)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_reshapeFrame(JNIEnv *env, jobject self,
                                        jint x, jint y, jint w, jint h)
{
    TRY;

    ReshapeFrameStruct *rfs = new ReshapeFrameStruct;
    rfs->frame = env->NewGlobalRef(self);
    rfs->x = x;
    rfs->y = y;
    rfs->w = w;
    rfs->h = h;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_ReshapeFrame, rfs);
    // global ref and rfs are deleted in _ReshapeFrame()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
* Method:    getNativeWindowSize
* Signature: ()Ljava/awt/Dimension;
*/
JNIEXPORT jobject JNICALL Java_sun_awt_windows_WWindowPeer_getNativeWindowSize
(JNIEnv *env, jobject self) {

    jobject res = NULL;
    TRY;
    SizeStruct *ss = new SizeStruct;
    ss->window = env->NewGlobalRef(self);

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_GetNativeWindowSize, ss);

    int w = ss->w;
    int h = ss->h;

    delete ss;
    // global ref is deleted in _GetNativeWindowSize()

    static jmethodID dimMID = NULL;
    static jclass dimClassID = NULL;
    if (dimClassID == NULL) {
        jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
        CHECK_NULL_RETURN(dimClassIDLocal, NULL);
        dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
        env->DeleteLocalRef(dimClassIDLocal);
    }

    if (dimMID == NULL) {
        dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
        CHECK_NULL_RETURN(dimMID, NULL);
    }

    return env->NewObject(dimClassID, dimMID, w, h);

    CATCH_BAD_ALLOC_RET(NULL);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getSysMinWidth
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysMinWidth(JNIEnv *env, jclass self)
{
    TRY;

    return ::GetSystemMetrics(SM_CXMIN);

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getSysMinHeight
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysMinHeight(JNIEnv *env, jclass self)
{
    TRY;

    return ::GetSystemMetrics(SM_CYMIN);

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getSysIconHeight
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysIconHeight(JNIEnv *env, jclass self)
{
    TRY;

    return ::GetSystemMetrics(SM_CYICON);

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getSysIconWidth
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysIconWidth(JNIEnv *env, jclass self)
{
    TRY;

    return ::GetSystemMetrics(SM_CXICON);

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getSysSmIconHeight
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysSmIconHeight(JNIEnv *env, jclass self)
{
    TRY;

    return ::GetSystemMetrics(SM_CYSMICON);

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getSysSmIconWidth
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getSysSmIconWidth(JNIEnv *env, jclass self)
{
    TRY;

    return ::GetSystemMetrics(SM_CXSMICON);

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setIconImagesData
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setIconImagesData(JNIEnv *env, jobject self,
    jintArray iconRaster, jint w, jint h,
    jintArray smallIconRaster, jint smw, jint smh)
{
    TRY;

    SetIconImagesDataStruct *sims = new SetIconImagesDataStruct;

    sims->window = env->NewGlobalRef(self);
    sims->iconRaster = (jintArray)env->NewGlobalRef(iconRaster);
    sims->w = w;
    sims->h = h;
    sims->smallIconRaster = (jintArray)env->NewGlobalRef(smallIconRaster);
    sims->smw = smw;
    sims->smh = smh;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetIconImagesData, sims);
    // global refs and sims are deleted in _SetIconImagesData()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setMinSize
 * Signature: (Lsun/awt/windows/WWindowPeer;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setMinSize(JNIEnv *env, jobject self,
                                              jint w, jint h)
{
    TRY;

    SizeStruct *ss = new SizeStruct;
    ss->window = env->NewGlobalRef(self);
    ss->w = w;
    ss->h = h;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetMinSize, ss);
    // global refs and mds are deleted in _SetMinSize

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    getScreenImOn
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self)
{
    TRY;

    return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall(
        (void *(*)(void *))AwtWindow::_GetScreenImOn,
        env->NewGlobalRef(self))));
    // global ref is deleted in _GetScreenImOn()

    CATCH_BAD_ALLOC_RET(-1);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setFullScreenExclusiveModeState
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env,
        jobject self, jboolean state)
{
    TRY;

    SetFullScreenExclusiveModeStateStruct *data =
        new SetFullScreenExclusiveModeStateStruct;
    data->window = env->NewGlobalRef(self);
    data->isFSEMState = state;

    AwtToolkit::GetInstance().SyncCall(
            AwtWindow::_SetFullScreenExclusiveModeState, data);
    // global ref and data are deleted in the invoked method

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    modalDisable
 * Signature: (J)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_modalDisable(JNIEnv *env, jobject self,
                                              jobject blocker, jlong blockerHWnd)
{
    TRY;

    ModalDisableStruct *mds = new ModalDisableStruct;
    mds->window = env->NewGlobalRef(self);
    mds->blockerHWnd = blockerHWnd;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalDisable, mds);
    // global ref and mds are deleted in _ModalDisable

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    modalEnable
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_modalEnable(JNIEnv *env, jobject self, jobject blocker)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_ModalEnable,
        env->NewGlobalRef(self));
    // global ref is deleted in _ModalEnable

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setFocusableWindow
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setFocusableWindow(JNIEnv *env, jobject self, jboolean isFocusableWindow)
{
    TRY;

    SetFocusableWindowStruct *sfws = new SetFocusableWindowStruct;
    sfws->window = env->NewGlobalRef(self);
    sfws->isFocusableWindow = isFocusableWindow;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetFocusableWindow, sfws);
    // global ref and sfws are deleted in _SetFocusableWindow()

    CATCH_BAD_ALLOC;
}

JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_nativeGrab(JNIEnv *env, jobject self)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_Grab, env->NewGlobalRef(self));
    // global ref is deleted in _Grab()

    CATCH_BAD_ALLOC;
}

JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_nativeUngrab(JNIEnv *env, jobject self)
{
    TRY;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_Ungrab, env->NewGlobalRef(self));
    // global ref is deleted in _Ungrab()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setOpacity
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpacity(JNIEnv *env, jobject self,
                                              jint iOpacity)
{
    TRY;

    OpacityStruct *os = new OpacityStruct;
    os->window = env->NewGlobalRef(self);
    os->iOpacity = iOpacity;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpacity, os);
    // global refs and mds are deleted in _SetMinSize

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    setOpaqueImpl
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setOpaqueImpl(JNIEnv *env, jobject self,
                                              jboolean isOpaque)
{
    TRY;

    OpaqueStruct *os = new OpaqueStruct;
    os->window = env->NewGlobalRef(self);
    os->isOpaque = isOpaque;

    AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetOpaque, os);
    // global refs and mds are deleted in _SetMinSize

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    updateWindowImpl
 * Signature: ([III)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_updateWindowImpl(JNIEnv *env, jobject self,
                                                  jintArray data,
                                                  jint width, jint height)
{
    TRY;

    UpdateWindowStruct *uws = new UpdateWindowStruct;
    uws->window = env->NewGlobalRef(self);
    uws->data = (jintArray)env->NewGlobalRef(data);
    uws->hBitmap = NULL;
    uws->width = width;
    uws->height = height;

    AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
    // global refs and mds are deleted in _UpdateWindow

    CATCH_BAD_ALLOC;
}

/**
 * This method is called from the WGL pipeline when it needs to update
 * the layered window WindowPeer's C++ level object.
 */
void AwtWindow_UpdateWindow(JNIEnv *env, jobject peer,
                            jint width, jint height, HBITMAP hBitmap)
{
    TRY;

    UpdateWindowStruct *uws = new UpdateWindowStruct;
    uws->window = env->NewGlobalRef(peer);
    uws->data = NULL;
    uws->hBitmap = hBitmap;
    uws->width = width;
    uws->height = height;

    AwtToolkit::GetInstance().InvokeFunction(AwtWindow::_UpdateWindow, uws);
    // global refs and mds are deleted in _UpdateWindow

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WComponentPeer
 * Method:    requestFocus
 * Signature: (Z)Z
 */
JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WWindowPeer_requestWindowFocus
    (JNIEnv *env, jobject self, jboolean isMouseEventCause)
{
    TRY;

    jobject selfGlobalRef = env->NewGlobalRef(self);

    RequestWindowFocusStruct *rfs = new RequestWindowFocusStruct;
    rfs->component = selfGlobalRef;
    rfs->isMouseEventCause = isMouseEventCause;

    return (jboolean)AwtToolkit::GetInstance().SyncCall(
        (void*(*)(void*))AwtWindow::_RequestWindowFocus, rfs);
    // global refs and rfs are deleted in _RequestWindowFocus

    CATCH_BAD_ALLOC_RET(JNI_FALSE);
}

/*
 * Class:     sun_awt_windows_WWindowPeer
 * Method:    repositionSecurityWarning
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env,
        jobject self)
{
    TRY;

    RepositionSecurityWarningStruct *rsws =
        new RepositionSecurityWarningStruct;
    rsws->window = env->NewGlobalRef(self);

    AwtToolkit::GetInstance().InvokeFunction(
            AwtWindow::_RepositionSecurityWarning, rsws);
    // global refs and mds are deleted in _RepositionSecurityWarning

    CATCH_BAD_ALLOC;
}

} /* extern "C" */