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