/*
 * X11 event driver
 *
 * Copyright 1993 Alexandre Julliard
 *	     1999 Noel Borthwick
 */

#include "config.h"

#include <X11/Xatom.h>
#include <X11/keysym.h>

#include "ts_xlib.h"
#include "ts_xresource.h"
#include "ts_xutil.h"
#ifdef HAVE_LIBXXF86DGA2
#include "ts_xf86dga2.h"
#endif

#include <assert.h>
#include <string.h>
#include "wine/winuser16.h"
#include "shlobj.h"  /* DROPFILES */

#include "clipboard.h"
#include "dce.h"
#include "debugtools.h"
#include "input.h"
#include "keyboard.h"
#include "mouse.h"
#include "options.h"
#include "win.h"
#include "winpos.h"
#include "windef.h"
#include "winreg.h"
#include "x11drv.h"
#include "shellapi.h"

DEFAULT_DEBUG_CHANNEL(event);
DECLARE_DEBUG_CHANNEL(win);
  
/* X context to associate a hwnd to an X window */
extern XContext winContext;

extern Atom wmProtocols;
extern Atom wmDeleteWindow;
extern Atom dndProtocol;
extern Atom dndSelection;

extern void X11DRV_KEYBOARD_UpdateState(void);
extern void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y );

#define NB_BUTTONS      5     /* Windows can handle 3 buttons and the wheel too */


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

/* The last X window which had the focus */
static Window glastXFocusWin = 0;

static const char * const event_names[] =
{
  "", "", "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"
};


static void EVENT_ProcessEvent( XEvent *event );
static BOOL X11DRV_CheckFocus(void);

  /* Event handlers */
static void EVENT_Key( HWND hWnd, XKeyEvent *event );
static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event );
static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event );
static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event );
static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event );
static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event );
static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event);
static void EVENT_PropertyNotify( XPropertyEvent *event );
static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
static void EVENT_MappingNotify( XMappingEvent *event );

extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event );
extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
extern void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event );

#ifdef HAVE_LIBXXF86DGA2
static int DGAMotionEventType;
static int DGAButtonPressEventType;
static int DGAButtonReleaseEventType;
static int DGAKeyPressEventType;
static int DGAKeyReleaseEventType;

static BOOL DGAUsed = FALSE;
static HWND DGAhwnd = 0;

static void EVENT_DGAMotionEvent( XDGAMotionEvent *event );
static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event );
static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event );
#endif

/* Static used for the current input method */
static INPUT_TYPE current_input_type = X11DRV_INPUT_ABSOLUTE;
static BOOL in_transition = FALSE; /* This is not used as for today */


/***********************************************************************
 *           process_events
 */
static int process_events( struct x11drv_thread_data *data )
{
    XEvent event;
    int count = 0;

    wine_tsx11_lock();
    while ( XPending( data->display ) )
    {
        XNextEvent( data->display, &event );
        wine_tsx11_unlock();
        EVENT_ProcessEvent( &event );
        count++;
        wine_tsx11_lock();
    }
    wine_tsx11_unlock();
    return count;
}


/***********************************************************************
 *           MsgWaitForMultipleObjectsEx   (X11DRV.@)
 */
DWORD X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
                                          DWORD timeout, DWORD mask, DWORD flags )
{
    HANDLE new_handles[MAXIMUM_WAIT_OBJECTS+1];  /* FIXME! */
    DWORD i, ret;
    struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;

    if (!data || data->process_event_count)
        return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
                                         timeout, flags & MWMO_ALERTABLE );

    for (i = 0; i < count; i++) new_handles[i] = handles[i];
    new_handles[count] = data->display_fd;

    wine_tsx11_lock();
    XFlush( gdi_display );
    XFlush( data->display );
    wine_tsx11_unlock();

    data->process_event_count++;
    if (process_events( data )) ret = count;
    else
    {
        ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
                                        timeout, flags & MWMO_ALERTABLE );
        if (ret == count) process_events( data );
    }
    data->process_event_count--;
    return ret;
}


/***********************************************************************
 *           EVENT_ProcessEvent
 *
 * Process an X event.
 */
static void EVENT_ProcessEvent( XEvent *event )
{
  HWND hWnd;
  Display *display = event->xany.display;

  TRACE( "called.\n" );

  switch (event->type)
  {
    case SelectionNotify: /* all of these should be caught by XCheckTypedWindowEvent() */
	 FIXME("Got SelectionNotify - must not happen!\n");
	 /* fall through */

      /* We get all these because of StructureNotifyMask.
         This check is placed here to avoid getting error messages below,
         as X might send some of these even for windows that have already
         been deleted ... */
    case CirculateNotify:
    case CreateNotify:
    case DestroyNotify:
    case GravityNotify:
    case ReparentNotify:
      return;
  }

#ifdef HAVE_LIBXXF86DGA2
  if (DGAUsed) {
    if (event->type == DGAMotionEventType) {
      TRACE("DGAMotionEvent received.\n");
      EVENT_DGAMotionEvent((XDGAMotionEvent *) event);
      return;
    }
    if (event->type == DGAButtonPressEventType) {
      TRACE("DGAButtonPressEvent received.\n");
      EVENT_DGAButtonPressEvent((XDGAButtonEvent *) event);
      return;
    }
    if (event->type == DGAButtonReleaseEventType) {
      TRACE("DGAButtonReleaseEvent received.\n");
      EVENT_DGAButtonReleaseEvent((XDGAButtonEvent *) event);
      return;
    }
    if ((event->type == DGAKeyPressEventType) ||
	(event->type == DGAKeyReleaseEventType)) {
      /* Fill a XKeyEvent to send to EVENT_Key */
      POINT pt;
      XKeyEvent ke;
      XDGAKeyEvent *evt = (XDGAKeyEvent *) event;

      TRACE("DGAKeyPress/ReleaseEvent received.\n");
      
      GetCursorPos( &pt );
      if (evt->type == DGAKeyReleaseEventType)
	ke.type = KeyRelease;
      else
	ke.type = KeyPress;
      ke.serial = evt->serial;
      ke.send_event = FALSE;
      ke.display = evt->display;
      ke.window = 0;
      ke.root = 0;
      ke.subwindow = 0;
      ke.time = evt->time;
      ke.x = pt.x;
      ke.y = pt.y;
      ke.x_root = -1;
      ke.y_root = -1;
      ke.state = evt->state;
      ke.keycode = evt->keycode;
      ke.same_screen = TRUE;
      
      X11DRV_KEYBOARD_HandleEvent(&ke,pt.x,pt.y);
      return;
    }
  }
#endif

  if (TSXFindContext( display, event->xany.window, winContext, (char **)&hWnd ) != 0)
      hWnd = 0;  /* Not for a registered window */

  if ( !hWnd && event->xany.window != root_window
             && event->type != PropertyNotify 
             && event->type != MappingNotify)
      WARN( "Got event %s for unknown Window %08lx\n",
            event_names[event->type], event->xany.window );
  else
      TRACE("Got event %s for hwnd %04x\n",
            event_names[event->type], hWnd );

  switch(event->type)
    {
    case KeyPress:
    case KeyRelease:
      EVENT_Key( hWnd, (XKeyEvent*)event );
      break;
      
    case ButtonPress:
      EVENT_ButtonPress( hWnd, (XButtonEvent*)event );
      break;
      
    case ButtonRelease:
      EVENT_ButtonRelease( hWnd, (XButtonEvent*)event );
      break;

    case MotionNotify:
      EVENT_MotionNotify( hWnd, (XMotionEvent*)event );
      break;

    case FocusIn:
      EVENT_FocusIn( hWnd, (XFocusChangeEvent*)event );
      break;

    case FocusOut:
      EVENT_FocusOut( hWnd, (XFocusChangeEvent*)event );
      break;

    case Expose:
      X11DRV_Expose( hWnd, &event->xexpose );
      break;

    case ConfigureNotify:
      if (!hWnd) return;
      X11DRV_ConfigureNotify( hWnd, &event->xconfigure );
      break;

    case SelectionRequest:
      if (!hWnd) return;
      EVENT_SelectionRequest( hWnd, (XSelectionRequestEvent *)event, FALSE );
      break;

    case SelectionClear:
      if (!hWnd) return;
      EVENT_SelectionClear( hWnd, (XSelectionClearEvent*) event );
      break;
      
    case PropertyNotify:
      EVENT_PropertyNotify( (XPropertyEvent *)event );
      break;

    case ClientMessage:
      if (!hWnd) return;
      EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event );
      break;

    case NoExpose:
      break;

    case MapNotify:
      X11DRV_MapNotify( hWnd, (XMapEvent *)event );
      break;

    case UnmapNotify:
      X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event );
      break;

    case MappingNotify:
      EVENT_MappingNotify( (XMappingEvent *) event );
      break;

    default:    
      WARN("Unprocessed event %s for hwnd %04x\n",
	   event_names[event->type], hWnd );
      break;
    }
    TRACE( "returns.\n" );
}

/***********************************************************************
 *           X11DRV_EVENT_XStateToKeyState
 *
 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
 */
WORD X11DRV_EVENT_XStateToKeyState( int state )
{
  int kstate = 0;
  
  if (state & Button1Mask) kstate |= MK_LBUTTON;
  if (state & Button2Mask) kstate |= MK_MBUTTON;
  if (state & Button3Mask) kstate |= MK_RBUTTON;
  if (state & ShiftMask)   kstate |= MK_SHIFT;
  if (state & ControlMask) kstate |= MK_CONTROL;
  return kstate;
}


/* get the coordinates of a mouse event */
static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt )
{
    struct x11drv_win_data *data;
    WND *win;

    if (!(win = WIN_FindWndPtr( *hwnd ))) return;
    data = win->pDriverData;

    if (window == data->whole_window)
    {
        x -= data->client_rect.left;
        y -= data->client_rect.top;
    }
    while (win->parent && win->parent->hwndSelf != GetDesktopWindow())
    {
        x += win->rectClient.left;
        y += win->rectClient.top;
        WIN_UpdateWndPtr( &win, win->parent );
    }
    pt->x = x + win->rectClient.left;
    pt->y = y + win->rectClient.top;
    *hwnd = win->hwndSelf;
    WIN_ReleaseWndPtr( win );
}


/***********************************************************************
 *           EVENT_Key
 *
 * Handle a X key event
 */
static void EVENT_Key( HWND hWnd, XKeyEvent *event )
{
    POINT pt;
    get_coords( &hWnd, event->window, event->x, event->y, &pt );
    X11DRV_KEYBOARD_HandleEvent( event, pt.x, pt.y );
}


/***********************************************************************
 *           EVENT_MotionNotify
 */
static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event )
{
    POINT pt;

    if (current_input_type == X11DRV_INPUT_ABSOLUTE)
    {
        get_coords( &hWnd, event->window, event->x, event->y, &pt );
        X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, pt.x, pt.y,
                          X11DRV_EVENT_XStateToKeyState( event->state ), 0,
                          event->time - X11DRV_server_startticks, hWnd);
    }
    else
    {
        X11DRV_SendEvent( MOUSEEVENTF_MOVE,
                          event->x_root, event->y_root,
                          X11DRV_EVENT_XStateToKeyState( event->state ), 0,
                          event->time - X11DRV_server_startticks, hWnd);
    }
}


/***********************************************************************
 *           EVENT_ButtonPress
 */
static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event )
{
    static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN,
                                                  MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL,
                                                  MOUSEEVENTF_WHEEL};
    int buttonNum = event->button - 1;
    WORD keystate, wData = 0;
    POINT pt;

    if (buttonNum >= NB_BUTTONS) return;

    get_coords( &hWnd, event->window, event->x, event->y, &pt );

    /* Get the compatible keystate */
    keystate = X11DRV_EVENT_XStateToKeyState( event->state );

    /*
     * Make sure that the state of the button that was just 
     * pressed is "down".
     */
    switch (buttonNum)
    {
    case 0:
        keystate |= MK_LBUTTON;
        break;
    case 1:
        keystate |= MK_MBUTTON;
        break;
    case 2:
        keystate |= MK_RBUTTON;
        break;
    case 3:
        wData = WHEEL_DELTA;
        break;
    case 4:
        wData = -WHEEL_DELTA;
        break;
    }

    X11DRV_SendEvent( statusCodes[buttonNum], pt.x, pt.y,
                      keystate, wData, event->time - X11DRV_server_startticks, hWnd);
}


/***********************************************************************
 *           EVENT_ButtonRelease
 */
static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event )
{
    static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP,
                                                  MOUSEEVENTF_RIGHTUP, 0, 0 };
    int buttonNum = event->button - 1;
    WORD keystate;
    POINT pt;

    if (buttonNum >= NB_BUTTONS) return;

    get_coords( &hWnd, event->window, event->x, event->y, &pt );

    /* Get the compatible keystate */
    keystate = X11DRV_EVENT_XStateToKeyState( event->state );

    /*
     * Make sure that the state of the button that was just 
     * released is "up".
     */
    switch (buttonNum)
    {
    case 0:
        keystate &= ~MK_LBUTTON;
        break;
    case 1:
        keystate &= ~MK_MBUTTON;
        break;
    case 2:
        keystate &= ~MK_RBUTTON;
        break;
    default:
        return;
    }
    X11DRV_SendEvent( statusCodes[buttonNum], pt.x, pt.y,
                      keystate, 0, event->time - X11DRV_server_startticks, hWnd);
}


/**********************************************************************
 *              EVENT_FocusIn
 */
static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event )
{
    WND *pWndLastFocus;
    XWindowAttributes win_attr;
    BOOL bIsDisabled;

    if (!hWnd) return;

    bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;

    /* If the window has been disabled and we are in managed mode,
       * revert the X focus back to the last focus window. This is to disallow
       * the window manager from switching focus away while the app is
       * in a modal state.
       */
    if ( Options.managed && bIsDisabled && glastXFocusWin)
    {
        /* Change focus only if saved focus window is registered and viewable */
        wine_tsx11_lock();
        if (XFindContext( event->display, glastXFocusWin, winContext,
                           (char **)&pWndLastFocus ) == 0 )
        {
            if (XGetWindowAttributes( event->display, glastXFocusWin, &win_attr ) &&
                (win_attr.map_state == IsViewable) )
            {
                XSetInputFocus( event->display, glastXFocusWin, RevertToParent, CurrentTime );
                wine_tsx11_unlock();
                return;
            }
        }
        wine_tsx11_unlock();
    }

    if (event->detail != NotifyPointer && hWnd != GetForegroundWindow())
    {
        SetForegroundWindow( hWnd );
        X11DRV_KEYBOARD_UpdateState();
    }
}


/**********************************************************************
 *              EVENT_FocusOut
 *
 * Note: only top-level override-redirect windows get FocusOut events.
 */
static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event )
{
    /* Save the last window which had the focus */
    glastXFocusWin = event->window;
    if (!hWnd) return;
    if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED) glastXFocusWin = 0;

    if (event->detail != NotifyPointer && hWnd == GetForegroundWindow())
    {
        /* don't reset the foreground window, if the window which is
               getting the focus is a Wine window */
        if (!X11DRV_CheckFocus())
        {
            SendMessageA( hWnd, WM_CANCELMODE, 0, 0 );
            /* 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())
                SetForegroundWindow( 0 );
        }
    }
}

/**********************************************************************
 *		CheckFocus (X11DRV.@)
 */
static BOOL X11DRV_CheckFocus(void)
{
    Display *display = thread_display();
  HWND   hWnd;
  Window xW;
  int	   state;
  
  TSXGetInputFocus(display, &xW, &state);
    if( xW == None ||
        TSXFindContext(display, xW, winContext, (char **)&hWnd) ) 
      return FALSE;
    return TRUE;
}


/***********************************************************************
 *           EVENT_SelectionRequest_TARGETS
 *  Service a TARGETS selection request event
 */
static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
                                            Atom target, Atom rprop )
{
    Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
    Atom* targets;
    Atom prop;
    UINT wFormat;
    unsigned long cTargets;
    BOOL bHavePixmap;
    int xRc;

    TRACE("Request for %s\n", TSXGetAtomName(display, target));
    
    /*
     * Count the number of items we wish to expose as selection targets.
     * We include the TARGETS item, and a PIXMAP if we have CF_DIB or CF_BITMAP
     */
    cTargets = CountClipboardFormats() + 1;
    if ( CLIPBOARD_IsPresent(CF_DIB) ||  CLIPBOARD_IsPresent(CF_BITMAP) )
       cTargets++;
    
    /* Allocate temp buffer */
    targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
    if(targets == NULL) return None;

    /* Create TARGETS property list (First item in list is TARGETS itself) */

    for ( targets[0] = xaTargets, cTargets = 1, wFormat = 0, bHavePixmap = FALSE;
          (wFormat = EnumClipboardFormats( wFormat )); )
    {
        if ( (prop = X11DRV_CLIPBOARD_MapFormatToProperty(wFormat)) != None )
        {
            /* Scan through what we have so far to avoid duplicates */
            int i;
            BOOL bExists;
            for (i = 0, bExists = FALSE; i < cTargets; i++)
            {
                if (targets[i] == prop)
                {
                    bExists = TRUE;
                    break;
                }
            }
            if (!bExists)
            {
                targets[cTargets++] = prop;
            
                /* Add PIXMAP prop for bitmaps additionally */
                if ( (wFormat == CF_DIB || wFormat == CF_BITMAP )
                     && !bHavePixmap )
                {
                    targets[cTargets++] = XA_PIXMAP;
                    bHavePixmap = TRUE;
                }
            }
        }
    }

    if (TRACE_ON(event))
    {
        int i;
        for ( i = 0; i < cTargets; i++)
        {
            if (targets[i])
            {
                char *itemFmtName = TSXGetAtomName(display, targets[i]);
                TRACE("\tAtom# %d:  Type %s\n", i, itemFmtName);
                TSXFree(itemFmtName);
            }
        }
    }
    
    /* Update the X property */
    TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));

    /* We may want to consider setting the type to xaTargets instead,
     * in case some apps expect this instead of XA_ATOM */
    xRc = TSXChangeProperty(display, requestor, rprop,
                            XA_ATOM, 32, PropModeReplace,
                            (unsigned char *)targets, cTargets);
    TRACE("(Rc=%d)\n", xRc);
    
    HeapFree( GetProcessHeap(), 0, targets );

    return rprop;
}


/***********************************************************************
 *           EVENT_SelectionRequest_STRING
 *  Service a STRING selection request event
 */
static Atom EVENT_SelectionRequest_STRING( Display *display, Window requestor,
                                           Atom target, Atom rprop )
{
    static UINT text_cp = (UINT)-1;
    HANDLE hUnicodeText;
    LPWSTR uni_text;
    LPSTR  text;
    int    size,i,j;
    char* lpstr = 0;
    char *itemFmtName;
    int xRc;

    if(text_cp == (UINT)-1)
    {
	HKEY hkey;
	/* default value */
	text_cp = CP_ACP;
	if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\x11drv", &hkey))
	{
	    char buf[20];
	    DWORD type, count = sizeof(buf);
	    if(!RegQueryValueExA(hkey, "TextCP", 0, &type, buf, &count))
		text_cp = atoi(buf);
	    RegCloseKey(hkey);
	  }
    }

    /*
     * Map the requested X selection property type atom name to a
     * windows clipboard format ID.
     */
    itemFmtName = TSXGetAtomName(display, target);
    TRACE("Request for %s (wFormat=%x %s)\n",
	itemFmtName, CF_UNICODETEXT, CLIPBOARD_GetFormatName(CF_UNICODETEXT));
    TSXFree(itemFmtName);

    hUnicodeText = GetClipboardData(CF_UNICODETEXT);
    if(!hUnicodeText)
       return None;
    uni_text = GlobalLock(hUnicodeText);
    if(!uni_text)
       return None;

    size = WideCharToMultiByte(text_cp, 0, uni_text, -1, NULL, 0, NULL, NULL);
    text = HeapAlloc(GetProcessHeap(), 0, size);
    if (!text)
       return None;
    WideCharToMultiByte(text_cp, 0, uni_text, -1, text, size, NULL, NULL);

    /* remove carriage returns */
    
    lpstr = (char*)HeapAlloc( GetProcessHeap(), 0, size-- );
    if(lpstr == NULL) return None;
    for(i=0,j=0; i < size && text[i]; i++ )
    {
        if( text[i] == '\r' && 
            (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
        lpstr[j++] = text[i];
    }
    lpstr[j]='\0';
    
    /* Update the X property */
    TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
    xRc = TSXChangeProperty(display, requestor, rprop,
                            XA_STRING, 8, PropModeReplace,
                            lpstr, j);
    TRACE("(Rc=%d)\n", xRc);

    GlobalUnlock(hUnicodeText);
    HeapFree(GetProcessHeap(), 0, text);
    HeapFree( GetProcessHeap(), 0, lpstr );

    return rprop;
}

/***********************************************************************
 *           EVENT_SelectionRequest_PIXMAP
 *  Service a PIXMAP selection request event
 */
static Atom EVENT_SelectionRequest_PIXMAP( Display *display, Window requestor,
                                           Atom target, Atom rprop )
{
    HANDLE hClipData = 0;
    Pixmap pixmap = 0;
    UINT   wFormat;
    char * itemFmtName;
    int xRc;
#if(0)
    XSetWindowAttributes win_attr;
    XWindowAttributes win_attr_src;
#endif
    
    /*
     * Map the requested X selection property type atom name to a
     * windows clipboard format ID.
     */
    itemFmtName = TSXGetAtomName(display, target);
    wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
    TRACE("Request for %s (wFormat=%x %s)\n",
                  itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat));
    TSXFree(itemFmtName);
    
    hClipData = GetClipboardData(wFormat);
    if ( !hClipData )
    {
        TRACE("Could not retrieve a Pixmap compatible format from clipboard!\n");
        rprop = None; /* Fail the request */
        goto END;
    }

    if (wFormat == CF_DIB)
    {
        HWND hwnd = GetOpenClipboardWindow();
        HDC hdc = GetDC(hwnd);
        
        /* For convert from packed DIB to Pixmap */
        pixmap = X11DRV_DIB_CreatePixmapFromDIB(hClipData, hdc);
        
        ReleaseDC(hdc, hwnd);
    }
    else if (wFormat == CF_BITMAP)
    {
        HWND hwnd = GetOpenClipboardWindow();
        HDC hdc = GetDC(hwnd);
        
        pixmap = X11DRV_BITMAP_CreatePixmapFromBitmap(hClipData, hdc);

        ReleaseDC(hdc, hwnd);
    }
    else
    {
        FIXME("%s to PIXMAP conversion not yet implemented!\n",
                      CLIPBOARD_GetFormatName(wFormat));
        rprop = None;
        goto END;
    }

    TRACE("\tUpdating property %s on Window %ld with %s %ld...\n",
          TSXGetAtomName(display, rprop), (long)requestor,
          TSXGetAtomName(display, target), pixmap);

    /* Store the Pixmap handle in the property */
    xRc = TSXChangeProperty(display, requestor, rprop, target, 
                            32, PropModeReplace,
                            (unsigned char *)&pixmap, 1);
    TRACE("(Rc=%d)\n", xRc);

    /* Enable the code below if you want to handle destroying Pixmap resources
     * in response to property notify events. Clients like XPaint don't
     * appear to be duplicating Pixmaps so they don't like us deleting,
     * the resource in response to the property being deleted.
     */
#if(0)
    /* Express interest in property notify events so that we can delete the
     * pixmap when the client deletes the property atom.
     */
    xRc = TSXGetWindowAttributes(display, requestor, &win_attr_src);
    TRACE("Turning on PropertyChangeEvent notifications from window %ld\n",
          (long)requestor);
    win_attr.event_mask = win_attr_src.your_event_mask | PropertyChangeMask;
    TSXChangeWindowAttributes(display, requestor, CWEventMask, &win_attr);

    /* Register the Pixmap we created with the request property Atom.
     * When this property is destroyed we also destroy the Pixmap in
     * response to the PropertyNotify event.
     */
    X11DRV_CLIPBOARD_RegisterPixmapResource( rprop, pixmap );
#endif
    
END:
    return rprop;
}


/***********************************************************************
 *           EVENT_SelectionRequest_WCF
 *  Service a Wine Clipboard Format selection request event.
 *  For <WCF>* data types we simply copy the data to X without conversion.
 */
static Atom EVENT_SelectionRequest_WCF( Display *display, Window requestor,
                                        Atom target, Atom rprop )
{
    HANDLE hClipData = 0;
    void*  lpClipData;
    UINT   wFormat;
    char * itemFmtName;
    int cBytes;
    int xRc;
    
    /*
     * Map the requested X selection property type atom name to a
     * windows clipboard format ID.
     */
    itemFmtName = TSXGetAtomName(display, target);
    wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
    TRACE("Request for %s (wFormat=%x %s)\n",
          itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat));
    TSXFree(itemFmtName);
    
    hClipData = GetClipboardData(wFormat);
    
    if( hClipData && (lpClipData = GlobalLock(hClipData)) )
    {
        cBytes = GlobalSize(hClipData);
        
        TRACE("\tUpdating property %s, %d bytes...\n",
              TSXGetAtomName(display, rprop), cBytes);
        
        xRc = TSXChangeProperty(display, requestor, rprop,
                                target, 8, PropModeReplace,
                                (unsigned char *)lpClipData, cBytes);
        TRACE("(Rc=%d)\n", xRc);
        
        GlobalUnlock(hClipData);
    }
    else
    {
        TRACE("\tCould not retrieve native format!\n");
        rprop = None; /* Fail the request */
    }
    
    return rprop;
}


/***********************************************************************
 *           EVENT_SelectionRequest_MULTIPLE
 *  Service a MULTIPLE selection request event
 *  rprop contains a list of (target,property) atom pairs.
 *  The first atom names a target and the second names a property.
 *  The effect is as if we have received a sequence of SelectionRequest events
 *  (one for each atom pair) except that:
 *  1. We reply with a SelectionNotify only when all the requested conversions
 *  have been performed.
 *  2. If we fail to convert the target named by an atom in the MULTIPLE property,
 *  we replace the atom in the property by None.
 */
static Atom EVENT_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent )
{
    Display *display = pevent->display;
    Atom           rprop;
    Atom           atype=AnyPropertyType;
    int		   aformat;
    unsigned long  remain;
    Atom*	   targetPropList=NULL;
    unsigned long  cTargetPropList = 0;
/*  Atom           xAtomPair = TSXInternAtom(display, "ATOM_PAIR", False); */
    
   /* If the specified property is None the requestor is an obsolete client.
    * We support these by using the specified target atom as the reply property.
    */
    rprop = pevent->property;
    if( rprop == None ) 
        rprop = pevent->target;
    if (!rprop)
        goto END;

    /* Read the MULTIPLE property contents. This should contain a list of
     * (target,property) atom pairs.
     */
    if(TSXGetWindowProperty(display, pevent->requestor, rprop,
                            0, 0x3FFF, False, AnyPropertyType, &atype,&aformat,
                            &cTargetPropList, &remain,
                            (unsigned char**)&targetPropList) != Success)
        TRACE("\tCouldn't read MULTIPLE property\n");
    else
    {
       TRACE("\tType %s,Format %d,nItems %ld, Remain %ld\n",
             TSXGetAtomName(display, atype), aformat, cTargetPropList, remain);

       /*
        * Make sure we got what we expect.
        * NOTE: According to the X-ICCCM Version 2.0 documentation the property sent
        * in a MULTIPLE selection request should be of type ATOM_PAIR.
        * However some X apps(such as XPaint) are not compliant with this and return
        * a user defined atom in atype when XGetWindowProperty is called.
        * The data *is* an atom pair but is not denoted as such.
        */
       if(aformat == 32 /* atype == xAtomPair */ )
       {
          int i;
          
          /* Iterate through the ATOM_PAIR list and execute a SelectionRequest
           * for each (target,property) pair */

          for (i = 0; i < cTargetPropList; i+=2)
          {
              char *targetName = TSXGetAtomName(display, targetPropList[i]);
              char *propName = TSXGetAtomName(display, targetPropList[i+1]);
              XSelectionRequestEvent event;

              TRACE("MULTIPLE(%d): Target='%s' Prop='%s'\n",
                    i/2, targetName, propName);
              TSXFree(targetName);
              TSXFree(propName);
              
              /* We must have a non "None" property to service a MULTIPLE target atom */
              if ( !targetPropList[i+1] )
              {
                  TRACE("\tMULTIPLE(%d): Skipping target with empty property!\n", i);
                  continue;
              }
              
              /* Set up an XSelectionRequestEvent for this (target,property) pair */
              memcpy( &event, pevent, sizeof(XSelectionRequestEvent) );
              event.target = targetPropList[i];
              event.property = targetPropList[i+1];
                  
              /* Fire a SelectionRequest, informing the handler that we are processing
               * a MULTIPLE selection request event.
               */
              EVENT_SelectionRequest( hWnd, &event, TRUE );
          }
       }

       /* Free the list of targets/properties */
       TSXFree(targetPropList);
    }

END:
    return rprop;
}


/***********************************************************************
 *           EVENT_SelectionRequest
 *  Process an event selection request event.
 *  The bIsMultiple flag is used to signal when EVENT_SelectionRequest is called
 *  recursively while servicing a "MULTIPLE" selection target.
 *
 *  Note: We only receive this event when WINE owns the X selection
 */
static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple )
{
    Display *display = event->display;
  XSelectionEvent result;
  Atom 	          rprop = None;
  Window          request = event->requestor;
  BOOL            couldOpen = FALSE;
  Atom            xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
  Atom            xaTargets = TSXInternAtom(display, "TARGETS", False);
  Atom            xaMultiple = TSXInternAtom(display, "MULTIPLE", False);

  /*
   * We can only handle the selection request if :
   * The selection is PRIMARY or CLIPBOARD, AND we can successfully open the clipboard.
   * Don't do these checks or open the clipboard while recursively processing MULTIPLE,
   * since this has been already done.
   */
  if ( !bIsMultiple )
  {
    if ( ( (event->selection != XA_PRIMARY) && (event->selection != xaClipboard) )
        || !(couldOpen = OpenClipboard(hWnd)) )
       goto END;
  }

  /* If the specified property is None the requestor is an obsolete client.
   * We support these by using the specified target atom as the reply property.
   */
  rprop = event->property;
  if( rprop == None ) 
      rprop = event->target;
  
  if(event->target == xaTargets)  /*  Return a list of all supported targets */
  {
      /* TARGETS selection request */
      rprop = EVENT_SelectionRequest_TARGETS( display, request, event->target, rprop );
  }
  else if(event->target == xaMultiple)  /*  rprop contains a list of (target, property) atom pairs */
  {
      /* MULTIPLE selection request */
      rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
  }
  else if(event->target == XA_STRING)  /* treat CF_TEXT as Unix text */
  {
      /* XA_STRING selection request */
      rprop = EVENT_SelectionRequest_STRING( display, request, event->target, rprop );
  }
  else if(event->target == XA_PIXMAP)  /*  Convert DIB's to Pixmaps */
  {
      /* XA_PIXMAP selection request */
      rprop = EVENT_SelectionRequest_PIXMAP( display, request, event->target, rprop );
  }
  else if(event->target == XA_BITMAP)  /*  Convert DIB's to 1-bit Pixmaps */
  {
      /* XA_BITMAP selection request - TODO: create a monochrome Pixmap */
      rprop = EVENT_SelectionRequest_PIXMAP( display, request, XA_PIXMAP, rprop );
  }
  else if(X11DRV_CLIPBOARD_IsNativeProperty(event->target)) /* <WCF>* */
  {
      /* All <WCF> selection requests */
      rprop = EVENT_SelectionRequest_WCF( display, request, event->target, rprop );
  }
  else
      rprop = None;  /* Don't support this format */

END:
  /* close clipboard only if we opened before */
  if(couldOpen) CloseClipboard();
  
  if( rprop == None) 
      TRACE("\tRequest ignored\n");

  /* reply to sender 
   * SelectionNotify should be sent only at the end of a MULTIPLE request
   */
  if ( !bIsMultiple )
  {
    result.type = SelectionNotify;
    result.display = display;
    result.requestor = request;
    result.selection = event->selection;
    result.property = rprop;
    result.target = event->target;
    result.time = event->time;
    TRACE("Sending SelectionNotify event...\n");
    TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
  }
}

/***********************************************************************
 *           EVENT_SelectionClear
 */
static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
{
  Atom xaClipboard = TSXInternAtom(event->display, "CLIPBOARD", False);
    
  if (event->selection == XA_PRIMARY || event->selection == xaClipboard)
      X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd );
}

/***********************************************************************
 *           EVENT_PropertyNotify
 *   We use this to release resources like Pixmaps when a selection
 *   client no longer needs them.
 */
static void EVENT_PropertyNotify( XPropertyEvent *event )
{
  /* Check if we have any resources to free */
  TRACE("Received PropertyNotify event: \n");

  switch(event->state)
  {
    case PropertyDelete:
    {
      TRACE("\tPropertyDelete for atom %s on window %ld\n",
            TSXGetAtomName(event->display, event->atom), (long)event->window);
      
      if (X11DRV_IsSelectionOwner())
          X11DRV_CLIPBOARD_FreeResources( event->atom );
      break;
    }

    case PropertyNewValue:
    {
      TRACE("\tPropertyNewValue for atom %s on window %ld\n\n",
            TSXGetAtomName(event->display, event->atom), (long)event->window);
      break;
    }
    
    default:
      break;
  }
}

/**********************************************************************
 *           EVENT_DropFromOffix
 *
 * don't know if it still works (last Changlog is from 96/11/04)
 */
static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
{
  unsigned long		data_length;
  unsigned long		aux_long;
  unsigned char*	p_data = NULL;
  union {
    Atom		atom_aux;
    struct {
      int x;
      int y;
    } pt_aux;
    int		i;
  }		u;
  int			x, y;
  BOOL16	        bAccept;
  HGLOBAL16		hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, sizeof(DRAGINFO16));
  LPDRAGINFO16          lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
  SEGPTR		spDragInfo = K32WOWGlobalLock16(hDragInfo);
  Window		w_aux_root, w_aux_child;
  WND*			pDropWnd;
  WND*                  pWnd;
  
  if( !lpDragInfo || !spDragInfo ) return;
  
  pWnd = WIN_FindWndPtr(hWnd);
  
  TSXQueryPointer( event->display, get_whole_window(pWnd), &w_aux_root, &w_aux_child,
                   &x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
                   (unsigned int*)&aux_long);
  
  lpDragInfo->hScope = hWnd;
  lpDragInfo->pt.x = (INT16)x; lpDragInfo->pt.y = (INT16)y;
  
  /* find out drop point and drop window */
  if( x < 0 || y < 0 ||
      x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
      y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
    {   bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES; x = y = 0; }
  else
    {
      bAccept = DRAG_QueryUpdate( hWnd, spDragInfo, TRUE );
      x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
    }
  pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
  WIN_ReleaseWndPtr(pWnd);
  
  GlobalFree16( hDragInfo );
  
  if( bAccept )
    {
      TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
			    dndSelection, 0, 65535, FALSE,
			    AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
			    &data_length, &aux_long, &p_data);
      
      if( !aux_long && p_data)	/* don't bother if > 64K */
	{
	  signed char *p = (signed char*) p_data;
	  char *p_drop;
	  
	  aux_long = 0; 
	  while( *p )	/* calculate buffer size */
	    {
	      p_drop = p;
	      if((u.i = *p) != -1 ) 
		{
		  INT len = GetShortPathNameA( p, NULL, 0 );
		  if (len) aux_long += len + 1;
		  else *p = -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 = (DROPFILES*)GlobalLock( hDrop );
	      
	      if( lpDrop )
		{
		  lpDrop->pFiles = sizeof(DROPFILES);
		  lpDrop->pt.x = x;
		  lpDrop->pt.y = y;
		  lpDrop->fNC =
		    ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left)  ||
		      y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top)    ||
		      x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
		      y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
                  lpDrop->fWide = FALSE;
		  p_drop = (char *)(lpDrop + 1);
		  p = p_data;
		  while(*p)
		    {
		      if( *p != -1 )	/* use only "good" entries */
			{
                          GetShortPathNameA( p, p_drop, 65535 );
                          p_drop += strlen( p_drop ) + 1;
			}
		      p += strlen(p) + 1;
		    }
		  *p_drop = '\0';
		  PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
		}
	    }
	}
      if( p_data ) TSXFree(p_data);  
      
    } /* WS_EX_ACCEPTFILES */

  WIN_ReleaseWndPtr(pDropWnd);
}

/**********************************************************************
 *           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 )
{
  WND           *pDropWnd;
  WND           *pWnd;
  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;
  }		u; /* unused */

  pWnd = WIN_FindWndPtr(hWnd);

  if (!(pWnd->dwExStyle & WS_EX_ACCEPTFILES))
  {
    WIN_ReleaseWndPtr(pWnd);
    return;
  }
  WIN_ReleaseWndPtr(pWnd);

  TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
			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 = 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 ) {
      TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
		       &x, &y, &u.i, &u.i, &u.i);

      pDropWnd = WIN_FindWndPtr( hWnd );
      
      drop_len += sizeof(DROPFILES) + 1;
      hDrop = GlobalAlloc( GMEM_SHARE, drop_len );
      lpDrop = (DROPFILES *) GlobalLock( hDrop );

      if( lpDrop ) {
	  lpDrop->pFiles = sizeof(DROPFILES);
	  lpDrop->pt.x = (INT)x;
	  lpDrop->pt.y = (INT)y;
	  lpDrop->fNC =
	    ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left)  ||
	      y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top)    ||
	      x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
	      y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
	  lpDrop->fWide = FALSE;
	  p_drop = (char*)(lpDrop + 1);
      }

      /* create message content */
      if (p_drop) {
	p = 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 );
      }
      WIN_ReleaseWndPtr(pDropWnd);
    }
    if( p_data ) TSXFree(p_data);  
  }
}

/**********************************************************************
 *           EVENT_ClientMessage
 */
static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event )
{
  if (event->message_type != None && event->format == 32) {
    if ((event->message_type == wmProtocols) && 
	(((Atom) event->data.l[0]) == wmDeleteWindow))
    {
        /* Ignore the delete window request if the window has been disabled */
        if (!(GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED))
            PostMessageA( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
    }
    else if (event->message_type == dndProtocol)
    {
        /* query window (drag&drop event contains only drag window) */
        Window root, child;
        int root_x, root_y, child_x, child_y;
        unsigned int u;
        TSXQueryPointer( event->display, root_window, &root, &child,
                         &root_x, &root_y, &child_x, &child_y, &u);
        if (TSXFindContext( event->display, child, winContext, (char **)&hWnd ) != 0) 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);
    }
    else {
#if 0
      /* enable this if you want to see the message */
      unsigned char* p_data = NULL;
      union {
	unsigned long	l;
	int            	i;
	Atom		atom;
      } u; /* unused */
      TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
			    dndSelection, 0, 65535, FALSE,
			    AnyPropertyType, &u.atom, &u.i,
			    &u.l, &u.l, &p_data);
      TRACE("message_type=%ld, data=%ld,%ld,%ld,%ld,%ld, msg=%s\n",
	    event->message_type, event->data.l[0], event->data.l[1], 
	    event->data.l[2], event->data.l[3], event->data.l[4],
	    p_data);
#endif
      TRACE("unrecognized ClientMessage\n" );
    }
  }
}


/***********************************************************************
 *           EVENT_MappingNotify
 */
static void EVENT_MappingNotify( XMappingEvent *event )
{
    TSXRefreshKeyboardMapping(event);

    /* reinitialize Wine-X11 driver keyboard table */
    X11DRV_InitKeyboard();
}


/**********************************************************************
 *              X11DRV_EVENT_SetInputMethod
 */
INPUT_TYPE X11DRV_EVENT_SetInputMethod(INPUT_TYPE type)
{
  INPUT_TYPE prev = current_input_type;

  /* Flag not used yet */
  in_transition = FALSE;
  current_input_type = type;

  return prev;
}

#ifdef HAVE_LIBXXF86DGA2
/**********************************************************************
 *              X11DRV_EVENT_SetDGAStatus
 */
void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base)
{
  if (event_base < 0) {
    DGAUsed = FALSE;
    DGAhwnd = 0;
  } else {
    DGAUsed = TRUE;
    DGAhwnd = hwnd;
    DGAMotionEventType = event_base + MotionNotify;
    DGAButtonPressEventType = event_base + ButtonPress;
    DGAButtonReleaseEventType = event_base + ButtonRelease;
    DGAKeyPressEventType = event_base + KeyPress;
    DGAKeyReleaseEventType = event_base + KeyRelease;
  }
}

/* DGA2 event handlers */
static void EVENT_DGAMotionEvent( XDGAMotionEvent *event )
{
  X11DRV_SendEvent( MOUSEEVENTF_MOVE, event->dx, event->dy,
                    X11DRV_EVENT_XStateToKeyState( event->state ), 0,
                    event->time - X11DRV_server_startticks, DGAhwnd );
}

static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event )
{
  static WORD statusCodes[NB_BUTTONS] = 
    { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN };
  int buttonNum = event->button - 1;
  
  WORD keystate;

  if (buttonNum >= NB_BUTTONS) return;
  
  keystate = X11DRV_EVENT_XStateToKeyState( event->state );
  
  switch (buttonNum)
  {
    case 0:
      keystate |= MK_LBUTTON;
      break;
    case 1:
      keystate |= MK_MBUTTON;
      break;
    case 2:
      keystate |= MK_RBUTTON;
      break;
  }
  
  X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, 0,
                    event->time - X11DRV_server_startticks, DGAhwnd );
}

static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event )
{
  static WORD statusCodes[NB_BUTTONS] = 
    { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTUP };
  int buttonNum = event->button - 1;
  
  WORD keystate;

  if (buttonNum >= NB_BUTTONS) return;
  
  keystate = X11DRV_EVENT_XStateToKeyState( event->state );
  
  switch (buttonNum)
  {
    case 0:
      keystate &= ~MK_LBUTTON;
      break;
    case 1:
      keystate &= ~MK_MBUTTON;
      break;
    case 2:
      keystate &= ~MK_RBUTTON;
      break;
  }
  
  X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, 0,
                    event->time - X11DRV_server_startticks, DGAhwnd );
}

#endif
