/*
 * X11 event driver
 *
 * Copyright 1993 Alexandre Julliard
 *	     1999 Noel Borthwick
 *
 * 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"

#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
#include <X11/extensions/XInput2.h>
#endif

#include <assert.h>
#include <stdarg.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"

#include "x11drv.h"

/* avoid conflict with field names in included win32 headers */
#undef Status
#include "shlobj.h"  /* DROPFILES */
#include "shellapi.h"

#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(event);

extern BOOL ximInComposeMode;

#define DndNotDnd       -1    /* OffiX drag&drop */
#define DndUnknown      0
#define DndRawData      1
#define DndFile         2
#define DndFiles        3
#define DndText         4
#define DndDir          5
#define DndLink         6
#define DndExe          7

#define DndEND          8

#define DndURL          128   /* KDE drag&drop */

#define XEMBED_EMBEDDED_NOTIFY        0
#define XEMBED_WINDOW_ACTIVATE        1
#define XEMBED_WINDOW_DEACTIVATE      2
#define XEMBED_REQUEST_FOCUS          3
#define XEMBED_FOCUS_IN               4
#define XEMBED_FOCUS_OUT              5
#define XEMBED_FOCUS_NEXT             6
#define XEMBED_FOCUS_PREV             7
#define XEMBED_MODALITY_ON            10
#define XEMBED_MODALITY_OFF           11
#define XEMBED_REGISTER_ACCELERATOR   12
#define XEMBED_UNREGISTER_ACCELERATOR 13
#define XEMBED_ACTIVATE_ACCELERATOR   14

Bool (*pXGetEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL;
void (*pXFreeEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL;

  /* Event handlers */
static void X11DRV_FocusIn( HWND hwnd, XEvent *event );
static void X11DRV_FocusOut( HWND hwnd, XEvent *event );
static void X11DRV_Expose( HWND hwnd, XEvent *event );
static void X11DRV_MapNotify( HWND hwnd, XEvent *event );
static void X11DRV_UnmapNotify( HWND hwnd, XEvent *event );
static void X11DRV_ReparentNotify( HWND hwnd, XEvent *event );
static void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );
static void X11DRV_PropertyNotify( HWND hwnd, XEvent *event );
static void X11DRV_ClientMessage( HWND hwnd, XEvent *event );
static void X11DRV_GravityNotify( HWND hwnd, XEvent *event );

#define MAX_EVENT_HANDLERS 128

static x11drv_event_handler handlers[MAX_EVENT_HANDLERS] =
{
    NULL,                     /*  0 reserved */
    NULL,                     /*  1 reserved */
    X11DRV_KeyEvent,          /*  2 KeyPress */
    X11DRV_KeyEvent,          /*  3 KeyRelease */
    X11DRV_ButtonPress,       /*  4 ButtonPress */
    X11DRV_ButtonRelease,     /*  5 ButtonRelease */
    X11DRV_MotionNotify,      /*  6 MotionNotify */
    X11DRV_EnterNotify,       /*  7 EnterNotify */
    NULL,                     /*  8 LeaveNotify */
    X11DRV_FocusIn,           /*  9 FocusIn */
    X11DRV_FocusOut,          /* 10 FocusOut */
    X11DRV_KeymapNotify,      /* 11 KeymapNotify */
    X11DRV_Expose,            /* 12 Expose */
    NULL,                     /* 13 GraphicsExpose */
    NULL,                     /* 14 NoExpose */
    NULL,                     /* 15 VisibilityNotify */
    NULL,                     /* 16 CreateNotify */
    X11DRV_DestroyNotify,     /* 17 DestroyNotify */
    X11DRV_UnmapNotify,       /* 18 UnmapNotify */
    X11DRV_MapNotify,         /* 19 MapNotify */
    NULL,                     /* 20 MapRequest */
    X11DRV_ReparentNotify,    /* 21 ReparentNotify */
    X11DRV_ConfigureNotify,   /* 22 ConfigureNotify */
    NULL,                     /* 23 ConfigureRequest */
    X11DRV_GravityNotify,     /* 24 GravityNotify */
    NULL,                     /* 25 ResizeRequest */
    NULL,                     /* 26 CirculateNotify */
    NULL,                     /* 27 CirculateRequest */
    X11DRV_PropertyNotify,    /* 28 PropertyNotify */
    X11DRV_SelectionClear,    /* 29 SelectionClear */
    X11DRV_SelectionRequest,  /* 30 SelectionRequest */
    NULL,                     /* 31 SelectionNotify */
    NULL,                     /* 32 ColormapNotify */
    X11DRV_ClientMessage,     /* 33 ClientMessage */
    X11DRV_MappingNotify,     /* 34 MappingNotify */
    X11DRV_GenericEvent       /* 35 GenericEvent */
};

static const char * event_names[MAX_EVENT_HANDLERS] =
{
    NULL, NULL, "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
    "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
    "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
    "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
    "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", "ResizeRequest",
    "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear", "SelectionRequest",
    "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify", "GenericEvent"
};

int xinput2_opcode = 0;

/* return the name of an X event */
static const char *dbgstr_event( int type )
{
    if (type < MAX_EVENT_HANDLERS && event_names[type]) return event_names[type];
    return wine_dbg_sprintf( "Unknown event %d", type );
}

static inline void get_event_data( XEvent *event )
{
#if defined(GenericEvent) && defined(HAVE_XEVENT_XCOOKIE)
    if (event->xany.type != GenericEvent) return;
    if (!pXGetEventData || !pXGetEventData( event->xany.display, event )) event->xcookie.data = NULL;
#endif
}

static inline void free_event_data( XEvent *event )
{
#if defined(GenericEvent) && defined(HAVE_XEVENT_XCOOKIE)
    if (event->xany.type != GenericEvent) return;
    if (event->xcookie.data) pXFreeEventData( event->xany.display, event );
#endif
}

/***********************************************************************
 *           X11DRV_register_event_handler
 *
 * Register a handler for a given event type.
 * If already registered, overwrite the previous handler.
 */
void X11DRV_register_event_handler( int type, x11drv_event_handler handler, const char *name )
{
    assert( type < MAX_EVENT_HANDLERS );
    assert( !handlers[type] || handlers[type] == handler );
    handlers[type] = handler;
    event_names[type] = name;
    TRACE("registered handler %p for event %d %s\n", handler, type, debugstr_a(name) );
}


/***********************************************************************
 *           filter_event
 */
static Bool filter_event( Display *display, XEvent *event, char *arg )
{
    ULONG_PTR mask = (ULONG_PTR)arg;

    if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return 1;

    switch(event->type)
    {
    case KeyPress:
    case KeyRelease:
    case KeymapNotify:
    case MappingNotify:
        return (mask & (QS_KEY|QS_HOTKEY)) != 0;
    case ButtonPress:
    case ButtonRelease:
        return (mask & QS_MOUSEBUTTON) != 0;
    case MotionNotify:
    case EnterNotify:
    case LeaveNotify:
        return (mask & QS_MOUSEMOVE) != 0;
    case Expose:
        return (mask & QS_PAINT) != 0;
    case FocusIn:
    case FocusOut:
    case MapNotify:
    case UnmapNotify:
    case ConfigureNotify:
    case PropertyNotify:
    case ClientMessage:
        return (mask & QS_POSTMESSAGE) != 0;
    default:
        return (mask & QS_SENDMESSAGE) != 0;
    }
}


enum event_merge_action
{
    MERGE_DISCARD,  /* discard the old event */
    MERGE_HANDLE,   /* handle the old event */
    MERGE_KEEP,     /* keep the old event for future merging */
    MERGE_IGNORE    /* ignore the new event, keep the old one */
};

/***********************************************************************
 *           merge_raw_motion_events
 */
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawEvent *next )
{
    int i, j, k;
    unsigned char mask;

    if (!prev->valuators.mask_len) return MERGE_HANDLE;
    if (!next->valuators.mask_len) return MERGE_HANDLE;

    mask = prev->valuators.mask[0] | next->valuators.mask[0];
    if (mask == next->valuators.mask[0])  /* keep next */
    {
        for (i = j = k = 0; i < 8; i++)
        {
            if (XIMaskIsSet( prev->valuators.mask, i ))
                next->valuators.values[j] += prev->valuators.values[k++];
            if (XIMaskIsSet( next->valuators.mask, i )) j++;
        }
        TRACE( "merging duplicate GenericEvent\n" );
        return MERGE_DISCARD;
    }
    if (mask == prev->valuators.mask[0])  /* keep prev */
    {
        for (i = j = k = 0; i < 8; i++)
        {
            if (XIMaskIsSet( next->valuators.mask, i ))
                prev->valuators.values[j] += next->valuators.values[k++];
            if (XIMaskIsSet( prev->valuators.mask, i )) j++;
        }
        TRACE( "merging duplicate GenericEvent\n" );
        return MERGE_IGNORE;
    }
    /* can't merge events with disjoint masks */
    return MERGE_HANDLE;
}
#endif

/***********************************************************************
 *           merge_events
 *
 * Try to merge 2 consecutive events.
 */
static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
{
    switch (prev->type)
    {
    case ConfigureNotify:
        switch (next->type)
        {
        case ConfigureNotify:
            if (prev->xany.window == next->xany.window)
            {
                TRACE( "discarding duplicate ConfigureNotify for window %lx\n", prev->xany.window );
                return MERGE_DISCARD;
            }
            break;
        case Expose:
        case PropertyNotify:
            return MERGE_KEEP;
        }
        break;
    case MotionNotify:
        switch (next->type)
        {
        case MotionNotify:
            if (prev->xany.window == next->xany.window)
            {
                TRACE( "discarding duplicate MotionNotify for window %lx\n", prev->xany.window );
                return MERGE_DISCARD;
            }
            break;
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
        case GenericEvent:
            if (next->xcookie.extension != xinput2_opcode) break;
            if (next->xcookie.evtype != XI_RawMotion) break;
            if (x11drv_thread_data()->warp_serial) break;
            return MERGE_KEEP;
        }
        break;
    case GenericEvent:
        if (prev->xcookie.extension != xinput2_opcode) break;
        if (prev->xcookie.evtype != XI_RawMotion) break;
        switch (next->type)
        {
        case GenericEvent:
            if (next->xcookie.extension != xinput2_opcode) break;
            if (next->xcookie.evtype != XI_RawMotion) break;
            if (x11drv_thread_data()->warp_serial) break;
            return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
#endif
        }
        break;
    }
    return MERGE_HANDLE;
}


/***********************************************************************
 *           call_event_handler
 */
static inline void call_event_handler( Display *display, XEvent *event )
{
    HWND hwnd;
    XEvent *prev;
    struct x11drv_thread_data *thread_data;

    if (!handlers[event->type])
    {
        TRACE( "%s for win %lx, ignoring\n", dbgstr_event( event->type ), event->xany.window );
        return;  /* no handler, ignore it */
    }

    if (XFindContext( display, event->xany.window, winContext, (char **)&hwnd ) != 0)
        hwnd = 0;  /* not for a registered window */
    if (!hwnd && event->xany.window == root_window) hwnd = GetDesktopWindow();

    TRACE( "%lu %s for hwnd/window %p/%lx\n",
           event->xany.serial, dbgstr_event( event->type ), hwnd, event->xany.window );
    wine_tsx11_unlock();
    thread_data = x11drv_thread_data();
    prev = thread_data->current_event;
    thread_data->current_event = event;
    handlers[event->type]( hwnd, event );
    thread_data->current_event = prev;
    wine_tsx11_lock();
}


/***********************************************************************
 *           process_events
 */
static int process_events( Display *display, Bool (*filter)(Display*, XEvent*,XPointer), ULONG_PTR arg )
{
    XEvent event, prev_event;
    int count = 0;
    enum event_merge_action action = MERGE_DISCARD;

    prev_event.type = 0;
    wine_tsx11_lock();
    while (XCheckIfEvent( display, &event, filter, (char *)arg ))
    {
        count++;
        if (XFilterEvent( &event, None ))
        {
            /*
             * SCIM on linux filters key events strangely. It does not filter the
             * KeyPress events for these keys however it does filter the
             * KeyRelease events. This causes wine to become very confused as
             * to the keyboard state.
             *
             * We need to let those KeyRelease events be processed so that the
             * keyboard state is correct.
             */
            if (event.type == KeyRelease)
            {
                KeySym keysym = 0;
                XKeyEvent *keyevent = &event.xkey;

                XLookupString(keyevent, NULL, 0, &keysym, NULL);
                if (!(keysym == XK_Shift_L ||
                    keysym == XK_Shift_R ||
                    keysym == XK_Control_L ||
                    keysym == XK_Control_R ||
                    keysym == XK_Alt_R ||
                    keysym == XK_Alt_L ||
                    keysym == XK_Meta_R ||
                    keysym == XK_Meta_L))
                        continue; /* not a key we care about, ignore it */
            }
            else
                continue;  /* filtered, ignore it */
        }
        get_event_data( &event );
        if (prev_event.type) action = merge_events( &prev_event, &event );
        switch( action )
        {
        case MERGE_HANDLE:  /* handle prev, keep new */
            call_event_handler( display, &prev_event );
            /* fall through */
        case MERGE_DISCARD:  /* discard prev, keep new */
            free_event_data( &prev_event );
            prev_event = event;
            break;
        case MERGE_KEEP:  /* handle new, keep prev for future merging */
            call_event_handler( display, &event );
            /* fall through */
        case MERGE_IGNORE: /* ignore new, keep prev for future merging */
            free_event_data( &event );
            break;
        }
    }
    if (prev_event.type) call_event_handler( display, &prev_event );
    free_event_data( &prev_event );
    XFlush( gdi_display );
    wine_tsx11_unlock();
    if (count) TRACE( "processed %d events\n", count );
    return count;
}


/***********************************************************************
 *           MsgWaitForMultipleObjectsEx   (X11DRV.@)
 */
DWORD CDECL X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
                                                DWORD timeout, DWORD mask, DWORD flags )
{
    DWORD ret;
    struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );

    if (!data)
    {
        if (!count && !timeout) return WAIT_TIMEOUT;
        return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
                                         timeout, flags & MWMO_ALERTABLE );
    }

    if (data->current_event) mask = 0;  /* don't process nested events */

    if (process_events( data->display, filter_event, mask )) ret = count - 1;
    else if (count || timeout)
    {
        ret = WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
                                        timeout, flags & MWMO_ALERTABLE );
        if (ret == count - 1) process_events( data->display, filter_event, mask );
    }
    else ret = WAIT_TIMEOUT;

    return ret;
}

/***********************************************************************
 *           EVENT_x11_time_to_win32_time
 *
 * Make our timer and the X timer line up as best we can
 *  Pass 0 to retrieve the current adjustment value (times -1)
 */
DWORD EVENT_x11_time_to_win32_time(Time time)
{
  static DWORD adjust = 0;
  DWORD now = GetTickCount();
  DWORD ret;

  if (! adjust && time != 0)
  {
    ret = now;
    adjust = time - now;
  }
  else
  {
      /* If we got an event in the 'future', then our clock is clearly wrong. 
         If we got it more than 10000 ms in the future, then it's most likely
         that the clock has wrapped.  */

      ret = time - adjust;
      if (ret > now && ((ret - now) < 10000) && time != 0)
      {
        adjust += ret - now;
        ret    -= ret - now;
      }
  }

  return ret;

}

/*******************************************************************
 *         can_activate_window
 *
 * Check if we can activate the specified window.
 */
static inline BOOL can_activate_window( HWND hwnd )
{
    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
    LONG style = GetWindowLongW( hwnd, GWL_STYLE );

    if (!(style & WS_VISIBLE)) return FALSE;
    if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
    if (style & WS_MINIMIZE) return FALSE;
    if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOACTIVATE) return FALSE;
    if (hwnd == GetDesktopWindow()) return FALSE;
    if (data && IsRectEmpty( &data->window_rect )) return FALSE;
    return !(style & WS_DISABLED);
}


/**********************************************************************
 *              set_focus
 */
static void set_focus( Display *display, HWND hwnd, Time time )
{
    HWND focus;
    Window win;
    GUITHREADINFO threadinfo;

    TRACE( "setting foreground window to %p\n", hwnd );
    SetForegroundWindow( hwnd );

    threadinfo.cbSize = sizeof(threadinfo);
    GetGUIThreadInfo(0, &threadinfo);
    focus = threadinfo.hwndFocus;
    if (!focus) focus = threadinfo.hwndActive;
    if (focus) focus = GetAncestor( focus, GA_ROOT );
    win = X11DRV_get_whole_window(focus);

    if (win)
    {
        TRACE( "setting focus to %p (%lx) time=%ld\n", focus, win, time );
        wine_tsx11_lock();
        XSetInputFocus( display, win, RevertToParent, time );
        wine_tsx11_unlock();
    }
}


/**********************************************************************
 *              handle_manager_message
 */
static void handle_manager_message( HWND hwnd, XClientMessageEvent *event )
{
    if (hwnd != GetDesktopWindow()) return;
    if (systray_atom && event->data.l[1] == systray_atom)
        change_systray_owner( event->display, event->data.l[2] );
}


/**********************************************************************
 *              handle_wm_protocols
 */
static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
{
    Atom protocol = (Atom)event->data.l[0];
    Time event_time = (Time)event->data.l[1];

    if (!protocol) return;

    if (protocol == x11drv_atom(WM_DELETE_WINDOW))
    {
        update_user_time( event_time );

        if (hwnd == GetDesktopWindow())
        {
            /* The desktop window does not have a close button that we can
             * pretend to click. Therefore, we simply send it a close command. */
            SendMessageW(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
            return;
        }

        /* Ignore the delete window request if the window has been disabled
         * and we are in managed mode. This is to disallow applications from
         * being closed by the window manager while in a modal state.
         */
        if (IsWindowEnabled(hwnd))
        {
            HMENU hSysMenu;

            if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return;
            hSysMenu = GetSystemMenu(hwnd, FALSE);
            if (hSysMenu)
            {
                UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
                if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED)))
                    return;
            }
            if (GetActiveWindow() != hwnd)
            {
                LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE,
                                           (WPARAM)GetAncestor( hwnd, GA_ROOT ),
                                           MAKELPARAM( HTCLOSE, WM_NCLBUTTONDOWN ) );
                switch(ma)
                {
                    case MA_NOACTIVATEANDEAT:
                    case MA_ACTIVATEANDEAT:
                        return;
                    case MA_NOACTIVATE:
                        break;
                    case MA_ACTIVATE:
                    case 0:
                        SetActiveWindow(hwnd);
                        break;
                    default:
                        WARN( "unknown WM_MOUSEACTIVATE code %d\n", (int) ma );
                        break;
                }
            }

            PostMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
        }
    }
    else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
    {
        HWND last_focus = x11drv_thread_data()->last_focus;

        TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08x), focus=%p, active=%p, fg=%p, last=%p\n",
               hwnd, IsWindowEnabled(hwnd), IsWindowVisible(hwnd), GetWindowLongW(hwnd, GWL_STYLE),
               GetFocus(), GetActiveWindow(), GetForegroundWindow(), last_focus );

        if (can_activate_window(hwnd))
        {
            /* simulate a mouse click on the caption to find out
             * whether the window wants to be activated */
            LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE,
                                       (WPARAM)GetAncestor( hwnd, GA_ROOT ),
                                       MAKELONG(HTCAPTION,WM_LBUTTONDOWN) );
            if (ma != MA_NOACTIVATEANDEAT && ma != MA_NOACTIVATE)
            {
                set_focus( event->display, hwnd, event_time );
                return;
            }
        }
        else if (hwnd == GetDesktopWindow())
        {
            hwnd = GetForegroundWindow();
            if (!hwnd) hwnd = last_focus;
            if (!hwnd) hwnd = GetDesktopWindow();
            set_focus( event->display, hwnd, event_time );
            return;
        }
        /* try to find some other window to give the focus to */
        hwnd = GetFocus();
        if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT );
        if (!hwnd) hwnd = GetActiveWindow();
        if (!hwnd) hwnd = last_focus;
        if (hwnd && can_activate_window(hwnd)) set_focus( event->display, hwnd, event_time );
    }
    else if (protocol == x11drv_atom(_NET_WM_PING))
    {
      XClientMessageEvent xev;
      xev = *event;
      
      TRACE("NET_WM Ping\n");
      wine_tsx11_lock();
      xev.window = DefaultRootWindow(xev.display);
      XSendEvent(xev.display, xev.window, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xev);
      wine_tsx11_unlock();
      /* this line is semi-stolen from gtk2 */
      TRACE("NET_WM Pong\n");
    }
}


static const char * const focus_details[] =
{
    "NotifyAncestor",
    "NotifyVirtual",
    "NotifyInferior",
    "NotifyNonlinear",
    "NotifyNonlinearVirtual",
    "NotifyPointer",
    "NotifyPointerRoot",
    "NotifyDetailNone"
};

/**********************************************************************
 *              X11DRV_FocusIn
 */
static void X11DRV_FocusIn( HWND hwnd, XEvent *xev )
{
    XFocusChangeEvent *event = &xev->xfocus;
    XIC xic;

    if (!hwnd) return;

    TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );

    if (event->detail == NotifyPointer) return;
    if (hwnd == GetDesktopWindow()) return;

    if ((xic = X11DRV_get_ic( hwnd )))
    {
        wine_tsx11_lock();
        XSetICFocus( xic );
        wine_tsx11_unlock();
    }
    if (use_take_focus)
    {
        if (hwnd == GetForegroundWindow()) clip_fullscreen_window( hwnd, FALSE );
        return;
    }

    if (!can_activate_window(hwnd))
    {
        HWND hwnd = GetFocus();
        if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT );
        if (!hwnd) hwnd = GetActiveWindow();
        if (!hwnd) hwnd = x11drv_thread_data()->last_focus;
        if (hwnd && can_activate_window(hwnd)) set_focus( event->display, hwnd, CurrentTime );
    }
    else SetForegroundWindow( hwnd );
}


/**********************************************************************
 *              X11DRV_FocusOut
 *
 * Note: only top-level windows get FocusOut events.
 */
static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
{
    XFocusChangeEvent *event = &xev->xfocus;
    HWND hwnd_tmp;
    Window focus_win;
    int revert;
    XIC xic;

    TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );

    if (event->detail == NotifyPointer)
    {
        if (!hwnd && event->window == x11drv_thread_data()->clip_window) reset_clipping_window();
        return;
    }
    if (!hwnd) return;
    if (ximInComposeMode) return;

    x11drv_thread_data()->last_focus = hwnd;
    if ((xic = X11DRV_get_ic( hwnd )))
    {
        wine_tsx11_lock();
        XUnsetICFocus( xic );
        wine_tsx11_unlock();
    }
    if (root_window != DefaultRootWindow(event->display))
    {
        if (hwnd == GetDesktopWindow()) reset_clipping_window();
        return;
    }
    if (hwnd != GetForegroundWindow()) return;
    SendMessageW( hwnd, WM_CANCELMODE, 0, 0 );

    /* don't reset the foreground window, if the window which is
       getting the focus is a Wine window */

    wine_tsx11_lock();
    XGetInputFocus( event->display, &focus_win, &revert );
    if (focus_win)
    {
        if (XFindContext( event->display, focus_win, winContext, (char **)&hwnd_tmp ) != 0)
            focus_win = 0;
    }
    wine_tsx11_unlock();

    if (!focus_win)
    {
        /* Abey : 6-Oct-99. Check again if the focus out window is the
           Foreground window, because in most cases the messages sent
           above must have already changed the foreground window, in which
           case we don't have to change the foreground window to 0 */
        if (hwnd == GetForegroundWindow())
        {
            TRACE( "lost focus, setting fg to desktop\n" );
            SetForegroundWindow( GetDesktopWindow() );
        }
    }
}


/***********************************************************************
 *           X11DRV_Expose
 */
static void X11DRV_Expose( HWND hwnd, XEvent *xev )
{
    XExposeEvent *event = &xev->xexpose;
    RECT rect;
    struct x11drv_win_data *data;
    int flags = RDW_INVALIDATE | RDW_ERASE;

    TRACE( "win %p (%lx) %d,%d %dx%d\n",
           hwnd, event->window, event->x, event->y, event->width, event->height );

    if (!(data = X11DRV_get_win_data( hwnd ))) return;

    rect.left   = event->x;
    rect.top    = event->y;
    rect.right  = event->x + event->width;
    rect.bottom = event->y + event->height;
    if (event->window == data->whole_window)
    {
        OffsetRect( &rect, data->whole_rect.left - data->client_rect.left,
                    data->whole_rect.top - data->client_rect.top );
        flags |= RDW_FRAME;
    }

    if (event->window != root_window)
    {
        if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
            mirror_rect( &data->client_rect, &rect );

        SERVER_START_REQ( update_window_zorder )
        {
            req->window      = wine_server_user_handle( hwnd );
            req->rect.left   = rect.left;
            req->rect.top    = rect.top;
            req->rect.right  = rect.right;
            req->rect.bottom = rect.bottom;
            wine_server_call( req );
        }
        SERVER_END_REQ;

        flags |= RDW_ALLCHILDREN;
    }
    else OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );

    RedrawWindow( hwnd, &rect, 0, flags );
}


/**********************************************************************
 *		X11DRV_MapNotify
 */
static void X11DRV_MapNotify( HWND hwnd, XEvent *event )
{
    struct x11drv_win_data *data;

    if (event->xany.window == x11drv_thread_data()->clip_window)
    {
        clipping_cursor = 1;
        return;
    }
    if (!(data = X11DRV_get_win_data( hwnd ))) return;
    if (!data->mapped || data->embedded) return;

    if (!data->managed)
    {
        HWND hwndFocus = GetFocus();
        if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus);  /* FIXME */
    }
}


/**********************************************************************
 *		X11DRV_UnmapNotify
 */
static void X11DRV_UnmapNotify( HWND hwnd, XEvent *event )
{
    if (event->xany.window == x11drv_thread_data()->clip_window) clipping_cursor = 0;
}


/***********************************************************************
 *     is_net_wm_state_maximized
 */
static BOOL is_net_wm_state_maximized( Display *display, struct x11drv_win_data *data )
{
    Atom type, *state;
    int format, ret = 0;
    unsigned long i, count, remaining;

    if (!data->whole_window) return FALSE;

    wine_tsx11_lock();
    if (!XGetWindowProperty( display, data->whole_window, x11drv_atom(_NET_WM_STATE), 0,
                             65536/sizeof(CARD32), False, XA_ATOM, &type, &format, &count,
                             &remaining, (unsigned char **)&state ))
    {
        if (type == XA_ATOM && format == 32)
        {
            for (i = 0; i < count; i++)
            {
                if (state[i] == x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT) ||
                    state[i] == x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ))
                    ret++;
            }
        }
        XFree( state );
    }
    wine_tsx11_unlock();
    return (ret == 2);
}


/***********************************************************************
 *           X11DRV_ReparentNotify
 */
static void X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
{
    XReparentEvent *event = &xev->xreparent;
    struct x11drv_win_data *data;
    HWND parent, old_parent;
    DWORD style;

    if (!(data = X11DRV_get_win_data( hwnd ))) return;
    if (!data->embedded) return;

    if (data->whole_window)
    {
        if (event->parent == root_window)
        {
            TRACE( "%p/%lx reparented to root\n", hwnd, data->whole_window );
            data->embedder = 0;
            SendMessageW( hwnd, WM_CLOSE, 0, 0 );
            return;
        }
        data->embedder = event->parent;
    }

    TRACE( "%p/%lx reparented to %lx\n", hwnd, data->whole_window, event->parent );

    style = GetWindowLongW( hwnd, GWL_STYLE );
    if (event->parent == root_window)
    {
        parent = GetDesktopWindow();
        style = (style & ~WS_CHILD) | WS_POPUP;
    }
    else
    {
        if (!(parent = create_foreign_window( event->display, event->parent ))) return;
        style = (style & ~WS_POPUP) | WS_CHILD;
    }

    ShowWindow( hwnd, SW_HIDE );
    old_parent = SetParent( hwnd, parent );
    SetWindowLongW( hwnd, GWL_STYLE, style );
    SetWindowPos( hwnd, HWND_TOP, event->x, event->y, 0, 0,
                  SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS |
                  ((style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0) );

    /* make old parent destroy itself if it no longer has children */
    if (old_parent != GetDesktopWindow()) PostMessageW( old_parent, WM_CLOSE, 0, 0 );
}


/***********************************************************************
 *		X11DRV_ConfigureNotify
 */
void X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
{
    XConfigureEvent *event = &xev->xconfigure;
    struct x11drv_win_data *data;
    RECT rect;
    UINT flags;
    HWND parent;
    BOOL root_coords;
    int cx, cy, x = event->x, y = event->y;

    if (!hwnd) return;
    if (!(data = X11DRV_get_win_data( hwnd ))) return;
    if (!data->mapped || data->iconic) return;
    if (data->whole_window && !data->managed) return;
    /* ignore synthetic events on foreign windows */
    if (event->send_event && !data->whole_window) return;
    if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0)
    {
        TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n",
               hwnd, data->whole_window, event->x, event->y, event->width, event->height,
               event->serial, data->configure_serial );
        return;
    }

    /* Get geometry */

    parent = GetAncestor( hwnd, GA_PARENT );
    root_coords = event->send_event;  /* synthetic events are always in root coords */

    if (!root_coords && parent == GetDesktopWindow()) /* normal event, map coordinates to the root */
    {
        Window child;
        wine_tsx11_lock();
        XTranslateCoordinates( event->display, event->window, root_window,
                               0, 0, &x, &y, &child );
        wine_tsx11_unlock();
        root_coords = TRUE;
    }
    rect.left   = x;
    rect.top    = y;
    rect.right  = x + event->width;
    rect.bottom = y + event->height;
    if (root_coords) OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );
    TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
           hwnd, data->whole_window, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
           event->x, event->y, event->width, event->height );

    X11DRV_X_to_window_rect( data, &rect );
    if (root_coords) MapWindowPoints( 0, parent, (POINT *)&rect, 2 );

    /* Compare what has changed */

    x     = rect.left;
    y     = rect.top;
    cx    = rect.right - rect.left;
    cy    = rect.bottom - rect.top;
    flags = SWP_NOACTIVATE | SWP_NOZORDER;

    if (!data->whole_window) flags |= SWP_NOCOPYBITS;  /* we can't copy bits of foreign windows */

    if (data->window_rect.left == x && data->window_rect.top == y) flags |= SWP_NOMOVE;
    else
        TRACE( "%p moving from (%d,%d) to (%d,%d)\n",
               hwnd, data->window_rect.left, data->window_rect.top, x, y );

    if ((data->window_rect.right - data->window_rect.left == cx &&
         data->window_rect.bottom - data->window_rect.top == cy) ||
        (IsRectEmpty( &data->window_rect ) && event->width == 1 && event->height == 1))
    {
        if (flags & SWP_NOMOVE)  /* if nothing changed, don't do anything */
        {
            TRACE( "Nothing has changed, ignoring event\n" );
            return;
        }
        flags |= SWP_NOSIZE;
    }
    else
        TRACE( "%p resizing from (%dx%d) to (%dx%d)\n",
               hwnd, data->window_rect.right - data->window_rect.left,
               data->window_rect.bottom - data->window_rect.top, cx, cy );

    if (is_net_wm_state_maximized( event->display, data ))
    {
        if (!IsZoomed( data->hwnd ))
        {
            TRACE( "win %p/%lx is maximized\n", data->hwnd, data->whole_window );
            SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
            return;
        }
    }
    else
    {
        if (IsZoomed( data->hwnd ))
        {
            TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
            SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
            return;
        }
    }

    SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
}


/**********************************************************************
 *           X11DRV_GravityNotify
 */
static void X11DRV_GravityNotify( HWND hwnd, XEvent *xev )
{
    XGravityEvent *event = &xev->xgravity;
    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
    RECT rect;

    if (!data || data->whole_window) return;  /* only handle this for foreign windows */

    rect.left   = event->x;
    rect.top    = event->y;
    rect.right  = rect.left + data->whole_rect.right - data->whole_rect.left;
    rect.bottom = rect.top + data->whole_rect.bottom - data->whole_rect.top;

    TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d)\n",
           hwnd, data->whole_window, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
           event->x, event->y );

    X11DRV_X_to_window_rect( data, &rect );

    if (data->window_rect.left != rect.left || data ->window_rect.top != rect.top)
        SetWindowPos( hwnd, 0, rect.left, rect.top, 0, 0,
                      SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS );
}


/***********************************************************************
 *           get_window_wm_state
 */
static int get_window_wm_state( Display *display, struct x11drv_win_data *data )
{
    struct
    {
        CARD32 state;
        XID     icon;
    } *state;
    Atom type;
    int format, ret = -1;
    unsigned long count, remaining;

    wine_tsx11_lock();
    if (!XGetWindowProperty( display, data->whole_window, x11drv_atom(WM_STATE), 0,
                             sizeof(*state)/sizeof(CARD32), False, x11drv_atom(WM_STATE),
                             &type, &format, &count, &remaining, (unsigned char **)&state ))
    {
        if (type == x11drv_atom(WM_STATE) && get_property_size( format, count ) >= sizeof(*state))
            ret = state->state;
        XFree( state );
    }
    wine_tsx11_unlock();
    return ret;
}


/***********************************************************************
 *           handle_wm_state_notify
 *
 * Handle a PropertyNotify for WM_STATE.
 */
static void handle_wm_state_notify( struct x11drv_win_data *data, XPropertyEvent *event,
                                    BOOL update_window )
{
    DWORD style;

    switch(event->state)
    {
    case PropertyDelete:
        TRACE( "%p/%lx: WM_STATE deleted from %d\n", data->hwnd, data->whole_window, data->wm_state );
        data->wm_state = WithdrawnState;
        break;
    case PropertyNewValue:
        {
            int old_state = data->wm_state;
            int new_state = get_window_wm_state( event->display, data );
            if (new_state != -1 && new_state != data->wm_state)
            {
                TRACE( "%p/%lx: new WM_STATE %d from %d\n",
                       data->hwnd, data->whole_window, new_state, old_state );
                data->wm_state = new_state;
                /* ignore the initial state transition out of withdrawn state */
                /* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
                if (!old_state) return;
            }
        }
        break;
    }

    if (!update_window || !data->managed || !data->mapped) return;

    style = GetWindowLongW( data->hwnd, GWL_STYLE );

    if (data->iconic && data->wm_state == NormalState)  /* restore window */
    {
        data->iconic = FALSE;
        if (is_net_wm_state_maximized( event->display, data ))
        {
            if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
            {
                TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
                SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
            }
            else TRACE( "not restoring to max win %p/%lx style %08x\n",
                        data->hwnd, data->whole_window, style );
        }
        else if (style & (WS_MINIMIZE | WS_MAXIMIZE))
        {
            TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
            SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
        }
        else TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
    }
    else if (!data->iconic && data->wm_state == IconicState)
    {
        data->iconic = TRUE;
        if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
        {
            TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
            SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
        }
        else TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
    }
}


/***********************************************************************
 *           X11DRV_PropertyNotify
 */
static void X11DRV_PropertyNotify( HWND hwnd, XEvent *xev )
{
    XPropertyEvent *event = &xev->xproperty;
    struct x11drv_win_data *data;

    if (!hwnd) return;
    if (!(data = X11DRV_get_win_data( hwnd ))) return;

    if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( data, event, TRUE );
}


/* event filter to wait for a WM_STATE change notification on a window */
static Bool is_wm_state_notify( Display *display, XEvent *event, XPointer arg )
{
    if (event->xany.window != (Window)arg) return 0;
    return (event->type == DestroyNotify ||
            (event->type == PropertyNotify && event->xproperty.atom == x11drv_atom(WM_STATE)));
}

/***********************************************************************
 *           wait_for_withdrawn_state
 */
void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set )
{
    DWORD end = GetTickCount() + 2000;

    if (!data->managed) return;

    TRACE( "waiting for window %p/%lx to become %swithdrawn\n",
           data->hwnd, data->whole_window, set ? "" : "not " );

    while (data->whole_window && ((data->wm_state == WithdrawnState) == !set))
    {
        XEvent event;
        int count = 0;

        wine_tsx11_lock();
        while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)data->whole_window ))
        {
            count++;
            if (XFilterEvent( &event, None )) continue;  /* filtered, ignore it */
            if (event.type == DestroyNotify) call_event_handler( display, &event );
            else
            {
                wine_tsx11_unlock();
                handle_wm_state_notify( data, &event.xproperty, FALSE );
                wine_tsx11_lock();
            }
        }
        wine_tsx11_unlock();

        if (!count)
        {
            struct pollfd pfd;
            int timeout = end - GetTickCount();

            pfd.fd = ConnectionNumber(display);
            pfd.events = POLLIN;
            if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1)
            {
                FIXME( "window %p/%lx wait timed out\n", data->hwnd, data->whole_window );
                break;
            }
        }
    }
    TRACE( "window %p/%lx state now %d\n", data->hwnd, data->whole_window, data->wm_state );
}


static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt )
{
    RECT tempRect;

    if (!IsWindowEnabled(hQueryWnd)) return 0;
    
    GetWindowRect(hQueryWnd, &tempRect);

    if(!PtInRect(&tempRect, *lpPt)) return 0;

    if (!IsIconic( hQueryWnd ))
    {
        POINT pt = *lpPt;
        ScreenToClient( hQueryWnd, &pt );
        GetClientRect( hQueryWnd, &tempRect );

        if (PtInRect( &tempRect, pt))
        {
            HWND ret = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE|CWP_SKIPDISABLED );
            if (ret && ret != hQueryWnd)
            {
                ret = find_drop_window( ret, lpPt );
                if (ret) return ret;
            }
        }
    }

    if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0;
    
    ScreenToClient(hQueryWnd, lpPt);

    return hQueryWnd;
}

/**********************************************************************
 *           EVENT_DropFromOffix
 *
 * don't know if it still works (last Changelog is from 96/11/04)
 */
static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
{
    struct x11drv_win_data *data;
    unsigned long	data_length;
    unsigned long	aux_long;
    unsigned char*	p_data = NULL;
    Atom atom_aux;
    int			x, y, dummy;
    BOOL	        bAccept;
    Window		win, w_aux_root, w_aux_child;

    win = X11DRV_get_whole_window(hWnd);
    wine_tsx11_lock();
    XQueryPointer( event->display, win, &w_aux_root, &w_aux_child,
                   &x, &y, &dummy, &dummy, (unsigned int*)&aux_long);
    x += virtual_screen_rect.left;
    y += virtual_screen_rect.top;
    wine_tsx11_unlock();

    if (!(data = X11DRV_get_win_data( hWnd ))) return;

    /* find out drop point and drop window */
    if( x < 0 || y < 0 ||
        x > (data->whole_rect.right - data->whole_rect.left) ||
        y > (data->whole_rect.bottom - data->whole_rect.top) )
    {   
	bAccept = GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES;
	x = 0;
	y = 0; 
    }
    else
    {
    	POINT	pt = { x, y };
        HWND    hwndDrop = find_drop_window( hWnd, &pt );
	if (hwndDrop)
	{
	    x = pt.x;
	    y = pt.y;
	    bAccept = TRUE;
	}
	else
	{
	    bAccept = FALSE;
	}
    }

    if (!bAccept) return;

    wine_tsx11_lock();
    XGetWindowProperty( event->display, DefaultRootWindow(event->display),
                        x11drv_atom(DndSelection), 0, 65535, FALSE,
                        AnyPropertyType, &atom_aux, &dummy,
                        &data_length, &aux_long, &p_data);
    wine_tsx11_unlock();

    if( !aux_long && p_data)  /* don't bother if > 64K */
    {
        char *p = (char *)p_data;
        char *p_drop;

        aux_long = 0;
        while( *p )  /* calculate buffer size */
        {
            INT len = GetShortPathNameA( p, NULL, 0 );
            if (len) aux_long += len + 1;
            p += strlen(p) + 1;
        }
        if( aux_long && aux_long < 65535 )
        {
            HDROP                 hDrop;
            DROPFILES *lpDrop;

            aux_long += sizeof(DROPFILES) + 1;
            hDrop = GlobalAlloc( GMEM_SHARE, aux_long );
            lpDrop = GlobalLock( hDrop );

            if( lpDrop )
            {
                lpDrop->pFiles = sizeof(DROPFILES);
                lpDrop->pt.x = x;
                lpDrop->pt.y = y;
                lpDrop->fNC = FALSE;
                lpDrop->fWide = FALSE;
                p_drop = (char *)(lpDrop + 1);
                p = (char *)p_data;
                while(*p)
                {
                    if (GetShortPathNameA( p, p_drop, aux_long - (p_drop - (char *)lpDrop) ))
                        p_drop += strlen( p_drop ) + 1;
                    p += strlen(p) + 1;
                }
                *p_drop = '\0';
                PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
            }
        }
    }
    wine_tsx11_lock();
    if( p_data ) XFree(p_data);
    wine_tsx11_unlock();
}

/**********************************************************************
 *           EVENT_DropURLs
 *
 * drop items are separated by \n
 * each item is prefixed by its mime type
 *
 * event->data.l[3], event->data.l[4] contains drop x,y position
 */
static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
{
  struct x11drv_win_data *win_data;
  unsigned long	data_length;
  unsigned long	aux_long, drop_len = 0;
  unsigned char	*p_data = NULL; /* property data */
  char		*p_drop = NULL;
  char          *p, *next;
  int		x, y;
  DROPFILES *lpDrop;
  HDROP hDrop;
  union {
    Atom	atom_aux;
    int         i;
    Window      w_aux;
    unsigned int u;
  }		u; /* unused */

  if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return;

  wine_tsx11_lock();
  XGetWindowProperty( event->display, DefaultRootWindow(event->display),
                      x11drv_atom(DndSelection), 0, 65535, FALSE,
                      AnyPropertyType, &u.atom_aux, &u.i,
                      &data_length, &aux_long, &p_data);
  wine_tsx11_unlock();
  if (aux_long)
    WARN("property too large, truncated!\n");
  TRACE("urls=%s\n", p_data);

  if( !aux_long && p_data) {	/* don't bother if > 64K */
    /* calculate length */
    p = (char*) p_data;
    next = strchr(p, '\n');
    while (p) {
      if (next) *next=0;
      if (strncmp(p,"file:",5) == 0 ) {
	INT len = GetShortPathNameA( p+5, NULL, 0 );
	if (len) drop_len += len + 1;
      }
      if (next) {
	*next = '\n';
	p = next + 1;
	next = strchr(p, '\n');
      } else {
	p = NULL;
      }
    }

    if( drop_len && drop_len < 65535 ) {
      wine_tsx11_lock();
      XQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
                     &x, &y, &u.i, &u.i, &u.u);
      x += virtual_screen_rect.left;
      y += virtual_screen_rect.top;
      wine_tsx11_unlock();

      drop_len += sizeof(DROPFILES) + 1;
      hDrop = GlobalAlloc( GMEM_SHARE, drop_len );
      lpDrop = GlobalLock( hDrop );

      if( lpDrop && (win_data = X11DRV_get_win_data( hWnd )))
      {
	  lpDrop->pFiles = sizeof(DROPFILES);
	  lpDrop->pt.x = x;
	  lpDrop->pt.y = y;
	  lpDrop->fNC =
	    ( x < (win_data->client_rect.left - win_data->whole_rect.left)  ||
	      y < (win_data->client_rect.top - win_data->whole_rect.top)    ||
	      x > (win_data->client_rect.right - win_data->whole_rect.left) ||
	      y > (win_data->client_rect.bottom - win_data->whole_rect.top) );
	  lpDrop->fWide = FALSE;
	  p_drop = (char*)(lpDrop + 1);
      }

      /* create message content */
      if (p_drop) {
	p = (char*) p_data;
	next = strchr(p, '\n');
	while (p) {
	  if (next) *next=0;
	  if (strncmp(p,"file:",5) == 0 ) {
	    INT len = GetShortPathNameA( p+5, p_drop, 65535 );
	    if (len) {
	      TRACE("drop file %s as %s\n", p+5, p_drop);
	      p_drop += len+1;
	    } else {
	      WARN("can't convert file %s to dos name\n", p+5);
	    }
	  } else {
	    WARN("unknown mime type %s\n", p);
	  }
	  if (next) {
	    *next = '\n';
	    p = next + 1;
	    next = strchr(p, '\n');
	  } else {
	    p = NULL;
	  }
	  *p_drop = '\0';
	}

        GlobalUnlock(hDrop);
        PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
      }
    }
    wine_tsx11_lock();
    if( p_data ) XFree(p_data);
    wine_tsx11_unlock();
  }
}


/**********************************************************************
 *              handle_xembed_protocol
 */
static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event )
{
    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );

    if (!data) return;

    switch (event->data.l[1])
    {
    case XEMBED_EMBEDDED_NOTIFY:
        TRACE( "win %p/%lx XEMBED_EMBEDDED_NOTIFY owner %lx\n", hwnd, event->window, event->data.l[3] );
        data->embedder = event->data.l[3];
        break;
    default:
        TRACE( "win %p/%lx XEMBED message %lu(%lu)\n",
               hwnd, event->window, event->data.l[1], event->data.l[2] );
        break;
    }
}


/**********************************************************************
 *              handle_dnd_protocol
 */
static void handle_dnd_protocol( HWND hwnd, XClientMessageEvent *event )
{
    Window root, child;
    int root_x, root_y, child_x, child_y;
    unsigned int u;

    /* query window (drag&drop event contains only drag window) */
    wine_tsx11_lock();
    XQueryPointer( event->display, root_window, &root, &child,
                   &root_x, &root_y, &child_x, &child_y, &u);
    if (XFindContext( event->display, child, winContext, (char **)&hwnd ) != 0) hwnd = 0;
    wine_tsx11_unlock();
    if (!hwnd) return;
    if (event->data.l[0] == DndFile || event->data.l[0] == DndFiles)
        EVENT_DropFromOffiX(hwnd, event);
    else if (event->data.l[0] == DndURL)
        EVENT_DropURLs(hwnd, event);
}


struct client_message_handler
{
    int    atom;                                  /* protocol atom */
    void (*handler)(HWND, XClientMessageEvent *); /* corresponding handler function */
};

static const struct client_message_handler client_messages[] =
{
    { XATOM_MANAGER,      handle_manager_message },
    { XATOM_WM_PROTOCOLS, handle_wm_protocols },
    { XATOM__XEMBED,      handle_xembed_protocol },
    { XATOM_DndProtocol,  handle_dnd_protocol },
    { XATOM_XdndEnter,    X11DRV_XDND_EnterEvent },
    { XATOM_XdndPosition, X11DRV_XDND_PositionEvent },
    { XATOM_XdndDrop,     X11DRV_XDND_DropEvent },
    { XATOM_XdndLeave,    X11DRV_XDND_LeaveEvent }
};


/**********************************************************************
 *           X11DRV_ClientMessage
 */
static void X11DRV_ClientMessage( HWND hwnd, XEvent *xev )
{
    XClientMessageEvent *event = &xev->xclient;
    unsigned int i;

    if (!hwnd) return;

    if (event->format != 32)
    {
        WARN( "Don't know how to handle format %d\n", event->format );
        return;
    }

    for (i = 0; i < sizeof(client_messages)/sizeof(client_messages[0]); i++)
    {
        if (event->message_type == X11DRV_Atoms[client_messages[i].atom - FIRST_XATOM])
        {
            client_messages[i].handler( hwnd, event );
            return;
        }
    }
    TRACE( "no handler found for %ld\n", event->message_type );
}
