/*
 * 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>

#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
}

/***********************************************************************
 *           xembed_request_focus
 */
static void xembed_request_focus( Display *display, Window window, DWORD timestamp )
{
    XEvent xev;

    xev.xclient.type = ClientMessage;
    xev.xclient.window = window;
    xev.xclient.message_type = x11drv_atom(_XEMBED);
    xev.xclient.serial = 0;
    xev.xclient.display = display;
    xev.xclient.send_event = True;
    xev.xclient.format = 32;

    xev.xclient.data.l[0] = timestamp;
    xev.xclient.data.l[1] = XEMBED_REQUEST_FOCUS;
    xev.xclient.data.l[2] = 0;
    xev.xclient.data.l[3] = 0;
    xev.xclient.data.l[4] = 0;

    XSendEvent(display, window, False, NoEventMask, &xev);
    XFlush( display );
}

/***********************************************************************
 *           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 );
    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;
}


/***********************************************************************
 *           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;
    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 );
    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 )
{
    LONG style = GetWindowLongW( hwnd, GWL_STYLE );
    RECT rect;

    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 (GetWindowRect( hwnd, &rect ) && IsRectEmpty( &rect )) return FALSE;
    return !(style & WS_DISABLED);
}


/**********************************************************************
 *              set_input_focus
 *
 * Try to force focus for embedded or non-managed windows.
 */
static void set_input_focus( struct x11drv_win_data *data )
{
    XWindowChanges changes;
    DWORD timestamp;

    if (!data->whole_window) return;

    if (EVENT_x11_time_to_win32_time(0))
        /* ICCCM says don't use CurrentTime, so try to use last message time if possible */
        /* FIXME: this is not entirely correct */
        timestamp = GetMessageTime() - EVENT_x11_time_to_win32_time(0);
    else
        timestamp = CurrentTime;

    /* Set X focus and install colormap */
    changes.stack_mode = Above;
    XConfigureWindow( data->display, data->whole_window, CWStackMode, &changes );

    if (data->embedder)
        xembed_request_focus( data->display, data->embedder, timestamp );
    else
        XSetInputFocus( data->display, data->whole_window, RevertToParent, timestamp );

}

/**********************************************************************
 *              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 );
        XSetInputFocus( display, win, RevertToParent, time );
    }
}


/**********************************************************************
 *              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");
      xev.window = DefaultRootWindow(xev.display);
      XSendEvent(xev.display, xev.window, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xev);
    }
}


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 ))) XSetICFocus( xic );
    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 );
}

/**********************************************************************
 *              focus_out
 */
 static void focus_out( Display *display , HWND hwnd )
 {
    HWND hwnd_tmp;
    Window focus_win;
    int revert;
    XIC xic;

    if (ximInComposeMode) return;

    x11drv_thread_data()->last_focus = hwnd;
    if ((xic = X11DRV_get_ic( hwnd ))) XUnsetICFocus( xic );

    if (root_window != DefaultRootWindow(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 */

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

    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_FocusOut
 *
 * Note: only top-level windows get FocusOut events.
 */
static void X11DRV_FocusOut( HWND hwnd, XEvent *xev )
{
    XFocusChangeEvent *event = &xev->xfocus;

    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;
    focus_out( event->display, hwnd );
}


/***********************************************************************
 *           X11DRV_Expose
 */
static void X11DRV_Expose( HWND hwnd, XEvent *xev )
{
    XExposeEvent *event = &xev->xexpose;
    RECT rect;
    POINT pos;
    struct x11drv_win_data *data;
    HRGN surface_region = 0;
    UINT flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN;

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

    if (event->window != root_window)
    {
        pos.x = event->x;
        pos.y = event->y;
    }
    else pos = root_to_virtual_screen( event->x, event->y );

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

    rect.left   = pos.x;
    rect.top    = pos.y;
    rect.right  = pos.x + event->width;
    rect.bottom = pos.y + event->height;

    if (event->window != data->client_window)
    {
        if (data->surface)
        {
            surface_region = expose_surface( data->surface, &rect );
            if (!surface_region) flags = 0;
            else OffsetRgn( surface_region, data->whole_rect.left - data->client_rect.left,
                            data->whole_rect.top - data->client_rect.top );

            if (data->vis.visualid != default_visual.visualid)
                data->surface->funcs->flush( data->surface );
        }
        OffsetRect( &rect, data->whole_rect.left - data->client_rect.left,
                    data->whole_rect.top - data->client_rect.top );
    }

    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;
    }
    else flags &= ~RDW_ALLCHILDREN;

    release_win_data( data );

    if (flags) RedrawWindow( hwnd, &rect, surface_region, flags );
    if (surface_region) DeleteObject( surface_region );
}


/**********************************************************************
 *		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 = TRUE;
        return;
    }
    if (!(data = get_win_data( hwnd ))) return;

    if (!data->managed && !data->embedded && data->mapped)
    {
        HWND hwndFocus = GetFocus();
        if (hwndFocus && IsChild( hwnd, hwndFocus ))
            set_input_focus( data );
    }
    release_win_data( data );
}


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


/***********************************************************************
 *     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;

    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 );
    }
    return (ret == 2);
}

/***********************************************************************
 *           reparent_notify
 */
static void reparent_notify( Display *display, HWND hwnd, Window xparent, int x, int y )
{
    HWND parent, old_parent;
    DWORD style;

    style = GetWindowLongW( hwnd, GWL_STYLE );
    if (xparent == root_window)
    {
        parent = GetDesktopWindow();
        style = (style & ~WS_CHILD) | WS_POPUP;
    }
    else
    {
        if (!(parent = create_foreign_window( display, xparent ))) 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, x, 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_ReparentNotify
 */
static void X11DRV_ReparentNotify( HWND hwnd, XEvent *xev )
{
    XReparentEvent *event = &xev->xreparent;
    struct x11drv_win_data *data;

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

    if (!data->embedded)
    {
        release_win_data( data );
        return;
    }

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

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

    reparent_notify( event->display, hwnd, event->parent, event->x, event->y );
}


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

    if (!hwnd) return;
    if (!(data = get_win_data( hwnd ))) return;
    if (!data->mapped || data->iconic) goto done;
    if (data->whole_window && !data->managed) goto done;
    /* ignore synthetic events on foreign windows */
    if (event->send_event && !data->whole_window) goto done;
    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 );
        goto done;
    }

    /* 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;
        XTranslateCoordinates( event->display, event->window, root_window,
                               0, 0, &x, &y, &child );
        root_coords = TRUE;
    }

    if (!root_coords)
    {
        pos.x = x;
        pos.y = y;
    }
    else pos = root_to_virtual_screen( x, y );

    rect.left   = pos.x;
    rect.top    = pos.y;
    rect.right  = pos.x + event->width;
    rect.bottom = pos.y + event->height;
    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 ))
        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 );

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

    if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
    {
        release_win_data( data );
        SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
        return;
    }

done:
    release_win_data( data );
}


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

    if (!data) return;

    if (data->whole_window)  /* only handle this for foreign windows */
    {
        release_win_data( data );
        return;
    }

    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 );
    window_rect = data->window_rect;
    release_win_data( data );

    if (window_rect.left != rect.left || 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, Window window )
{
    struct
    {
        CARD32 state;
        XID     icon;
    } *state;
    Atom type;
    int format, ret = -1;
    unsigned long count, remaining;

    if (!XGetWindowProperty( display, 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 );
    }
    return ret;
}


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

    if (!data) return;

    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->whole_window );
            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) goto done;
            }
        }
        break;
    }

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

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

    if (data->iconic && data->wm_state == NormalState)  /* restore window */
    {
        data->iconic = FALSE;
        if ((style & WS_CAPTION) == WS_CAPTION && 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 );
                release_win_data( data );
                SendMessageW( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
                return;
            }
            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 );
                release_win_data( data );
                SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
                return;
            }
            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 );
            release_win_data( data );
            SendMessageW( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
            return;
        }
        TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
    }
done:
    release_win_data( data );
}


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

    if (!hwnd) return;
    if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( hwnd, 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( HWND hwnd, BOOL set )
{
    Display *display = thread_display();
    struct x11drv_win_data *data;
    DWORD end = GetTickCount() + 2000;

    TRACE( "waiting for window %p to become %swithdrawn\n", hwnd, set ? "" : "not " );

    for (;;)
    {
        XEvent event;
        Window window;
        int count = 0;

        if (!(data = get_win_data( hwnd ))) break;
        if (!data->managed || data->embedded || data->display != display) break;
        if (!(window = data->whole_window)) break;
        if (!data->mapped == !set)
        {
            TRACE( "window %p/%lx now %smapped\n", hwnd, window, data->mapped ? "" : "un" );
            break;
        }
        if ((data->wm_state == WithdrawnState) != !set)
        {
            TRACE( "window %p/%lx state now %d\n", hwnd, window, data->wm_state );
            break;
        }
        release_win_data( data );

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

        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", hwnd, window );
                return;
            }
        }
    }
    release_win_data( data );
}


/*****************************************************************
 *		SetFocus   (X11DRV.@)
 *
 * Set the X focus.
 */
void CDECL X11DRV_SetFocus( HWND hwnd )
{
    struct x11drv_win_data *data;

    HWND parent;

    for (;;)
    {
        if (!(data = get_win_data( hwnd ))) return;
        if (data->embedded) break;
        parent = GetAncestor( hwnd, GA_PARENT );
        if (!parent || parent == GetDesktopWindow()) break;
        release_win_data( data );
        hwnd = parent;
    }
    if (!data->managed || data->embedder) set_input_focus( data );
    release_win_data( data );
}


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;
    POINT pt;
    unsigned long	data_length;
    unsigned long	aux_long;
    unsigned char*	p_data = NULL;
    Atom atom_aux;
    int			x, y, cx, cy, dummy;
    Window		win, w_aux_root, w_aux_child;

    if (!(data = get_win_data( hWnd ))) return;
    cx = data->whole_rect.right - data->whole_rect.left;
    cy = data->whole_rect.bottom - data->whole_rect.top;
    win = data->whole_window;
    release_win_data( data );

    XQueryPointer( event->display, win, &w_aux_root, &w_aux_child,
                   &x, &y, &dummy, &dummy, (unsigned int*)&aux_long);
    pt = root_to_virtual_screen( x, y );

    /* find out drop point and drop window */
    if (pt.x < 0 || pt.y < 0 || pt.x > cx || pt.y > cy)
    {
	if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return;
	pt.x = pt.y = 0;
    }
    else
    {
        if (!find_drop_window( hWnd, &pt )) return;
    }

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

    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 = pt;
                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 );
            }
        }
    }
    if( p_data ) XFree(p_data);
}

/**********************************************************************
 *           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;
  POINT pos;
  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;

  XGetWindowProperty( event->display, DefaultRootWindow(event->display),
                      x11drv_atom(DndSelection), 0, 65535, FALSE,
                      AnyPropertyType, &u.atom_aux, &u.i,
                      &data_length, &aux_long, &p_data);
  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 ) {
      XQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
                     &x, &y, &u.i, &u.i, &u.u);
      pos = root_to_virtual_screen( x, y );

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

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

      /* 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 );
      }
    }
    if( p_data ) XFree(p_data);
  }
}


/**********************************************************************
 *              handle_xembed_protocol
 */
static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event )
{
    switch (event->data.l[1])
    {
    case XEMBED_EMBEDDED_NOTIFY:
        {
            struct x11drv_win_data *data = get_win_data( hwnd );
            if (!data) break;

            TRACE( "win %p/%lx XEMBED_EMBEDDED_NOTIFY owner %lx\n", hwnd, event->window, event->data.l[3] );
            data->embedder = event->data.l[3];

            /* window has been marked as embedded before (e.g. systray) */
            if (data->embedded || !data->embedder /* broken QX11EmbedContainer implementation */)
            {
                release_win_data( data );
                break;
            }

            make_window_embedded( data );
            release_win_data( data );
            reparent_notify( event->display, hwnd, event->data.l[3], 0, 0 );
        }
        break;

    case XEMBED_WINDOW_DEACTIVATE:
        TRACE( "win %p/%lx XEMBED_WINDOW_DEACTIVATE message\n", hwnd, event->window );
        focus_out( event->display, GetAncestor( hwnd, GA_ROOT ) );
        break;

    case XEMBED_FOCUS_OUT:
        TRACE( "win %p/%lx XEMBED_FOCUS_OUT message\n", hwnd, event->window );
        focus_out( event->display, GetAncestor( hwnd, GA_ROOT ) );
        break;

    case XEMBED_MODALITY_ON:
        TRACE( "win %p/%lx XEMBED_MODALITY_ON message\n", hwnd, event->window );
        EnableWindow( hwnd, FALSE );
        break;

    case XEMBED_MODALITY_OFF:
        TRACE( "win %p/%lx XEMBED_MODALITY_OFF message\n", hwnd, event->window );
        EnableWindow( hwnd, TRUE );
        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) */
    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;
    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 );
}
