/*
 * Copyright (c) 2005, 2008, 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 <windowsx.h>
#include <shellapi.h>
#include <shlwapi.h>

#include "awt_Toolkit.h"
#include "awt_TrayIcon.h"
#include "awt_AWTEvent.h"

#include <java_awt_event_InputEvent.h>

/***********************************************************************/
// Struct for _SetToolTip() method
struct SetToolTipStruct {
    jobject trayIcon;
    jstring tooltip;
};
// Struct for _SetIcon() method
struct SetIconStruct {
    jobject trayIcon;
    HICON hIcon;
};
// Struct for _UpdateIcon() method
struct UpdateIconStruct {
    jobject trayIcon;
    jboolean update;
};
// Struct for _DisplayMessage() method
struct DisplayMessageStruct {
    jobject trayIcon;
    jstring caption;
    jstring text;
    jstring msgType;
};

typedef struct tagBitmapheader  {
    BITMAPV5HEADER bmiHeader;
    DWORD            dwMasks[256];
} Bitmapheader, *LPBITMAPHEADER;


/************************************************************************
 * AwtTrayIcon fields
 */

jfieldID AwtTrayIcon::idID;
jfieldID AwtTrayIcon::actionCommandID;

HWND AwtTrayIcon::sm_msgWindow = NULL;
AwtTrayIcon::TrayIconListItem* AwtTrayIcon::sm_trayIconList = NULL;
int AwtTrayIcon::sm_instCount = 0;

/************************************************************************
 * AwtTrayIcon methods
 */

AwtTrayIcon::AwtTrayIcon() {
    ::ZeroMemory(&m_nid, sizeof(m_nid));

    if (sm_instCount++ == 0 && AwtTrayIcon::sm_msgWindow == NULL) {
        sm_msgWindow = AwtTrayIcon::CreateMessageWindow();
    }
    m_mouseButtonClickAllowed = 0;
}

AwtTrayIcon::~AwtTrayIcon() {
}

void AwtTrayIcon::Dispose() {
    SendTrayMessage(NIM_DELETE);
    UnlinkObjects();

    if (--sm_instCount == 0) {
        AwtTrayIcon::DestroyMessageWindow();
    }

    AwtObject::Dispose();
}

LPCTSTR AwtTrayIcon::GetClassName() {
    return TEXT("SunAwtTrayIcon");
}

void AwtTrayIcon::FillClassInfo(WNDCLASS *lpwc)
{
    lpwc->style         = 0L;
    lpwc->lpfnWndProc   = (WNDPROC)TrayWindowProc;
    lpwc->cbClsExtra    = 0;
    lpwc->cbWndExtra    = 0;
    lpwc->hInstance     = AwtToolkit::GetInstance().GetModuleHandle(),
    lpwc->hIcon         = AwtToolkit::GetInstance().GetAwtIcon();
    lpwc->hCursor       = NULL;
    lpwc->hbrBackground = NULL;
    lpwc->lpszMenuName  = NULL;
    lpwc->lpszClassName = AwtTrayIcon::GetClassName();
}

void AwtTrayIcon::RegisterClass()
{
    WNDCLASS  wc;

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

    if (!::GetClassInfo(AwtToolkit::GetInstance().GetModuleHandle(),
                        AwtTrayIcon::GetClassName(), &wc))
    {
        AwtTrayIcon::FillClassInfo(&wc);
        ATOM atom = ::RegisterClass(&wc);
        DASSERT(atom != 0);
    }
}

void AwtTrayIcon::UnregisterClass()
{
    ::UnregisterClass(AwtTrayIcon::GetClassName(), AwtToolkit::GetInstance().GetModuleHandle());
}

HWND AwtTrayIcon::CreateMessageWindow()
{
    AwtTrayIcon::RegisterClass();

    HWND hWnd = ::CreateWindow(AwtTrayIcon::GetClassName(), TEXT("TrayMessageWindow"),
                               0, 0, 0, 0, 0, NULL, NULL,
                               AwtToolkit::GetInstance().GetModuleHandle(), NULL);
    return hWnd;
}

void AwtTrayIcon::DestroyMessageWindow()
{
    ::DestroyWindow(AwtTrayIcon::sm_msgWindow);
    AwtTrayIcon::sm_msgWindow = NULL;
    AwtTrayIcon::UnregisterClass();
}

AwtTrayIcon* AwtTrayIcon::Create(jobject self, jobject parent)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jobject target = NULL;
    AwtTrayIcon* awtTrayIcon = NULL;

    target  = env->GetObjectField(self, AwtObject::targetID);
    DASSERT(target);

    awtTrayIcon = new AwtTrayIcon();
    awtTrayIcon->LinkObjects(env, self);
    awtTrayIcon->InitNID(env->GetIntField(target, AwtTrayIcon::idID));
    awtTrayIcon->AddTrayIconItem(awtTrayIcon->GetID());

    env->DeleteLocalRef(target);
    return awtTrayIcon;
}

void AwtTrayIcon::InitNID(UINT uID)
{
    // fix for 6271589: we MUST set the size of the structure to match
    // the shell version, otherwise some errors may occur (like missing
    // balloon messages on win2k)
    DLLVERSIONINFO dllVersionInfo;
    dllVersionInfo.cbSize = sizeof(DLLVERSIONINFO);
    int shellVersion = 5; // WIN_2000
    // MSDN: DllGetVersion should not be implicitly called, but rather
    // loaded using GetProcAddress
    HMODULE hShell = LoadLibrary(TEXT("Shell32.dll"));
    if (hShell != NULL) {
        DLLGETVERSIONPROC proc = (DLLGETVERSIONPROC)GetProcAddress(hShell, "DllGetVersion");
        if (proc != NULL) {
            if (proc(&dllVersionInfo) == NOERROR) {
                shellVersion = dllVersionInfo.dwMajorVersion;
            }
        }
    }
    FreeLibrary(hShell);
    switch (shellVersion) {
        case 5: // WIN_2000
            m_nid.cbSize = (BYTE *)(&m_nid.guidItem) - (BYTE *)(&m_nid.cbSize);
            break;
        case 6: // WIN_XP
            // Uncomment these two lines when moving to VS2008
//            m_nid.cbSize = (BYTE *)(&m_nid.hBalloonIcon) - (BYTE *)(&m_nid.cbSize);
//            break;
        default: // WIN_VISTA?
            m_nid.cbSize = sizeof(m_nid);
            break;
    }
    m_nid.hWnd = AwtTrayIcon::sm_msgWindow;
    m_nid.uID = uID;
    m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
    m_nid.uCallbackMessage = WM_AWT_TRAY_NOTIFY;
    m_nid.hIcon = AwtToolkit::GetInstance().GetAwtIcon();
    m_nid.szTip[0] = '\0';
    m_nid.uVersion = NOTIFYICON_VERSION;
}

BOOL AwtTrayIcon::SendTrayMessage(DWORD dwMessage)
{
    return Shell_NotifyIcon(dwMessage, (PNOTIFYICONDATA)&m_nid);
}

static UINT lastMessage = WM_NULL;

LRESULT CALLBACK AwtTrayIcon::TrayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LRESULT retValue = 0;
    MsgRouting mr = mrDoDefault;
    static UINT s_msgTaskbarCreated;

    switch(uMsg)
    {
        case WM_CREATE:
            // Fix for CR#6369062
            s_msgTaskbarCreated = ::RegisterWindowMessage(TEXT("TaskbarCreated"));
            break;
        case WM_AWT_TRAY_NOTIFY:
            if (hwnd == AwtTrayIcon::sm_msgWindow) {
                AwtTrayIcon* trayIcon = AwtTrayIcon::SearchTrayIconItem((UINT)wParam);
                if (trayIcon != NULL) {
                    mr = trayIcon->WmAwtTrayNotify(wParam, lParam);
                }
            }
            break;
        default:
            if(uMsg == s_msgTaskbarCreated) {
                if (hwnd == AwtTrayIcon::sm_msgWindow) {
                    mr = WmTaskbarCreated();
                }
            }
            break;
    }

    if (mr != mrConsume) {
        retValue = ::DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return retValue;
}

/*
 * This function processes callback messages for taskbar icons.
 */
MsgRouting AwtTrayIcon::WmAwtTrayNotify(WPARAM wParam, LPARAM lParam)
{
    MsgRouting mr = mrDoDefault;

    POINT pos = {0, 0};
    ::GetCursorPos(&pos);

    lastMessage = (UINT)lParam;
    UINT flags = AwtToolkit::GetInstance().GetMouseKeyState();

    switch((UINT)lParam)
    {
        case WM_MOUSEMOVE:
            mr = WmMouseMove(flags, pos.x, pos.y);
            break;
        case WM_LBUTTONDBLCLK:
        case WM_LBUTTONDOWN:
            mr = WmMouseDown(flags, pos.x, pos.y, LEFT_BUTTON);
            break;
        case WM_LBUTTONUP:
            mr = WmMouseUp(flags, pos.x, pos.y, LEFT_BUTTON);
            break;
        case WM_RBUTTONDBLCLK:
        case WM_RBUTTONDOWN:
            mr = WmMouseDown(flags, pos.x, pos.y, RIGHT_BUTTON);
            break;
        case WM_RBUTTONUP:
            mr = WmMouseUp(flags, pos.x, pos.y, RIGHT_BUTTON);
            break;
        case WM_MBUTTONDBLCLK:
        case WM_MBUTTONDOWN:
            mr = WmMouseDown(flags, pos.x, pos.y, MIDDLE_BUTTON);
            break;
        case WM_MBUTTONUP:
            mr = WmMouseUp(flags, pos.x, pos.y, MIDDLE_BUTTON);
            break;
        case WM_CONTEXTMENU:
            mr = WmContextMenu(0, pos.x, pos.y);
            break;
        case NIN_KEYSELECT:
            mr = WmKeySelect(0, pos.x, pos.y);
            break;
        case NIN_SELECT:
            mr = WmSelect(0, pos.x, pos.y);
            break;
        case NIN_BALLOONUSERCLICK:
            mr = WmBalloonUserClick(0, pos.x, pos.y);
            break;
    }
    return mr;
}

/* Double-click variables. */
static jlong multiClickTime = ::GetDoubleClickTime();
static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK);
static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK);
static AwtTrayIcon* lastClickTrIc = NULL;
static jlong lastTime = 0;
static int lastClickX = 0;
static int lastClickY = 0;
static int lastButton = 0;
static int clickCount = 0;

MsgRouting AwtTrayIcon::WmMouseDown(UINT flags, int x, int y, int button)
{
    jlong now = TimeHelper::windowsToUTC(::GetTickCount());
    jint javaModif = AwtComponent::GetJavaModifiers();

    if (lastClickTrIc == this &&
        lastButton == button &&
        (now - lastTime) <= multiClickTime &&
        abs(x - lastClickX) <= multiClickMaxX &&
        abs(y - lastClickY) <= multiClickMaxY)
    {
        clickCount++;
    } else {
        clickCount = 1;
        lastClickTrIc = this;
        lastButton = button;
        lastClickX = x;
        lastClickY = y;
    }
    lastTime = now;
    // it's needed only if WM_LBUTTONUP doesn't come for some reason
    m_mouseButtonClickAllowed |= AwtComponent::GetButtonMK(button);

    MSG msg;
    AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);

    SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
                   javaModif, clickCount, JNI_FALSE,
                   AwtComponent::GetButton(button), &msg);

    return mrConsume;
}

MsgRouting AwtTrayIcon::WmMouseUp(UINT flags, int x, int y, int button)
{
    MSG msg;
    AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);

    SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::windowsToUTC(::GetTickCount()),
                   x, y, AwtComponent::GetJavaModifiers(), clickCount,
                   (AwtComponent::GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ?
                    TRUE : FALSE), AwtComponent::GetButton(button), &msg);

    if ((m_mouseButtonClickAllowed & AwtComponent::GetButtonMK(button)) != 0) { // No up-button in the drag-state
        SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED,
                       TimeHelper::windowsToUTC(::GetTickCount()), x, y, AwtComponent::GetJavaModifiers(),
                       clickCount, JNI_FALSE, AwtComponent::GetButton(button));
    }
    m_mouseButtonClickAllowed &= ~AwtComponent::GetButtonMK(button); // Exclude the up-button from the drag-state

    return mrConsume;
}

MsgRouting AwtTrayIcon::WmMouseMove(UINT flags, int x, int y)
{
    MSG msg;
    static AwtTrayIcon* lastComp = NULL;
    static int lastX = 0;
    static int lastY = 0;

    /*
     * Workaround for CR#6267980
     * Windows sends WM_MOUSEMOVE if mouse is motionless
     */
    if (lastComp != this || x != lastX || y != lastY) {
        lastComp = this;
        lastX = x;
        lastY = y;
        AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
        if ((flags & ALL_MK_BUTTONS) != 0) {
            m_mouseButtonClickAllowed = 0;
        } else {
            SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::windowsToUTC(::GetTickCount()), x, y,
                           AwtComponent::GetJavaModifiers(), 0, JNI_FALSE,
                           java_awt_event_MouseEvent_NOBUTTON, &msg);
        }
    }
    return mrConsume;
}

MsgRouting AwtTrayIcon::WmBalloonUserClick(UINT flags, int x, int y)
{
    if (AwtComponent::GetJavaModifiers() & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) {
        MSG msg;
        AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
        SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()),
                        AwtComponent::GetJavaModifiers(), &msg);
    }
    return mrConsume;
}

MsgRouting AwtTrayIcon::WmKeySelect(UINT flags, int x, int y)
{
    static jlong lastKeySelectTime = 0;
    jlong now = TimeHelper::windowsToUTC(::GetTickCount());

    // If a user selects a notify icon with the ENTER key,
    // Shell 5.0 sends double NIN_KEYSELECT notification.
    if (lastKeySelectTime != now) {
        MSG msg;
        AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
        SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()),
                        AwtComponent::GetJavaModifiers(), &msg);
    }
    lastKeySelectTime = now;

    return mrConsume;
}

MsgRouting AwtTrayIcon::WmSelect(UINT flags, int x, int y)
{

    // If a user click on a notify icon with the mouse,
    // Shell 5.0 sends NIN_SELECT notification on every click.
    // To be compatible with JDK6.0 only second click is important.
    if (clickCount == 2) {
        MSG msg;
        AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
        SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()),
                        AwtComponent::GetJavaModifiers(), &msg);
    }
    return mrConsume;
}

MsgRouting AwtTrayIcon::WmContextMenu(UINT flags, int x, int y)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jobject peer = GetPeer(env);
    if (peer != NULL) {
        JNU_CallMethodByName(env, NULL, peer, "showPopupMenu",
                             "(II)V", x, y);
    }
    return mrConsume;
}

/*
 * Adds all icons we already have to taskbar.
 * We use this method on taskbar recreation (see 6369062).
 */
MsgRouting AwtTrayIcon::WmTaskbarCreated() {
    TrayIconListItem* item;
    for (item = sm_trayIconList; item != NULL; item = item->m_next) {
        BOOL result = item->m_trayIcon->SendTrayMessage(NIM_ADD);
        // 6270114: Instructs the taskbar to behave according to the Shell version 5.0
        if (result) {
            item->m_trayIcon->SendTrayMessage(NIM_SETVERSION);
        }
    }
    return mrDoDefault;
}

void AwtTrayIcon::SendMouseEvent(jint id, jlong when, jint x, jint y,
                                 jint modifiers, jint clickCount,
                                 jboolean popupTrigger, jint button,
                                 MSG *pMsg)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (GetPeer(env) == NULL) {
        /* event received during termination. */
        return;
    }

    static jclass mouseEventCls;
    if (mouseEventCls == NULL) {
        jclass mouseEventClsLocal =
            env->FindClass("java/awt/event/MouseEvent");
        if (!mouseEventClsLocal) {
            /* exception already thrown */
            return;
        }
        mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal);
        env->DeleteLocalRef(mouseEventClsLocal);
    }

    static jmethodID mouseEventConst;
    if (mouseEventConst == NULL) {
        mouseEventConst =
            env->GetMethodID(mouseEventCls, "<init>",
                             "(Ljava/awt/Component;IJIIIIIIZI)V");
        DASSERT(mouseEventConst);
    }
    if (env->EnsureLocalCapacity(2) < 0) {
        return;
    }
    jobject target = GetTarget(env);
    jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst,
                                        target,
                                        id, when, modifiers,
                                        x, y, // no client area coordinates
                                        x, y,
                                        clickCount, popupTrigger, button);

    if (safe_ExceptionOccurred(env)) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }

    DASSERT(mouseEvent != NULL);
    if (pMsg != 0) {
        AwtAWTEvent::saveMSG(env, pMsg, mouseEvent);
    }
    SendEvent(mouseEvent);

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

void AwtTrayIcon::SendActionEvent(jint id, jlong when, jint modifiers, MSG *pMsg)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (GetPeer(env) == NULL) {
        /* event received during termination. */
        return;
    }

    static jclass actionEventCls;
    if (actionEventCls == NULL) {
        jclass actionEventClsLocal =
            env->FindClass("java/awt/event/ActionEvent");
        if (!actionEventClsLocal) {
            /* exception already thrown */
            return;
        }
        actionEventCls = (jclass)env->NewGlobalRef(actionEventClsLocal);
        env->DeleteLocalRef(actionEventClsLocal);
    }

    static jmethodID actionEventConst;
    if (actionEventConst == NULL) {
        actionEventConst =
            env->GetMethodID(actionEventCls, "<init>",
                             "(Ljava/lang/Object;ILjava/lang/String;JI)V");
        DASSERT(actionEventConst);
    }
    if (env->EnsureLocalCapacity(2) < 0) {
        return;
    }
    jobject target = GetTarget(env);
    jstring actionCommand = (jstring)env->GetObjectField(target, AwtTrayIcon::actionCommandID);
    jobject actionEvent = env->NewObject(actionEventCls, actionEventConst,
                                         target, id, actionCommand, when, modifiers);

    if (safe_ExceptionOccurred(env)) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }

    DASSERT(actionEvent != NULL);
    if (pMsg != 0) {
        AwtAWTEvent::saveMSG(env, pMsg, actionEvent);
    }
    SendEvent(actionEvent);

    env->DeleteLocalRef(actionEvent);
    env->DeleteLocalRef(target);
    env->DeleteLocalRef(actionCommand);
}

AwtTrayIcon* AwtTrayIcon::SearchTrayIconItem(UINT id) {
    TrayIconListItem* item;
    for (item = sm_trayIconList; item != NULL; item = item->m_next) {
        if (item->m_ID == id) {
            return item->m_trayIcon;
        }
    }
    /*
     * DASSERT(FALSE);
     * This should not be happend if all tray icons are recorded
     */
    return NULL;
}

void AwtTrayIcon::RemoveTrayIconItem(UINT id) {
    TrayIconListItem* item = sm_trayIconList;
    TrayIconListItem* lastItem = NULL;
    while (item != NULL) {
        if (item->m_ID == id) {
            if (lastItem == NULL) {
                sm_trayIconList = item->m_next;
            } else {
                lastItem->m_next = item->m_next;
            }
            item->m_next = NULL;
            DASSERT(item != NULL);
            delete item;
            return;
        }
        lastItem = item;
        item = item->m_next;
    }
}

void AwtTrayIcon::LinkObjects(JNIEnv *env, jobject peer)
{
    if (m_peerObject == NULL) {
        m_peerObject = env->NewGlobalRef(peer);
    }

    /* Bind JavaPeer -> C++*/
    JNI_SET_PDATA(peer, this);
}

void AwtTrayIcon::UnlinkObjects()
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (m_peerObject) {
        JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
        env->DeleteGlobalRef(m_peerObject);
        m_peerObject = NULL;
    }
}

HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH)
{
    Bitmapheader    bmhHeader = {0};
    HDC             hDC;
    char            *ptrImageData;
    HBITMAP         hbmpBitmap;
    HBITMAP         hBitmap;
    int             nNumChannels    = 4;

    if (!hW) {
        hW = ::GetDesktopWindow();
    }
    hDC = ::GetDC(hW);
    if (!hDC) {
        return NULL;
    }

    bmhHeader.bmiHeader.bV5Size              = sizeof(BITMAPV5HEADER);
    bmhHeader.bmiHeader.bV5Width             = nW;
    bmhHeader.bmiHeader.bV5Height            = -nH;
    bmhHeader.bmiHeader.bV5Planes            = 1;

    bmhHeader.bmiHeader.bV5BitCount          = 32;
    bmhHeader.bmiHeader.bV5Compression       = BI_BITFIELDS;

    // The following mask specification specifies a supported 32 BPP
    // alpha format for Windows XP.
    bmhHeader.bmiHeader.bV5RedMask   =  0x00FF0000;
    bmhHeader.bmiHeader.bV5GreenMask =  0x0000FF00;
    bmhHeader.bmiHeader.bV5BlueMask  =  0x000000FF;
    bmhHeader.bmiHeader.bV5AlphaMask =  0xFF000000;

    hbmpBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bmhHeader),
                                    DIB_RGB_COLORS,
                                    (void**)&(ptrImageData),
                                    NULL, 0);
    int  *srcPtr = imageData;
    char *dstPtr = ptrImageData;
    if (!dstPtr) {
        ReleaseDC(hW, hDC);
        return NULL;
    }
    for (int nOutern = 0; nOutern < nH; nOutern++) {
        for (int nInner = 0; nInner < nSS; nInner++) {
            dstPtr[3] = (*srcPtr >> 0x18) & 0xFF;
            dstPtr[2] = (*srcPtr >> 0x10) & 0xFF;
            dstPtr[1] = (*srcPtr >> 0x08) & 0xFF;
            dstPtr[0] = *srcPtr & 0xFF;

            srcPtr++;
            dstPtr += nNumChannels;
        }
    }

    // convert it into DDB to make CustomCursor work on WIN95
    hBitmap = CreateDIBitmap(hDC,
                             (BITMAPINFOHEADER*)&bmhHeader,
                             CBM_INIT,
                             (void *)ptrImageData,
                             (BITMAPINFO*)&bmhHeader,
                             DIB_RGB_COLORS);

    ::DeleteObject(hbmpBitmap);
    ::ReleaseDC(hW, hDC);
//  ::GdiFlush();
    return hBitmap;
}

void AwtTrayIcon::SetToolTip(LPCTSTR tooltip)
{
    if (tooltip == NULL) {
        m_nid.szTip[0] = '\0';
    } else if (lstrlen(tooltip) > TRAY_ICON_TOOLTIP_MAX_SIZE) {
        _tcsncpy(m_nid.szTip, tooltip, TRAY_ICON_TOOLTIP_MAX_SIZE);
        m_nid.szTip[TRAY_ICON_TOOLTIP_MAX_SIZE - 1] = '\0';
    } else {
        _tcscpy(m_nid.szTip, tooltip);
    }

    SendTrayMessage(NIM_MODIFY);
}

void AwtTrayIcon::_SetToolTip(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    SetToolTipStruct *sts = (SetToolTipStruct *)param;
    jobject self = sts->trayIcon;
    jstring jtooltip = sts->tooltip;
    AwtTrayIcon *trayIcon = NULL;
    LPCTSTR tooltipStr = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    trayIcon = (AwtTrayIcon *)pData;

    if (jtooltip == NULL) {
        trayIcon->SetToolTip(NULL);
        goto ret;
    }

    tooltipStr = JNU_GetStringPlatformChars(env, jtooltip, (jboolean *)NULL);
    trayIcon->SetToolTip(tooltipStr);
    JNU_ReleaseStringPlatformChars(env, jtooltip, tooltipStr);
ret:
    env->DeleteGlobalRef(self);
    env->DeleteGlobalRef(jtooltip);
    delete sts;
}

void AwtTrayIcon::SetIcon(HICON hIcon)
{
    ::DestroyIcon(m_nid.hIcon);
    m_nid.hIcon = hIcon;
}

void AwtTrayIcon::_SetIcon(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    SetIconStruct *sis = (SetIconStruct *)param;
    jobject self = sis->trayIcon;
    HICON hIcon = sis->hIcon;
    AwtTrayIcon *trayIcon = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    trayIcon = (AwtTrayIcon *)pData;

    trayIcon->SetIcon(hIcon);

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

void AwtTrayIcon::_UpdateIcon(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    UpdateIconStruct *uis = (UpdateIconStruct *)param;
    jobject self = uis->trayIcon;
    jboolean jupdate = uis->update;
    AwtTrayIcon *trayIcon = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    trayIcon = (AwtTrayIcon *)pData;

    BOOL result = trayIcon->SendTrayMessage(jupdate == JNI_TRUE ? NIM_MODIFY : NIM_ADD);
    // 6270114: Instructs the taskbar to behave according to the Shell version 5.0
    if (result && jupdate == JNI_FALSE) {
        trayIcon->SendTrayMessage(NIM_SETVERSION);
    }
ret:
    env->DeleteGlobalRef(self);
    delete uis;
}

void AwtTrayIcon::DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType)
{
    m_nid.uFlags |= NIF_INFO;
    m_nid.uTimeout = 10000;

    if (lstrcmp(msgType, TEXT("ERROR")) == 0) {
        m_nid.dwInfoFlags = NIIF_ERROR;
    } else if (lstrcmp(msgType, TEXT("WARNING")) == 0) {
        m_nid.dwInfoFlags = NIIF_WARNING;
    } else if (lstrcmp(msgType, TEXT("INFO")) == 0) {
        m_nid.dwInfoFlags = NIIF_INFO;
    } else if (lstrcmp(msgType, TEXT("NONE")) == 0) {
        m_nid.dwInfoFlags = NIIF_NONE;
    } else {
        m_nid.dwInfoFlags = NIIF_NONE;
    }

    if (caption[0] == '\0') {
        m_nid.szInfoTitle[0] = '\0';

    } else if (lstrlen(caption) > TRAY_ICON_BALLOON_TITLE_MAX_SIZE) {

        _tcsncpy(m_nid.szInfoTitle, caption, TRAY_ICON_BALLOON_TITLE_MAX_SIZE);
        m_nid.szInfoTitle[TRAY_ICON_BALLOON_TITLE_MAX_SIZE - 1] = '\0';

    } else {
        _tcscpy(m_nid.szInfoTitle, caption);
    }

    if (text[0] == '\0') {
        m_nid.szInfo[0] = ' ';
        m_nid.szInfo[1] = '\0';

    } else if (lstrlen(text) > TRAY_ICON_BALLOON_INFO_MAX_SIZE) {

        _tcsncpy(m_nid.szInfo, text, TRAY_ICON_BALLOON_INFO_MAX_SIZE);
        m_nid.szInfo[TRAY_ICON_BALLOON_INFO_MAX_SIZE - 1] = '\0';

    } else {
        _tcscpy(m_nid.szInfo, text);
    }

    SendTrayMessage(NIM_MODIFY);
    m_nid.uFlags &= ~NIF_INFO;
}

void AwtTrayIcon::_DisplayMessage(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    DisplayMessageStruct *dms = (DisplayMessageStruct *)param;
    jobject self = dms->trayIcon;
    jstring jcaption = dms->caption;
    jstring jtext = dms-> text;
    jstring jmsgType = dms->msgType;
    AwtTrayIcon *trayIcon = NULL;
    LPCTSTR captionStr = NULL;
    LPCTSTR textStr = NULL;
    LPCTSTR msgTypeStr = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    trayIcon = (AwtTrayIcon *)pData;

    captionStr = JNU_GetStringPlatformChars(env, jcaption, (jboolean *)NULL);
    textStr = JNU_GetStringPlatformChars(env, jtext, (jboolean *)NULL);
    msgTypeStr = JNU_GetStringPlatformChars(env, jmsgType, (jboolean *)NULL);

    trayIcon->DisplayMessage(captionStr, textStr, msgTypeStr);

    JNU_ReleaseStringPlatformChars(env, jcaption, captionStr);
    JNU_ReleaseStringPlatformChars(env, jtext, textStr);
    JNU_ReleaseStringPlatformChars(env, jmsgType, msgTypeStr);
ret:
    env->DeleteGlobalRef(self);
    env->DeleteGlobalRef(jcaption);
    env->DeleteGlobalRef(jtext);
    env->DeleteGlobalRef(jmsgType);
    delete dms;
}

/************************************************************************
 * TrayIcon native methods
 */

extern "C" {

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

    /* init field ids */
    AwtTrayIcon::idID = env->GetFieldID(cls, "id", "I");
    AwtTrayIcon::actionCommandID = env->GetFieldID(cls, "actionCommand", "Ljava/lang/String;");

    DASSERT(AwtTrayIcon::idID != NULL);
    DASSERT(AwtTrayIcon::actionCommandID != NULL);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WTrayIconPeer
 * Method:    create
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WTrayIconPeer_create(JNIEnv *env, jobject self)
{
    TRY;

    AwtToolkit::CreateComponent(self, NULL,
                                (AwtToolkit::ComponentFactory)
                                AwtTrayIcon::Create);
    PDATA pData;
    JNI_CHECK_PEER_CREATION_RETURN(self);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WTrayIconPeer
 * Method:    _dispose
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WTrayIconPeer__1dispose(JNIEnv *env, jobject self)
{
    TRY;

    PDATA pData = JNI_GET_PDATA(self);
    AwtObject::_Dispose(pData);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WTrayIconPeer
 * Method:    _setToolTip
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WTrayIconPeer_setToolTip(JNIEnv *env, jobject self,
                                              jstring tooltip)
{
    TRY;

    SetToolTipStruct *sts = new SetToolTipStruct;
    sts->trayIcon = env->NewGlobalRef(self);
    if (tooltip != NULL) {
        sts->tooltip = (jstring)env->NewGlobalRef(tooltip);
    } else {
        sts->tooltip = NULL;
    }

    AwtToolkit::GetInstance().SyncCall(AwtTrayIcon::_SetToolTip, sts);
    // global ref and sts are deleted in _SetToolTip

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WTrayIconPeer
 * Method:    setNativeIcon
 * Signature: (I[B[IIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WTrayIconPeer_setNativeIcon(JNIEnv *env, jobject self,
                                                 jintArray intRasterData, jbyteArray andMask,
                                                 jint nSS, jint nW, jint nH)
{
    TRY;

    int length = env->GetArrayLength(andMask);
    jbyte *andMaskPtr = new jbyte[length];

    env->GetByteArrayRegion(andMask, 0, length, andMaskPtr);

    HBITMAP hMask = ::CreateBitmap(nW, nH, 1, 1, (BYTE *)andMaskPtr);
//    ::GdiFlush();

    delete[] andMaskPtr;

    jint *intRasterDataPtr = NULL;
    HBITMAP hColor = NULL;
    try {
        intRasterDataPtr =
            (jint *)env->GetPrimitiveArrayCritical(intRasterData, 0);
        hColor = AwtTrayIcon::CreateBMP(NULL, (int *)intRasterDataPtr, nSS, nW, nH);
    } catch (...) {
        if (intRasterDataPtr != NULL) {
            env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0);
        }
        ::DeleteObject(hMask);
        throw;
    }

    env->ReleasePrimitiveArrayCritical(intRasterData, intRasterDataPtr, 0);
    intRasterDataPtr = NULL;

    HICON hIcon = NULL;

    if (hMask && hColor) {
        ICONINFO icnInfo;
        memset(&icnInfo, 0, sizeof(ICONINFO));
        icnInfo.hbmMask = hMask;
        icnInfo.hbmColor = hColor;
        icnInfo.fIcon = TRUE;
        icnInfo.xHotspot = TRAY_ICON_X_HOTSPOT;
        icnInfo.yHotspot = TRAY_ICON_Y_HOTSPOT;

        hIcon = ::CreateIconIndirect(&icnInfo);
    }
    ::DeleteObject(hColor);
    ::DeleteObject(hMask);

    //////////////////////////////////////////

    SetIconStruct *sis = new SetIconStruct;
    sis->trayIcon = env->NewGlobalRef(self);
    sis->hIcon = hIcon;

    AwtToolkit::GetInstance().SyncCall(AwtTrayIcon::_SetIcon, sis);
    // global ref is deleted in _SetIcon

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WTrayIconPeer
 * Method:    updateNativeIcon
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WTrayIconPeer_updateNativeIcon(JNIEnv *env, jobject self,
                                                    jboolean doUpdate)
{
    TRY;

    UpdateIconStruct *uis = new UpdateIconStruct;
    uis->trayIcon = env->NewGlobalRef(self);
    uis->update = doUpdate;

    AwtToolkit::GetInstance().SyncCall(AwtTrayIcon::_UpdateIcon, uis);
    // global ref is deleted in _UpdateIcon

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WTrayIconPeer
 * Method:    displayMessage
 * Signature: ()V;
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WTrayIconPeer__1displayMessage(JNIEnv *env, jobject self,
    jstring caption, jstring text, jstring msgType)
{
    TRY;

    DisplayMessageStruct *dms = new DisplayMessageStruct;
    dms->trayIcon = env->NewGlobalRef(self);
    dms->caption = (jstring)env->NewGlobalRef(caption);
    dms->text = (jstring)env->NewGlobalRef(text);
    dms->msgType = (jstring)env->NewGlobalRef(msgType);

    AwtToolkit::GetInstance().SyncCall(AwtTrayIcon::_DisplayMessage, dms);
    // global ref is deleted in _DisplayMessage

    CATCH_BAD_ALLOC(NULL);
}

} /* extern "C" */
