/*
 * DirectDraw driver interface
 *
 * Copyright 2001 TransGaming Technologies, Inc.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <string.h>

#include "ts_xlib.h"
#include "x11drv.h"
#include "x11ddraw.h"
#include "xvidmode.h"
#include "dga2.h"

#include "windef.h"
#include "wingdi.h"
#include "ddrawi.h"
#include "bitmap.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(x11drv);

extern int dxgrab;

LPDDRAWI_DDRAWSURFACE_LCL X11DRV_DD_Primary;
LPDDRAWI_DDRAWSURFACE_GBL X11DRV_DD_PrimaryGbl;
HWND X11DRV_DD_PrimaryWnd;
HBITMAP X11DRV_DD_PrimaryDIB;
Drawable X11DRV_DD_PrimaryDrawable;
ATOM X11DRV_DD_UserClass;
BOOL X11DRV_DD_IsDirect;
static UINT X11DRV_DD_GrabMessage;
static WNDPROC X11DRV_DD_GrabOldProcedure;

static void SetPrimaryDIB(HBITMAP hBmp)
{
  X11DRV_DD_PrimaryDIB = hBmp;
  if (hBmp) {
    BITMAPOBJ *bmp;
    bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
    X11DRV_DD_PrimaryDrawable = (Pixmap)bmp->physBitmap;
    GDI_ReleaseObj( hBmp );
  } else {
    X11DRV_DD_PrimaryDrawable = 0;
  }
}

static LRESULT WINAPI GrabWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
  Display *display = thread_display();

  if(message != X11DRV_DD_GrabMessage)
    return CallWindowProcA(X11DRV_DD_GrabOldProcedure, hWnd, message, wParam, lParam);
 
  TRACE("hwnd=%d, grab=%d\n", hWnd, wParam);

  if (wParam) 
  {  
    /* find the X11 window that ddraw uses */  
    Window win = X11DRV_get_whole_window(hWnd);  
    TRACE("X11 window: %ld\n", win);  
    if (!win) {  
      TRACE("host off desktop\n");  
      win = root_window;  
    }  

    TSXGrabPointer(display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);  
  }  
  else 
  {
    TSXUngrabPointer(display, CurrentTime);  
  } 

  return 0; 
} 

static void GrabPointer(BOOL grab)
{
  if(grab) { 
    Window window = X11DRV_get_whole_window(GetFocus()); 
    if(window)
      XSetInputFocus(thread_display(), window, RevertToParent, CurrentTime); 
  } 

  if(!X11DRV_DD_GrabMessage)
    X11DRV_DD_GrabMessage = RegisterWindowMessageA("WINE_X11DRV_GRABPOINTER");

  /* FIXME: Replace with SetWindowLongPtrA when available */
  X11DRV_DD_GrabOldProcedure = (WNDPROC)SetWindowLongA(X11DRV_DD_PrimaryWnd,
                                                       GWL_WNDPROC, (LONG)GrabWndProc);

  SendMessageA(X11DRV_DD_PrimaryWnd, X11DRV_DD_GrabMessage, grab ? 1 : 0, 0);

  /* FIXME: Replace with SetWindowLongPtrA when available */
  if(SetWindowLongA(X11DRV_DD_PrimaryWnd, GWL_WNDPROC,
                    (LONG)X11DRV_DD_GrabOldProcedure) != (LONG)GrabWndProc)
    ERR("Window procedure has been changed!\n");
}

static DWORD PASCAL X11DRV_DDHAL_DestroyDriver(LPDDHAL_DESTROYDRIVERDATA data)
{
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_HANDLED;
}

static DWORD PASCAL X11DRV_DDHAL_CreateSurface(LPDDHAL_CREATESURFACEDATA data)
{
  if (data->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) {
    X11DRV_DD_Primary = *data->lplpSList;
    X11DRV_DD_PrimaryWnd = (HWND)X11DRV_DD_Primary->lpSurfMore->lpDDRAWReserved;
    X11DRV_DD_PrimaryGbl = X11DRV_DD_Primary->lpGbl;
    SetPrimaryDIB(GET_LPDDRAWSURFACE_GBL_MORE(X11DRV_DD_PrimaryGbl)->hKernelSurface);
    X11DRV_DD_UserClass = GlobalFindAtomA("WINE_DDRAW");
    if (dxgrab) GrabPointer(TRUE);
  }
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_NOTHANDLED;
}

static DWORD PASCAL X11DRV_DDHAL_CreatePalette(LPDDHAL_CREATEPALETTEDATA data)
{
  FIXME("stub\n");
  /* only makes sense to do anything if the X server is running at 8bpp,
   * which few people do nowadays */
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_HANDLED;
}

static DDHAL_DDCALLBACKS hal_ddcallbacks = {
  sizeof(DDHAL_DDCALLBACKS),
  0x3ff, /* all callbacks are 32-bit */
  X11DRV_DDHAL_DestroyDriver,
  X11DRV_DDHAL_CreateSurface,
  NULL, /* SetColorKey */
  NULL, /* SetMode */
  NULL, /* WaitForVerticalBlank */
  NULL, /* CanCreateSurface */
  X11DRV_DDHAL_CreatePalette,
  NULL, /* GetScanLine */
  NULL, /* SetExclusiveMode */
  NULL  /* FlipToGDISurface */
};

static DWORD PASCAL X11DRV_DDHAL_DestroySurface(LPDDHAL_DESTROYSURFACEDATA data)
{
  if (data->lpDDSurface == X11DRV_DD_Primary) {
    if (dxgrab) GrabPointer(FALSE);
    X11DRV_DD_Primary = NULL;
    X11DRV_DD_PrimaryWnd = 0;
    X11DRV_DD_PrimaryGbl = NULL;
    SetPrimaryDIB(0);
    X11DRV_DD_UserClass = 0;
  }
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_HANDLED;
}

static DWORD PASCAL X11DRV_DDHAL_SetPalette(LPDDHAL_SETPALETTEDATA data)
{
  if (data->lpDDPalette && data->lpDDPalette->u1.dwReserved1) {
    if (data->lpDDSurface == X11DRV_DD_Primary) {
      FIXME("stub\n");
      /* we should probably find the ddraw window (maybe data->lpDD->lpExclusiveOwner->hWnd),
       * and attach the palette to it
       *
       * Colormap pal = data->lpDDPalette->u1.dwReserved1;
       */
    }
  }
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_HANDLED;
}

static DDHAL_DDSURFACECALLBACKS hal_ddsurfcallbacks = {
  sizeof(DDHAL_DDSURFACECALLBACKS),
  0x3fff, /* all callbacks are 32-bit */
  X11DRV_DDHAL_DestroySurface,
  NULL, /* Flip */
  NULL, /* SetClipList */
  NULL, /* Lock */
  NULL, /* Unlock */
  NULL, /* Blt */
  NULL, /* SetColorKey */
  NULL, /* AddAttachedSurface */
  NULL, /* GetBltStatus */
  NULL, /* GetFlipStatus */
  NULL, /* UpdateOverlay */
  NULL, /* SetOverlayPosition */
  NULL, /* reserved4 */
  X11DRV_DDHAL_SetPalette
};

static DWORD PASCAL X11DRV_DDHAL_DestroyPalette(LPDDHAL_DESTROYPALETTEDATA data)
{
  Colormap pal = data->lpDDPalette->u1.dwReserved1;
  if (pal) TSXFreeColormap(gdi_display, pal);
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_HANDLED;
}

static DWORD PASCAL X11DRV_DDHAL_SetPaletteEntries(LPDDHAL_SETENTRIESDATA data)
{
  X11DRV_DDHAL_SetPalEntries(data->lpDDPalette->u1.dwReserved1,
			     data->dwBase, data->dwNumEntries,
			     data->lpEntries);
  data->ddRVal = DD_OK;
  return DDHAL_DRIVER_HANDLED;
}

static DDHAL_DDPALETTECALLBACKS hal_ddpalcallbacks = {
  sizeof(DDHAL_DDPALETTECALLBACKS),
  0x3, /* all callbacks are 32-bit */
  X11DRV_DDHAL_DestroyPalette,
  X11DRV_DDHAL_SetPaletteEntries
};

static X11DEVICE x11device = {
  NULL
};

static DWORD PASCAL X11DRV_DDHAL_GetDriverInfo(LPDDHAL_GETDRIVERINFODATA data)
{
  LPX11DRIVERINFO info = x11device.lpInfo;
  while (info) {
    if (IsEqualGUID(&data->guidInfo, info->lpGuid)) {
      DWORD dwSize = info->dwSize;
      data->dwActualSize = dwSize;
      if (data->dwExpectedSize < dwSize) dwSize = data->dwExpectedSize;
      memcpy(data->lpvData, info->lpvData, dwSize);
      data->ddRVal = DD_OK;
      return DDHAL_DRIVER_HANDLED;
    }
    info = info->lpNext;
  }
  data->ddRVal = DDERR_CURRENTLYNOTAVAIL;
  return DDHAL_DRIVER_HANDLED;
}

static DDHALINFO hal_info = {
  sizeof(DDHALINFO),
  &hal_ddcallbacks,
  &hal_ddsurfcallbacks,
  &hal_ddpalcallbacks,
  {	/* vmiData */
   0	 /* fpPrimary */
  },
  {	/* ddCaps (only stuff the HAL implements here) */
   sizeof(DDCORECAPS),							/* dwSize */
   DDCAPS_GDI | DDCAPS_PALETTE,						/* dwCaps */
   DDCAPS2_CERTIFIED | DDCAPS2_NONLOCALVIDMEM | DDCAPS2_NOPAGELOCKREQUIRED |
   DDCAPS2_WIDESURFACES | DDCAPS2_PRIMARYGAMMA | DDCAPS2_FLIPNOVSYNC,   /* dwCaps2 */
   0,									/* dwCKeyCaps */
   0,									/* dwFXCaps */
   0,									/* dwFXAlphaCaps */
   DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE,				/* dwPalCaps */
   0,									/* dwSVCaps */
   0,									/* dwAlphaBltConstBitDepths */
   0,									/* dwAlphaBltPixelBitDepths */
   0,									/* dwAlphaBltSurfaceBitDepths */
   0,									/* dwAlphaOverlayBltConstBitDepths */
   0,									/* dwAlphaOverlayBltPixelBitDepths */
   0,									/* dwAlphaOverlayBltSurfaceBitDepths */
   0,									/* dwZBufferBitDepths */
   16*1024*1024,							/* dwVidMemTotal */
   16*1024*1024,							/* dwVidMemFree */
   0,									/* dwMaxVisibleOverlays */
   0,									/* dwCurrVisibleOverlays */
   0,									/* dwNumFourCCCodes */
   0,									/* dwAlignBoundarySrc */
   0,									/* dwAlignSizeSrc */
   0,									/* dwAlignBoundaryDest */
   0,									/* dwAlignSizeDest */
   0,									/* dwAlignStrideAlign */
   {0},									/* dwRops */
   {									/* ddsCaps */
    DDSCAPS_BACKBUFFER | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER |
    DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE |
    DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY |
    DDSCAPS_VISIBLE | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM	/* dwCaps */
   },
   0,									/* dwMinOverlayStretch */
   0,									/* dwMaxOverlayStretch */
   0,									/* dwMinLiveVideoStretch */
   0,									/* dwMaxLiveVideoStretch */
   0,									/* dwMinHwCodecStretch */
   0,									/* dwMaxHwCodecStretch */
   0,									/* dwReserved1 */
   0,									/* dwReserved2 */
   0,									/* dwReserved2 */
   0,									/* dwSVBCaps */
   0,									/* dwSVBCKeyCaps */
   0,									/* dwSVBFXCaps */
   {0},									/* dwSVBRops */
   0,									/* dwVSBCaps */
   0,									/* dwVSBCKeyCaps */
   0,									/* dwVSBFXCaps */
   {0},									/* dwVSBRops */
   0,									/* dwSSBCaps */
   0,									/* dwSSBCKeyCaps */
   0,									/* dwSSBFXCaps */
   {0},									/* dwSSBRops */
   0,									/* dwMaxVideoPorts */
   0,									/* dwCurrVideoPorts */
   0									/* dwSVBCaps */
  },
  0,	/* dwMonitorFrequency */
  X11DRV_DDHAL_GetDriverInfo,
  0,	/* dwModeIndex */
  NULL,	/* lpdwFourCC */
  0,	/* dwNumModes */
  NULL,	/* lpModeInfo */
  DDHALINFO_ISPRIMARYDISPLAY | DDHALINFO_MODEXILLEGAL | DDHALINFO_GETDRIVERINFOSET, /* dwFlags */
  &x11device,
  0,	/* hInstance */
  0,	/* lpD3DGlobalDriverData */
  0,	/* lpD3DHALCallbacks */
  NULL	/* lpDDExeBufCallbacks */
};

static LPDDHALDDRAWFNS ddraw_fns;
static DWORD ddraw_ver;

static void X11DRV_DDHAL_SetInfo(void)
{
  (ddraw_fns->lpSetInfo)(&hal_info, FALSE);
}

INT X11DRV_DCICommand(INT cbInput, const DCICMD *lpCmd, LPVOID lpOutData)
{
  TRACE("(%d,(%ld,%ld,%ld),%p)\n", cbInput, lpCmd->dwCommand,
	lpCmd->dwParam1, lpCmd->dwParam2, lpOutData);

  switch (lpCmd->dwCommand) {
  case DDNEWCALLBACKFNS:
    ddraw_fns = (LPDDHALDDRAWFNS)lpCmd->dwParam1;
    return TRUE;
  case DDVERSIONINFO:
    {
      LPDDVERSIONDATA lpVer = (LPDDVERSIONDATA)lpOutData;
      ddraw_ver = lpCmd->dwParam1;
      if (!lpVer) break;
      /* well, whatever... the DDK says so */
      lpVer->dwHALVersion = DD_RUNTIME_VERSION;
    }
    return TRUE;
  case DDGET32BITDRIVERNAME:
    {
      LPDD32BITDRIVERDATA lpData = (LPDD32BITDRIVERDATA)lpOutData;
      /* here, we could ask ddraw to load a separate DLL, that
       * would contain the 32-bit ddraw HAL */
      strcpy(lpData->szName,"x11drv");
      /* the entry point named here should initialize our hal_info
       * with 32-bit entry points (ignored for now) */
      strcpy(lpData->szEntryPoint,"DriverInit");
      lpData->dwContext = 0;
    }
    return TRUE;
  case DDCREATEDRIVEROBJECT:
    {
      LPDWORD lpInstance = (LPDWORD)lpOutData;

      /* FIXME: get x11drv's hInstance */
#ifdef HAVE_LIBXXF86DGA2
      if (!X11DRV_XF86DGA2_CreateDriver(&hal_info))
#endif
      {
#ifdef HAVE_LIBXXF86VM
	X11DRV_XF86VM_CreateDriver(&hal_info);
#endif
      }
#ifdef HAVE_OPENGL
      /*X11DRV_GLX_CreateDriver(&hal_info);*/
#endif

      (ddraw_fns->lpSetInfo)(&hal_info, FALSE);
      *lpInstance = hal_info.hInstance;
    }
    return TRUE;
  }
  return 0;
}

void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr, LPVIDMEM fb_mem)
{
  LPDDHALMODEINFO info = &hal_info.lpModeInfo[dwModeIndex];

  hal_info.dwModeIndex        = dwModeIndex;
  hal_info.dwMonitorFrequency = info->wRefreshRate;
  hal_info.vmiData.fpPrimary  = (FLATPTR)fb_addr;
  hal_info.vmiData.dwDisplayWidth  = info->dwWidth;
  hal_info.vmiData.dwDisplayHeight = info->dwHeight;
  hal_info.vmiData.lDisplayPitch   = info->lPitch;
  hal_info.vmiData.ddpfDisplay.dwSize = info->dwBPP ? sizeof(hal_info.vmiData.ddpfDisplay) : 0;
  hal_info.vmiData.ddpfDisplay.dwFlags = (info->wFlags & DDMODEINFO_PALETTIZED) ? DDPF_PALETTEINDEXED8 : 0;
  hal_info.vmiData.ddpfDisplay.u1.dwRGBBitCount = (info->dwBPP > 24) ? 24 : info->dwBPP;
  hal_info.vmiData.ddpfDisplay.u2.dwRBitMask = info->dwRBitMask;
  hal_info.vmiData.ddpfDisplay.u3.dwGBitMask = info->dwGBitMask;
  hal_info.vmiData.ddpfDisplay.u4.dwBBitMask = info->dwBBitMask;
  hal_info.vmiData.dwNumHeaps = fb_mem ? 1 : 0;
  hal_info.vmiData.pvmList = fb_mem;

  X11DRV_DDHAL_SetInfo();
}

void X11DRV_DDHAL_SetPalEntries(Colormap pal, DWORD dwBase, DWORD dwNumEntries,
				LPPALETTEENTRY lpEntries)
{
  XColor c;
  int n;

  if (pal) {
    c.flags = DoRed|DoGreen|DoBlue;
    c.pixel = dwBase;
    for (n=0; n<dwNumEntries; n++,c.pixel++) {
      c.red   = lpEntries[n].peRed   << 8;
      c.green = lpEntries[n].peGreen << 8;
      c.blue  = lpEntries[n].peBlue  << 8;
      TSXStoreColor(gdi_display, pal, &c);
    }
    TSXFlush(gdi_display); /* update display immediately */
  }
}
