/*
 * X11 system tray management
 *
 * Copyright (C) 2004 Mike Hearn, for CodeWeavers
 * Copyright (C) 2005 Robert Shearman
 * Copyright (C) 2008 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <X11/Xlib.h>

#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "commctrl.h"
#include "shellapi.h"

#include "x11drv.h"
#include "wine/list.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(systray);

/* an individual systray icon */
struct tray_icon
{
    struct list    entry;
    HICON          image;    /* the image to render */
    HWND           owner;    /* the HWND passed in to the Shell_NotifyIcon call */
    HWND           window;   /* the adaptor window */
    HWND           tooltip;  /* Icon tooltip */
    UINT           state;    /* state flags */
    UINT           id;       /* the unique id given by the app */
    UINT           callback_message;
    int            display;  /* display index, or -1 if hidden */
    WCHAR          tiptext[128];    /* tooltip text */
    WCHAR          info_text[256];  /* info balloon text */
    WCHAR          info_title[64];  /* info balloon title */
    UINT           info_flags;      /* flags for info balloon */
    UINT           info_timeout;    /* timeout for info balloon */
    HICON          info_icon;       /* info balloon icon */
};

static struct list icon_list = LIST_INIT( icon_list );

static const WCHAR icon_classname[] = {'_','_','w','i','n','e','x','1','1','_','t','r','a','y','_','i','c','o','n',0};
static const WCHAR tray_classname[] = {'_','_','w','i','n','e','x','1','1','_','s','t','a','n','d','a','l','o','n','e','_','t','r','a','y',0};

static BOOL show_icon( struct tray_icon *icon );
static BOOL hide_icon( struct tray_icon *icon );
static BOOL delete_icon( struct tray_icon *icon );

#define SYSTEM_TRAY_REQUEST_DOCK  0
#define SYSTEM_TRAY_BEGIN_MESSAGE   1
#define SYSTEM_TRAY_CANCEL_MESSAGE  2

Atom systray_atom = 0;

#define MIN_DISPLAYED 8
#define ICON_BORDER 2

#define VALID_WIN_TIMER      1
#define BALLOON_CREATE_TIMER 2
#define BALLOON_SHOW_TIMER   3

#define VALID_WIN_TIMEOUT        2000
#define BALLOON_CREATE_TIMEOUT   2000
#define BALLOON_SHOW_MIN_TIMEOUT 10000
#define BALLOON_SHOW_MAX_TIMEOUT 30000

static struct tray_icon *balloon_icon;
static HWND balloon_window;
static POINT balloon_pos;

/* stand-alone tray window */
static HWND standalone_tray;
static int icon_cx, icon_cy;
static unsigned int nb_displayed;

/* retrieves icon record by owner window and ID */
static struct tray_icon *get_icon(HWND owner, UINT id)
{
    struct tray_icon *this;

    LIST_FOR_EACH_ENTRY( this, &icon_list, struct tray_icon, entry )
        if ((this->id == id) && (this->owner == owner)) return this;
    return NULL;
}

static void init_common_controls(void)
{
    static BOOL initialized = FALSE;

    if (!initialized)
    {
        INITCOMMONCONTROLSEX init_tooltip;

        init_tooltip.dwSize = sizeof(INITCOMMONCONTROLSEX);
        init_tooltip.dwICC = ICC_TAB_CLASSES;

        InitCommonControlsEx(&init_tooltip);
        initialized = TRUE;
    }
}

/* create tooltip window for icon */
static void create_tooltip(struct tray_icon *icon)
{
    init_common_controls();
    icon->tooltip = CreateWindowExW( WS_EX_TOPMOST, TOOLTIPS_CLASSW, NULL,
                                     WS_POPUP | TTS_ALWAYSTIP,
                                     CW_USEDEFAULT, CW_USEDEFAULT,
                                     CW_USEDEFAULT, CW_USEDEFAULT,
                                     icon->window, NULL, NULL, NULL);
    if (icon->tooltip)
    {
        TTTOOLINFOW ti;
        ZeroMemory(&ti, sizeof(ti));
        ti.cbSize = sizeof(TTTOOLINFOW);
        ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
        ti.hwnd = icon->window;
        ti.uId = (UINT_PTR)icon->window;
        ti.lpszText = icon->tiptext;
        SendMessageW(icon->tooltip, TTM_ADDTOOLW, 0, (LPARAM)&ti);
    }
}

void update_systray_balloon_position(void)
{
    RECT rect;
    POINT pos;

    if (!balloon_icon) return;
    GetWindowRect( balloon_icon->window, &rect );
    pos.x = (rect.left + rect.right) / 2;
    pos.y = (rect.top + rect.bottom) / 2;
    if (pos.x == balloon_pos.x && pos.y == balloon_pos.y) return;  /* nothing changed */
    balloon_pos = pos;
    SendMessageW( balloon_window, TTM_TRACKPOSITION, 0, MAKELONG( pos.x, pos.y ));
}

static void balloon_create_timer( struct tray_icon *icon )
{
    TTTOOLINFOW ti;

    init_common_controls();
    balloon_window = CreateWindowExW( WS_EX_TOPMOST, TOOLTIPS_CLASSW, NULL,
                                      WS_POPUP | TTS_ALWAYSTIP | TTS_NOPREFIX | TTS_BALLOON | TTS_CLOSE,
                                      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                                      icon->window, NULL, NULL, NULL);

    memset( &ti, 0, sizeof(ti) );
    ti.cbSize = sizeof(TTTOOLINFOW);
    ti.hwnd = icon->window;
    ti.uId = (UINT_PTR)icon->window;
    ti.uFlags = TTF_TRACK | TTF_IDISHWND;
    ti.lpszText = icon->info_text;
    SendMessageW( balloon_window, TTM_ADDTOOLW, 0, (LPARAM)&ti );
    if ((icon->info_flags & NIIF_ICONMASK) == NIIF_USER)
        SendMessageW( balloon_window, TTM_SETTITLEW, (WPARAM)icon->info_icon, (LPARAM)icon->info_title );
    else
        SendMessageW( balloon_window, TTM_SETTITLEW, icon->info_flags, (LPARAM)icon->info_title );
    balloon_icon = icon;
    balloon_pos.x = balloon_pos.y = MAXLONG;
    update_systray_balloon_position();
    SendMessageW( balloon_window, TTM_TRACKACTIVATE, TRUE, (LPARAM)&ti );
    KillTimer( icon->window, BALLOON_CREATE_TIMER );
    SetTimer( icon->window, BALLOON_SHOW_TIMER, icon->info_timeout, NULL );
}

static BOOL show_balloon( struct tray_icon *icon )
{
    if (standalone_tray && !show_systray) return FALSE;  /* no systray window */
    if (!icon->window) return FALSE;  /* not displayed */
    if (!icon->info_text[0]) return FALSE;  /* no balloon */
    balloon_icon = icon;
    SetTimer( icon->window, BALLOON_CREATE_TIMER, BALLOON_CREATE_TIMEOUT, NULL );
    return TRUE;
}

static void hide_balloon(void)
{
    if (!balloon_icon) return;
    if (balloon_window)
    {
        KillTimer( balloon_icon->window, BALLOON_SHOW_TIMER );
        DestroyWindow( balloon_window );
        balloon_window = 0;
    }
    else KillTimer( balloon_icon->window, BALLOON_CREATE_TIMER );
    balloon_icon = NULL;
}

static void show_next_balloon(void)
{
    struct tray_icon *icon;

    LIST_FOR_EACH_ENTRY( icon, &icon_list, struct tray_icon, entry )
        if (show_balloon( icon )) break;
}

static void update_balloon( struct tray_icon *icon )
{
    if (balloon_icon == icon)
    {
        hide_balloon();
        show_balloon( icon );
    }
    else if (!balloon_icon)
    {
        if (!show_balloon( icon )) return;
    }
    if (!balloon_icon) show_next_balloon();
}

static void balloon_timer(void)
{
    if (balloon_icon) balloon_icon->info_text[0] = 0;  /* clear text now that balloon has been shown */
    hide_balloon();
    show_next_balloon();
}

/* synchronize tooltip text with tooltip window */
static void update_tooltip_text(struct tray_icon *icon)
{
    TTTOOLINFOW ti;

    ZeroMemory(&ti, sizeof(ti));
    ti.cbSize = sizeof(TTTOOLINFOW);
    ti.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
    ti.hwnd = icon->window;
    ti.uId = (UINT_PTR)icon->window;
    ti.lpszText = icon->tiptext;

    SendMessageW(icon->tooltip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti);
}

/* get the size of the stand-alone tray window */
static SIZE get_window_size(void)
{
    SIZE size;
    RECT rect;

    rect.left = 0;
    rect.top = 0;
    rect.right = icon_cx * max( nb_displayed, MIN_DISPLAYED );
    rect.bottom = icon_cy;
    AdjustWindowRect( &rect, WS_CAPTION, FALSE );
    size.cx = rect.right - rect.left;
    size.cy = rect.bottom - rect.top;
    return size;
}

/* get the position of an icon in the stand-alone tray */
static POINT get_icon_pos( struct tray_icon *icon )
{
    POINT pos;

    pos.x = icon_cx * icon->display;
    pos.y = 0;
    return pos;
}

/* window procedure for the standalone tray window */
static LRESULT WINAPI standalone_tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    switch (msg)
    {
    case WM_MOVE:
        update_systray_balloon_position();
        break;
    case WM_CLOSE:
        ShowWindow( hwnd, SW_HIDE );
        hide_balloon();
        show_systray = FALSE;
        return 0;
    case WM_DESTROY:
        standalone_tray = 0;
        break;
    }
    return DefWindowProcW( hwnd, msg, wparam, lparam );
}

/* add an icon to the standalone tray window */
static void add_to_standalone_tray( struct tray_icon *icon )
{
    SIZE size;
    POINT pos;

    if (!standalone_tray)
    {
        static const WCHAR winname[] = {'W','i','n','e',' ','S','y','s','t','e','m',' ','T','r','a','y',0};

        size = get_window_size();
        standalone_tray = CreateWindowExW( 0, tray_classname, winname, WS_CAPTION | WS_SYSMENU,
                                           CW_USEDEFAULT, CW_USEDEFAULT, size.cx, size.cy, 0, 0, 0, 0 );
        if (!standalone_tray) return;
    }

    icon->display = nb_displayed;
    pos = get_icon_pos( icon );
    icon->window = CreateWindowW( icon_classname, NULL, WS_CHILD | WS_VISIBLE,
                                  pos.x, pos.y, icon_cx, icon_cy, standalone_tray, NULL, NULL, icon );
    if (!icon->window)
    {
        icon->display = -1;
        return;
    }
    create_tooltip( icon );

    nb_displayed++;
    size = get_window_size();
    SetWindowPos( standalone_tray, 0, 0, 0, size.cx, size.cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
    if (nb_displayed == 1 && show_systray) ShowWindow( standalone_tray, SW_SHOWNA );
    TRACE( "added %u now %d icons\n", icon->id, nb_displayed );
}

/* remove an icon from the stand-alone tray */
static void remove_from_standalone_tray( struct tray_icon *icon )
{
    struct tray_icon *ptr;
    POINT pos;

    if (icon->display == -1) return;

    LIST_FOR_EACH_ENTRY( ptr, &icon_list, struct tray_icon, entry )
    {
        if (ptr == icon) continue;
        if (ptr->display < icon->display) continue;
        ptr->display--;
        pos = get_icon_pos( ptr );
        SetWindowPos( ptr->window, 0, pos.x, pos.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER );
    }
    icon->display = -1;
    if (!--nb_displayed) ShowWindow( standalone_tray, SW_HIDE );
    TRACE( "removed %u now %d icons\n", icon->id, nb_displayed );
}

/* window procedure for the individual tray icon window */
static LRESULT WINAPI tray_icon_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    struct tray_icon *icon = NULL;
    BOOL ret;

    TRACE("hwnd=%p, msg=0x%x\n", hwnd, msg);

    /* set the icon data for the window from the data passed into CreateWindow */
    if (msg == WM_NCCREATE)
        SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)((const CREATESTRUCTW *)lparam)->lpCreateParams);

    icon = (struct tray_icon *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);

    switch (msg)
    {
    case WM_CREATE:
        SetTimer( hwnd, VALID_WIN_TIMER, VALID_WIN_TIMEOUT, NULL );
        break;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            RECT rc;
            HDC hdc;
            int cx = GetSystemMetrics( SM_CXSMICON );
            int cy = GetSystemMetrics( SM_CYSMICON );

            hdc = BeginPaint(hwnd, &ps);
            GetClientRect(hwnd, &rc);
            TRACE("painting rect %s\n", wine_dbgstr_rect(&rc));
            DrawIconEx( hdc, (rc.left + rc.right - cx) / 2, (rc.top + rc.bottom - cy) / 2,
                        icon->image, cx, cy, 0, 0, DI_DEFAULTSIZE|DI_NORMAL );
            EndPaint(hwnd, &ps);
            return 0;
        }

    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_LBUTTONDBLCLK:
    case WM_RBUTTONDBLCLK:
    case WM_MBUTTONDBLCLK:
        /* notify the owner hwnd of the message */
        TRACE("relaying 0x%x\n", msg);
        ret = PostMessageW(icon->owner, icon->callback_message, icon->id, msg);
        if (!ret && (GetLastError() == ERROR_INVALID_WINDOW_HANDLE))
        {
            WARN( "application window was destroyed, removing icon %u\n", icon->id );
            delete_icon( icon );
        }
        return 0;

    case WM_WINDOWPOSCHANGED:
        update_systray_balloon_position();
        break;

    case WM_TIMER:
        switch (wparam)
        {
        case VALID_WIN_TIMER:
            if (!IsWindow( icon->owner )) delete_icon( icon );
            break;
        case BALLOON_CREATE_TIMER:
            balloon_create_timer( icon );
            break;
        case BALLOON_SHOW_TIMER:
            balloon_timer();
            break;
        }
        return 0;

    case WM_CLOSE:
        if (icon->display == -1)
        {
            TRACE( "icon %u no longer embedded\n", icon->id );
            hide_icon( icon );
            add_to_standalone_tray( icon );
        }
        return 0;
    }
    return DefWindowProcW( hwnd, msg, wparam, lparam );
}

/* find the X11 window owner the system tray selection */
static Window get_systray_selection_owner( Display *display )
{
    Window ret;

    wine_tsx11_lock();
    ret = XGetSelectionOwner( display, systray_atom );
    wine_tsx11_unlock();
    return ret;
}

static BOOL init_systray(void)
{
    static BOOL init_done;
    WNDCLASSEXW class;
    Display *display;

    if (root_window != DefaultRootWindow( gdi_display )) return FALSE;
    if (init_done) return TRUE;

    icon_cx = GetSystemMetrics( SM_CXSMICON ) + 2 * ICON_BORDER;
    icon_cy = GetSystemMetrics( SM_CYSMICON ) + 2 * ICON_BORDER;

    memset( &class, 0, sizeof(class) );
    class.cbSize        = sizeof(class);
    class.lpfnWndProc   = tray_icon_wndproc;
    class.hIcon         = LoadIconW(0, (LPCWSTR)IDI_WINLOGO);
    class.hCursor       = LoadCursorW( 0, (LPCWSTR)IDC_ARROW );
    class.lpszClassName = icon_classname;
    class.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

    if (!RegisterClassExW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
    {
        ERR( "Could not register icon tray window class\n" );
        return FALSE;
    }

    class.lpfnWndProc   = standalone_tray_wndproc;
    class.hbrBackground = (HBRUSH)COLOR_WINDOW;
    class.lpszClassName = tray_classname;
    class.style         = CS_DBLCLKS;

    if (!RegisterClassExW( &class ) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
    {
        ERR( "Could not register standalone tray window class\n" );
        return FALSE;
    }

    display = thread_init_display();
    wine_tsx11_lock();
    if (DefaultScreen( display ) == 0)
        systray_atom = x11drv_atom(_NET_SYSTEM_TRAY_S0);
    else
    {
        char systray_buffer[29]; /* strlen(_NET_SYSTEM_TRAY_S4294967295)+1 */
        sprintf( systray_buffer, "_NET_SYSTEM_TRAY_S%u", DefaultScreen( display ) );
        systray_atom = XInternAtom( display, systray_buffer, False );
    }
    XSelectInput( display, root_window, StructureNotifyMask );
    wine_tsx11_unlock();

    init_done = TRUE;
    return TRUE;
}

/* dock the given icon with the NETWM system tray */
static void dock_systray_icon( Display *display, struct tray_icon *icon, Window systray_window )
{
    struct x11drv_win_data *data;
    XEvent ev;
    XSetWindowAttributes attr;

    icon->window = CreateWindowW( icon_classname, NULL, WS_CLIPSIBLINGS | WS_POPUP,
                                  CW_USEDEFAULT, CW_USEDEFAULT, icon_cx, icon_cy,
                                  NULL, NULL, NULL, icon );
    if (!icon->window) return;

    if (!(data = X11DRV_get_win_data( icon->window )) &&
        !(data = X11DRV_create_win_data( icon->window ))) return;

    TRACE( "icon window %p/%lx managed %u\n", data->hwnd, data->whole_window, data->managed );

    make_window_embedded( display, data );
    create_tooltip( icon );
    ShowWindow( icon->window, SW_SHOWNA );

    /* send the docking request message */
    ev.xclient.type = ClientMessage;
    ev.xclient.window = systray_window;
    ev.xclient.message_type = x11drv_atom( _NET_SYSTEM_TRAY_OPCODE );
    ev.xclient.format = 32;
    ev.xclient.data.l[0] = CurrentTime;
    ev.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
    ev.xclient.data.l[2] = data->whole_window;
    ev.xclient.data.l[3] = 0;
    ev.xclient.data.l[4] = 0;
    wine_tsx11_lock();
    XSendEvent( display, systray_window, False, NoEventMask, &ev );
    attr.background_pixmap = ParentRelative;
    attr.bit_gravity = ForgetGravity;
    XChangeWindowAttributes( display, data->whole_window, CWBackPixmap | CWBitGravity, &attr );
    XChangeWindowAttributes( display, data->client_window, CWBackPixmap | CWBitGravity, &attr );
    wine_tsx11_unlock();
}

/* dock systray windows again with the new owner */
void change_systray_owner( Display *display, Window systray_window )
{
    struct tray_icon *icon;

    TRACE( "new owner %lx\n", systray_window );
    LIST_FOR_EACH_ENTRY( icon, &icon_list, struct tray_icon, entry )
    {
        if (icon->display == -1) continue;
        hide_icon( icon );
        dock_systray_icon( display, icon, systray_window );
    }
}

/* hide a tray icon */
static BOOL hide_icon( struct tray_icon *icon )
{
    struct x11drv_win_data *data;

    TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner );

    if (!icon->window) return TRUE;  /* already hidden */

    /* make sure we don't try to unmap it, it confuses some systray docks */
    if ((data = X11DRV_get_win_data( icon->window )) && data->embedded) data->mapped = FALSE;

    DestroyWindow(icon->window);
    DestroyWindow(icon->tooltip);
    icon->window = 0;
    icon->tooltip = 0;
    remove_from_standalone_tray( icon );
    update_balloon( icon );
    return TRUE;
}

/* make the icon visible */
static BOOL show_icon( struct tray_icon *icon )
{
    Window systray_window;
    Display *display = thread_init_display();

    TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner );

    if (icon->window) return TRUE;  /* already shown */

    if ((systray_window = get_systray_selection_owner( display )))
        dock_systray_icon( display, icon, systray_window );
    else
        add_to_standalone_tray( icon );

    update_balloon( icon );
    return TRUE;
}

/* Modifies an existing icon record */
static BOOL modify_icon( struct tray_icon *icon, NOTIFYICONDATAW *nid )
{
    TRACE( "id=0x%x hwnd=%p flags=%x\n", nid->uID, nid->hWnd, nid->uFlags );

    if (nid->uFlags & NIF_STATE)
    {
        icon->state = (icon->state & ~nid->dwStateMask) | (nid->dwState & nid->dwStateMask);
    }

    if (nid->uFlags & NIF_ICON)
    {
        if (icon->image) DestroyIcon(icon->image);
        icon->image = CopyIcon(nid->hIcon);
        if (icon->window)
        {
            if (icon->display != -1) InvalidateRect( icon->window, NULL, TRUE );
            else
            {
                struct x11drv_win_data *data = X11DRV_get_win_data( icon->window );
                if (data) XClearArea( gdi_display, data->client_window, 0, 0, 0, 0, True );
            }
        }
    }

    if (nid->uFlags & NIF_MESSAGE)
    {
        icon->callback_message = nid->uCallbackMessage;
    }
    if (nid->uFlags & NIF_TIP)
    {
        lstrcpynW(icon->tiptext, nid->szTip, sizeof(icon->tiptext)/sizeof(WCHAR));
        if (icon->tooltip) update_tooltip_text(icon);
    }
    if (nid->uFlags & NIF_INFO && nid->cbSize >= NOTIFYICONDATAA_V2_SIZE)
    {
        lstrcpynW( icon->info_text, nid->szInfo, sizeof(icon->info_text)/sizeof(WCHAR) );
        lstrcpynW( icon->info_title, nid->szInfoTitle, sizeof(icon->info_title)/sizeof(WCHAR) );
        icon->info_flags = nid->dwInfoFlags;
        icon->info_timeout = max(min(nid->u.uTimeout, BALLOON_SHOW_MAX_TIMEOUT), BALLOON_SHOW_MIN_TIMEOUT);
        icon->info_icon = nid->hBalloonIcon;
        update_balloon( icon );
    }
    if (icon->state & NIS_HIDDEN) hide_icon( icon );
    else show_icon( icon );
    return TRUE;
}

/* Adds a new icon record to the list */
static BOOL add_icon(NOTIFYICONDATAW *nid)
{
    struct tray_icon  *icon;

    TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd);

    if ((icon = get_icon(nid->hWnd, nid->uID)))
    {
        WARN("duplicate tray icon add, buggy app?\n");
        return FALSE;
    }

    if (!(icon = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*icon))))
    {
        ERR("out of memory\n");
        return FALSE;
    }

    ZeroMemory(icon, sizeof(struct tray_icon));
    icon->id     = nid->uID;
    icon->owner  = nid->hWnd;
    icon->display = -1;

    list_add_tail(&icon_list, &icon->entry);

    return modify_icon( icon, nid );
}

/* delete tray icon window and icon structure */
static BOOL delete_icon( struct tray_icon *icon )
{
    hide_icon( icon );
    list_remove( &icon->entry );
    DestroyIcon( icon->image );
    HeapFree( GetProcessHeap(), 0, icon );
    return TRUE;
}


/***********************************************************************
 *              wine_notify_icon   (X11DRV.@)
 *
 * Driver-side implementation of Shell_NotifyIcon.
 */
int CDECL wine_notify_icon( DWORD msg, NOTIFYICONDATAW *data )
{
    BOOL ret = FALSE;
    struct tray_icon *icon;

    switch (msg)
    {
    case NIM_ADD:
        if (!init_systray()) return -1;  /* fall back to default handling */
        ret = add_icon( data );
        break;
    case NIM_DELETE:
        if ((icon = get_icon( data->hWnd, data->uID ))) ret = delete_icon( icon );
        break;
    case NIM_MODIFY:
        if ((icon = get_icon( data->hWnd, data->uID ))) ret = modify_icon( icon, data );
        break;
    default:
        FIXME( "unhandled tray message: %u\n", msg );
        break;
    }
    return ret;
}
