/*
 * X11 windows driver
 *
 * Copyright 1993, 1994, 1995, 1996 Alexandre Julliard
 *                             1993 David Metcalfe
 *                       1995, 1996 Alex Korobka
 */

#include "config.h"

#ifndef X_DISPLAY_MISSING

#include <X11/Xatom.h>
#include "ts_xlib.h"
#include "ts_xutil.h"

#include <stdlib.h>
#include <string.h>
#include "bitmap.h"
#include "color.h"
#include "debug.h"
#include "display.h"
#include "dce.h"
#include "options.h"
#include "message.h"
#include "heap.h"
#include "win.h"
#include "windef.h"
#include "class.h"
#include "x11drv.h"
#include "wine/winuser16.h"

DEFAULT_DEBUG_CHANNEL(win)

/**********************************************************************/

extern Cursor X11DRV_MOUSE_XCursor;  /* Current X cursor */
extern BOOL   X11DRV_CreateBitmap( HBITMAP );
extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );

/**********************************************************************/

/* X context to associate a hwnd to an X window */
XContext winContext = 0;

Atom wmProtocols = None;
Atom wmDeleteWindow = None;
Atom dndProtocol = None;
Atom dndSelection = None;
Atom wmChangeState = None;

/***********************************************************************
 *		X11DRV_WND_GetXWindow
 *
 * Return the X window associated to a window.
 */
Window X11DRV_WND_GetXWindow(WND *wndPtr)
{
    return wndPtr && wndPtr->pDriverData ? 
      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
}

/***********************************************************************
 *		X11DRV_WND_FindXWindow
 *
 * Return the the first X window associated to a window chain.
 */
Window X11DRV_WND_FindXWindow(WND *wndPtr)
{
    while (wndPtr && 
	   !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) 
      wndPtr = wndPtr->parent;
    return wndPtr ?
      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
}

/***********************************************************************
 *              X11DRV_WND_GetXScreen
 *
 * Return the X screen associated to the window.
 */
Screen *X11DRV_WND_GetXScreen(WND *wndPtr)
{
  while(wndPtr->parent) wndPtr = wndPtr->parent;
  return X11DRV_DESKTOP_GetXScreen((struct tagDESKTOP *) wndPtr->wExtra);
}

/***********************************************************************
 *              X11DRV_WND_GetXRootWindow
 *
 * Return the X display associated to the window.
 */
Window X11DRV_WND_GetXRootWindow(WND *wndPtr)
{
  while(wndPtr->parent) wndPtr = wndPtr->parent;
  return X11DRV_DESKTOP_GetXRootWindow((struct tagDESKTOP *) wndPtr->wExtra);
}

/***********************************************************************
 *		X11DRV_WND_RegisterWindow
 *
 * Associate an X window to a HWND.
 */
static void X11DRV_WND_RegisterWindow(WND *wndPtr)
{
  TSXSetWMProtocols( display, X11DRV_WND_GetXWindow(wndPtr), &wmDeleteWindow, 1 );
  
  if (!winContext) winContext = TSXUniqueContext();
  TSXSaveContext( display, X11DRV_WND_GetXWindow(wndPtr), winContext, (char *) wndPtr );
}

/**********************************************************************
 *		X11DRV_WND_Initialize
 */
void X11DRV_WND_Initialize(WND *wndPtr)
{
  X11DRV_WND_DATA *pWndDriverData = 
    (X11DRV_WND_DATA *) HeapAlloc(SystemHeap, 0, sizeof(X11DRV_WND_DATA));

  wndPtr->pDriverData = (void *) pWndDriverData;

  pWndDriverData->window = 0;
}

/**********************************************************************
 *		X11DRV_WND_Finalize
 */
void X11DRV_WND_Finalize(WND *wndPtr)
{
  X11DRV_WND_DATA *pWndDriverData =
    (X11DRV_WND_DATA *) wndPtr->pDriverData;

  if (!wndPtr->pDriverData) {
     ERR(win,"Trying to destroy window again. Not good.\n");
     return;
  }
  if(pWndDriverData->window)
    {
      ERR(win, 
	  "WND destroyed without destroying "
	  "the associated X Window (%ld)\n", 
	  pWndDriverData->window
      );
    }
  HeapFree(SystemHeap, 0, wndPtr->pDriverData);
  wndPtr->pDriverData = NULL;
}

/**********************************************************************
 *		X11DRV_WND_CreateDesktopWindow
 */
BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode)
{
    if (wmProtocols == None)
        wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
    if (wmDeleteWindow == None)
        wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
    if( dndProtocol == None )
	dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
    if( dndSelection == None )
	dndSelection = TSXInternAtom( display, "DndSelection" , False );
    if( wmChangeState == None )
        wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);

    ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = 
      X11DRV_WND_GetXRootWindow( wndPtr );
    X11DRV_WND_RegisterWindow( wndPtr );

    return TRUE;
}


/**********************************************************************
 *		X11DRV_WND_CreateWindow
 */
BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BOOL bUnicode)
{
  /* Create the X window (only for top-level windows, and then only */
  /* when there's no desktop window) */
  
  if (!(cs->style & WS_CHILD) && 
      (X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display)))
  {
      Window    wGroupLeader;
      XWMHints* wm_hints;
      XSetWindowAttributes win_attr;
      
      /* Create "managed" windows only if a title bar or resizable */
      /* frame is required. */
      if (Options.managed && ( ((cs->style & WS_CAPTION) == WS_CAPTION) ||
                              (cs->style & WS_THICKFRAME) ||
			      (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
        {
	  win_attr.event_mask = ExposureMask | KeyPressMask |
	    KeyReleaseMask | PointerMotionMask |
	    ButtonPressMask | ButtonReleaseMask |
	    FocusChangeMask | StructureNotifyMask;
	  win_attr.override_redirect = FALSE;
	  wndPtr->flags |= WIN_MANAGED;
	}
      else
        {
	  win_attr.event_mask = ExposureMask | KeyPressMask |
	    KeyReleaseMask | PointerMotionMask |
	    ButtonPressMask | ButtonReleaseMask |
	    FocusChangeMask;
	  win_attr.override_redirect = TRUE;
	}
      wndPtr->flags |= WIN_NATIVE;

      win_attr.bit_gravity   = (classPtr->style & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest;
      win_attr.colormap      = X11DRV_PALETTE_PaletteXColormap;
      win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
      win_attr.save_under    = ((classPtr->style & CS_SAVEBITS) != 0);
      win_attr.cursor        = X11DRV_MOUSE_XCursor;

      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = win_attr.bit_gravity;
      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = 
	TSXCreateWindow( display, 
			 X11DRV_WND_GetXRootWindow(wndPtr), 
			 cs->x, cs->y, cs->cx, cs->cy, 
			 0, CopyFromParent, 
			 InputOutput, CopyFromParent,
			 CWEventMask | CWOverrideRedirect |
			 CWColormap | CWCursor | CWSaveUnder |
			 CWBackingStore | CWBitGravity, 
			 &win_attr );
      
      if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
	return FALSE;

      if (wndPtr->flags & WIN_MANAGED) 
      {
	  XClassHint *class_hints = TSXAllocClassHint();

	  if (class_hints) 
	  {
	      class_hints->res_name = "wineManaged";
	      class_hints->res_class = "Wine";
	      TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
	      TSXFree (class_hints);
	  }

	  if (cs->dwExStyle & WS_EX_DLGMODALFRAME) 
	  {
	      XSizeHints* size_hints = TSXAllocSizeHints();
	  
	      if (size_hints) 
	      {
	          size_hints->min_width = size_hints->max_width = cs->cx;
	          size_hints->min_height = size_hints->max_height = cs->cy;
                  size_hints->flags = (PSize | PMinSize | PMaxSize);
                  TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), 
					size_hints, XA_WM_NORMAL_HINTS );
                  TSXFree(size_hints);
              }
          }
      }
      
      if (cs->hwndParent)  /* Get window owner */
      {
	  Window w;
          WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);

	  w = X11DRV_WND_FindXWindow( tmpWnd );
	  if (w != None)
	  {
	      TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
	      wGroupLeader = w;
	  }
          WIN_ReleaseWndPtr(tmpWnd);
      }

      wm_hints = TSXAllocWMHints();
      {
	  wm_hints->flags = InputHint | StateHint | WindowGroupHint;
	  wm_hints->input = True;

	  if( wndPtr->flags & WIN_MANAGED )
	  {
	      if( wndPtr->class->hIcon )
	      { 
		  CURSORICONINFO *ptr;

		  if( (ptr = (CURSORICONINFO *)GlobalLock16( wndPtr->class->hIcon )) )
		  {
		      /* This is not entirely correct, may need to create
		       * an icon window and set the pixmap as a background */

		      HBITMAP hBitmap = CreateBitmap( ptr->nWidth, ptr->nHeight, 
		   	  ptr->bPlanes, ptr->bBitsPerPixel, (char *)(ptr + 1) +
                          ptr->nHeight * BITMAP_GetWidthBytes(ptr->nWidth,1) );

		      if( hBitmap )
		      {
			((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = hBitmap;
			  X11DRV_CreateBitmap( hBitmap );
			  wm_hints->flags |= IconPixmapHint;
			  wm_hints->icon_pixmap = X11DRV_BITMAP_Pixmap( hBitmap );
		      }
		   }
	      }
	      wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE) 
					? IconicState : NormalState;
	  }
	  else
	      wm_hints->initial_state = NormalState;
	  wm_hints->window_group = wGroupLeader;

	  TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
	  TSXFree(wm_hints);
      }
      X11DRV_WND_RegisterWindow( wndPtr );
  }
  return TRUE;
}

/***********************************************************************
 *		X11DRV_WND_DestroyWindow
 */
BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
{
   Window w;
   if ((w = X11DRV_WND_GetXWindow(wndPtr)))
   {
       XEvent xe;
       TSXDeleteContext( display, w, winContext );
       TSXDestroyWindow( display, w );
       while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );

       ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
       if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
       {
	   DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
	   ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
       }
   }

   return TRUE;
}

/*****************************************************************
 *		X11DRV_WND_SetParent
 */
WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
{
    WND *pDesktop = WIN_GetDesktop();
    
    if( wndPtr && pWndParent && (wndPtr != pDesktop) )
    {
	WND* pWndPrev = wndPtr->parent;

	if( pWndParent != pWndPrev )
	{
	    if ( X11DRV_WND_GetXWindow(wndPtr) )
	    {
		/* Toplevel window needs to be reparented.  Used by Tk 8.0 */

		TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
		((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
	    }

	    WIN_UnlinkWindow(wndPtr->hwndSelf);
	    wndPtr->parent = pWndParent;

            /* Create an X counterpart for reparented top-level windows
	     * when not in the desktop mode. */

            if( pWndParent == pDesktop )
            {
                wndPtr->dwStyle &= ~WS_CHILD;
                wndPtr->wIDmenu = 0;
                if( X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display) )
                {
                    CREATESTRUCTA cs;
                    cs.lpCreateParams = NULL;
                    cs.hInstance = 0; /* not used if following call */
                    cs.hMenu = 0; /* not used in following call */
                    cs.hwndParent = pWndParent->hwndSelf;
                    cs.cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
                    if (!cs.cy)
                      cs.cy = 1;
                    cs.cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
                    if (!cs.cx)
                      cs.cx = 1;
                    cs.y = wndPtr->rectWindow.top;
                    cs.x = wndPtr->rectWindow.left;
                    cs.style = wndPtr->dwStyle;
                    cs.lpszName = 0; /* not used in following call */
                    cs.lpszClass = 0; /*not used in following call */
                    cs.dwExStyle = wndPtr->dwExStyle;
                    X11DRV_WND_CreateWindow(wndPtr, wndPtr->class,
                                            &cs, FALSE);
                }
            }
            else /* a child window */
            {
                if( !( wndPtr->dwStyle & WS_CHILD ) )
                {
                    wndPtr->dwStyle |= WS_CHILD;
                    if( wndPtr->wIDmenu != 0)
                    {
                        DestroyMenu( (HMENU) wndPtr->wIDmenu );
                        wndPtr->wIDmenu = 0;
                    }
                }
            }
	    WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
	}
        WIN_ReleaseDesktop();
	return pWndPrev;
    } /* failure */
    WIN_ReleaseDesktop();
    return 0;
}

/***********************************************************************
 *		X11DRV_WND_ForceWindowRaise
 *
 * Raise a window on top of the X stacking order, while preserving 
 * the correct Windows Z order.
 */
void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
{
  XWindowChanges winChanges;
  WND *wndPrev,*pDesktop = WIN_GetDesktop();
  
  if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->flags & WIN_MANAGED) )
  {
      WIN_ReleaseDesktop();
    return;
  }
  
  /* Raise all windows up to wndPtr according to their Z order.
   * (it would be easier with sibling-related Below but it doesn't
   * work very well with SGI mwm for instance)
   */
  winChanges.stack_mode = Above;
  while (wndPtr)
    {
      if (X11DRV_WND_GetXWindow(wndPtr)) 
	TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(wndPtr), 0,
				CWStackMode, &winChanges );
      wndPrev = pDesktop->child;
      if (wndPrev == wndPtr) break;
      while (wndPrev && (wndPrev->next != wndPtr)) wndPrev = wndPrev->next;
      wndPtr = wndPrev;
    }
  WIN_ReleaseDesktop();
}

/***********************************************************************
 *		X11DRV_WND_FindDesktopXWindow	[Internal]
 *
 * Find the actual X window which needs be restacked.
 * Used by X11DRV_SetWindowPos().
 */
static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
{
  if (!(wndPtr->flags & WIN_MANAGED))
    return X11DRV_WND_GetXWindow(wndPtr);
  else
    {
      Window window, root, parent, *children;
      int nchildren;
      window = X11DRV_WND_GetXWindow(wndPtr);
      for (;;)
        {
	  TSXQueryTree( display, window, &root, &parent,
                        &children, &nchildren );
	  TSXFree( children );
	  if (parent == root)
	    return window;
	  window = parent;
        }
    }
}

/***********************************************************************
 *           WINPOS_SetXWindowPos
 *
 * SetWindowPos() for an X window. Used by the real SetWindowPos().
 */
void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos)
{
    XWindowChanges winChanges;
    int changeMask = 0;
    WND *winposPtr = WIN_FindWndPtr( winpos->hwnd );

    if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happend!!! */
  
    if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
    {
      if(X11DRV_WND_GetXWindow(wndPtr)) 
	TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
    }

    if(bChangePos)
    {
	if ( !(winpos->flags & SWP_NOSIZE))
	{
	  winChanges.width     = (winpos->cx > 0 ) ? winpos->cx : 1;
	  winChanges.height    = (winpos->cy > 0 ) ? winpos->cy : 1;
	  changeMask |= CWWidth | CWHeight;
	  
	  /* Tweak dialog window size hints */
	  
	  if ((winposPtr->flags & WIN_MANAGED) &&
	      (winposPtr->dwExStyle & WS_EX_DLGMODALFRAME))
	    {
	      XSizeHints *size_hints = TSXAllocSizeHints();
	      
	      if (size_hints)
		{
		  long supplied_return;
		  
		  TSXGetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
				     &supplied_return, XA_WM_NORMAL_HINTS);
		  size_hints->min_width = size_hints->max_width = winpos->cx;
		  size_hints->min_height = size_hints->max_height = winpos->cy;
		  TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
				     XA_WM_NORMAL_HINTS );
		  TSXFree(size_hints);
		}
	    }
	}
	if (!(winpos->flags & SWP_NOMOVE))
	{
	  winChanges.x = winpos->x;
	  winChanges.y = winpos->y;
	  changeMask |= CWX | CWY;
	}
	if (!(winpos->flags & SWP_NOZORDER))
	{
	  winChanges.stack_mode = Below;
	  changeMask |= CWStackMode;
	  
	  if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
	  else if (winpos->hwndInsertAfter != HWND_BOTTOM)
	    {
	      WND*   insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
	      Window stack[2];
	      
	      stack[0] = X11DRV_WND_FindDesktopXWindow( insertPtr );
	      stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
	      
	      /* for stupid window managers (i.e. all of them) */
	      
	      TSXRestackWindows(display, stack, 2); 
	      changeMask &= ~CWStackMode;
              
              WIN_ReleaseWndPtr(insertPtr);
	    }
	}
	if (changeMask)
	{
	    TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
	    if( winposPtr->class->style & (CS_VREDRAW | CS_HREDRAW) )
		X11DRV_WND_SetHostAttr( winposPtr, HAK_BITGRAVITY, BGForget );
	}
    }

    if ( winpos->flags & SWP_SHOWWINDOW )
    {
	if(X11DRV_WND_GetXWindow(wndPtr)) 
	   TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
    }
    WIN_ReleaseWndPtr(winposPtr);
}

/*****************************************************************
 *		X11DRV_WND_SetText
 */
void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text)
{   
  if (!X11DRV_WND_GetXWindow(wndPtr))
    return;

  TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text );
  TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text );
}

/*****************************************************************
 *		X11DRV_WND_SetFocus
 *
 * Set the X focus.
 * Explicit colormap management seems to work only with OLVWM.
 */
void X11DRV_WND_SetFocus(WND *wndPtr)
{
  HWND hwnd =  wndPtr->hwndSelf;
  XWindowAttributes win_attr;
  Window win;
  
  /* Only mess with the X focus if there's */
  /* no desktop window and no window manager. */
  if ((X11DRV_WND_GetXRootWindow(wndPtr) != DefaultRootWindow(display))
      || Options.managed) return;
  
  if (!hwnd)	/* If setting the focus to 0, uninstall the colormap */
    {
      if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
	TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
      return;
    }
  
  /* Set X focus and install colormap */
  
  if (!(win = X11DRV_WND_FindXWindow(wndPtr))) return;
  if (!TSXGetWindowAttributes( display, win, &win_attr ) ||
      (win_attr.map_state != IsViewable))
    return;  /* If window is not viewable, don't change anything */
  
  TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
  if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
    TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
  
  EVENT_Synchronize();
}

/*****************************************************************
 *		X11DRV_WND_PreSizeMove
 */
void X11DRV_WND_PreSizeMove(WND *wndPtr)
{
  if (!(wndPtr->dwStyle & WS_CHILD) && 
      (X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display)))
    TSXGrabServer( display );
}

/*****************************************************************
 *		 X11DRV_WND_PostSizeMove
 */
void X11DRV_WND_PostSizeMove(WND *wndPtr)
{
  if (!(wndPtr->dwStyle & WS_CHILD) && 
      (X11DRV_GetXRootWindow() == DefaultRootWindow(display)))
    TSXUngrabServer( display );
}

/*****************************************************************
 *		 X11DRV_WND_SurfaceCopy
 *
 * Copies rect to (rect.left + dx, rect.top + dy). 
 */
void X11DRV_WND_SurfaceCopy(WND* wndPtr, DC *dcPtr, INT dx, INT dy, 
			    const RECT *rect, BOOL bUpdate)
{
    X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
    POINT dst, src;
  
    dst.x = (src.x = dcPtr->w.DCOrgX + rect->left) + dx;
    dst.y = (src.y = dcPtr->w.DCOrgY + rect->top) + dy;
  
    if (bUpdate) /* handles non-Wine windows hanging over the copied area */
	TSXSetGraphicsExposures( display, physDev->gc, True );
    TSXSetFunction( display, physDev->gc, GXcopy );
    TSXCopyArea( display, physDev->drawable, physDev->drawable,
                 physDev->gc, src.x, src.y,
                 rect->right - rect->left,
                 rect->bottom - rect->top,
                 dst.x, dst.y );
    if (bUpdate)
	TSXSetGraphicsExposures( display, physDev->gc, False );

    if (bUpdate) /* Make sure exposure events have been processed */
	EVENT_Synchronize();
}

/***********************************************************************
 *		X11DRV_WND_SetDrawable
 *
 * Set the drawable, origin and dimensions for the DC associated to
 * a given window.
 */
void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin)
{
    X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;

    if (!wndPtr)  /* Get a DC for the whole screen */
    {
        dc->w.DCOrgX = 0;
        dc->w.DCOrgY = 0;
        physDev->drawable = X11DRV_WND_GetXRootWindow(wndPtr);
        TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors );
    }
    else
    {
        if (flags & DCX_WINDOW)
        {
            dc->w.DCOrgX  = wndPtr->rectWindow.left;
            dc->w.DCOrgY  = wndPtr->rectWindow.top;
        }
        else
        {
            dc->w.DCOrgX  = wndPtr->rectClient.left;
            dc->w.DCOrgY  = wndPtr->rectClient.top;
        }
        while (!X11DRV_WND_GetXWindow(wndPtr))
        {
            wndPtr = wndPtr->parent;
            dc->w.DCOrgX += wndPtr->rectClient.left;
            dc->w.DCOrgY += wndPtr->rectClient.top;
        }
        dc->w.DCOrgX -= wndPtr->rectWindow.left;
        dc->w.DCOrgY -= wndPtr->rectWindow.top;
        physDev->drawable = X11DRV_WND_GetXWindow(wndPtr);

#if 0
	/* This is needed when we reuse a cached DC because
	 * SetDCState() called by ReleaseDC() screws up DC
	 * origins for child windows.
	 */

	if( bSetClipOrigin )
	    TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY );
#endif
    }
}

/***********************************************************************
 *              X11DRV_SetWMHint
 */
static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
{
    XWMHints* wm_hints = TSXAllocWMHints();
    {
        wm_hints->flags = hint;
	switch( hint )
	{
	    case InputHint:
		 wm_hints->input = val;
		 break;

	    case StateHint:
		 wm_hints->initial_state = val;
		 break;

	    case IconPixmapHint:
		 wm_hints->icon_pixmap = (Pixmap)val;
		 break;

	    case IconWindowHint:
		 wm_hints->icon_window = (Window)val;
		 break;
	}

        TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
        TSXFree(wm_hints);
        return TRUE;
    }
    return FALSE;
}


/***********************************************************************
 *              X11DRV_WND_SetHostAttr
 *
 * This function returns TRUE if the attribute is supported and the
 * action was successful. Otherwise it should return FALSE and Wine will try 
 * to get by without the functionality provided by the host window system.
 */
BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
{
    Window w;

    if( (w = X11DRV_WND_GetXWindow(wnd)) )
    {
	XSetWindowAttributes win_attr;

	switch( ha )
	{
	case HAK_ICONICSTATE: /* called when a window is minimized/restored */

		    if( (wnd->flags & WIN_MANAGED) )
		    {
			if( value )
			{
			    if( wnd->dwStyle & WS_VISIBLE )
			    {
				XClientMessageEvent ev;

				/* FIXME: set proper icon */

				ev.type = ClientMessage;
				ev.display = display;
				ev.message_type = wmChangeState;
				ev.format = 32;
				ev.data.l[0] = IconicState;
				ev.window = w;

				if( TSXSendEvent (display,
		RootWindow( display, XScreenNumberOfScreen(X11DRV_WND_GetXScreen(wnd)) ), 
		True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
				{
				    XEvent xe;
				    TSXFlush (display);
				    while( !TSXCheckTypedWindowEvent( display, w, UnmapNotify, &xe) );
				}
				else 
				    break;
			    }
			    else
				X11DRV_SetWMHint( display, wnd, StateHint, IconicState );
			}
			else
			{
			    if( !(wnd->flags & WS_VISIBLE) )
				X11DRV_SetWMHint( display, wnd, StateHint, NormalState );
			    else
			    {
				XEvent xe;
				XMapWindow(display, w );
				while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
			    }
			}
			return TRUE;
		    }
		    break;

	case HAK_BITGRAVITY: /* called when a window is resized */

		    if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value )
		    {
		        win_attr.bit_gravity = value;
		        ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value;
		        TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr );
		    }
		   return TRUE;

	case HAK_ACCEPTFOCUS: /* called when a window is disabled/enabled */

		if( (wnd->flags & WIN_MANAGED) )
		    return X11DRV_SetWMHint( display, wnd, InputHint, value );
	}
    }
    return FALSE;
}

/***********************************************************************
 *		X11DRV_WND_IsSelfClipping
 */
BOOL X11DRV_WND_IsSelfClipping(WND *wndPtr)
{
  return X11DRV_WND_GetXWindow(wndPtr) != None;
}

#endif /* !defined(X_DISPLAY_MISSING) */
