Commit 71c69849 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Implemented DirectDraw's Hardware Abstraction Layer (HAL) interface.

Disabled DirectDraw's old XVidMode and DGA2 drivers, it now depends on the display driver (x11drv) HAL implementations of these features.
parent 9bebbc5d
......@@ -24,15 +24,18 @@ C_SRCS = \
convert.c \
dclipper/main.c \
ddraw/dga2.c \
ddraw/hal.c \
ddraw/main.c \
ddraw/thunks.c \
ddraw/user.c \
ddraw/xvidmode.c \
dpalette/hal.c \
dpalette/main.c \
dsurface/dga2.c \
dsurface/dib.c \
dsurface/fakezbuffer.c \
dsurface/gamma.c \
dsurface/hal.c \
dsurface/main.c \
dsurface/thunks.c \
dsurface/user.c \
......
/* DirectDraw HAL driver
*
* Copyright 2001 TransGaming Technologies Inc.
*/
#include "config.h"
#include "debugtools.h"
#include "ddraw.h"
#include "ddrawi.h"
#include "d3dhal.h"
#include <assert.h>
#include <stdlib.h>
#include "ddraw_private.h"
#include "ddraw/main.h"
#include "ddraw/user.h"
#include "ddraw/hal.h"
#include "dclipper/main.h"
#include "dpalette/main.h"
#include "dpalette/hal.h"
#include "dsurface/main.h"
#include "dsurface/dib.h"
#include "dsurface/user.h"
#include "dsurface/hal.h"
#include "options.h"
DEFAULT_DEBUG_CHANNEL(ddraw);
static ICOM_VTABLE(IDirectDraw7) HAL_DirectDraw_VTable;
static DDVERSIONDATA hal_version;
static DD32BITDRIVERDATA hal_driverdata;
static HINSTANCE hal_instance;
static const DDDEVICEIDENTIFIER2 hal_device =
{
"display",
"DirectDraw HAL",
{ { 0x00010001, 0x00010001 } },
0, 0, 0, 0,
/* 40c1b248-9d7d-4a29-b7d7-4cd8109f3d5d */
{0x40c1b248,0x9d7d,0x4a29,{0xd7,0xb7,0x4c,0xd8,0x10,0x9f,0x3d,0x5d}},
0
};
HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
IUnknown* pUnkOuter, BOOL ex);
HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*);
static const ddraw_driver hal_driver =
{
&hal_device,
100, /* we prefer the HAL */
HAL_DirectDraw_Create,
HAL_DirectDraw_Initialize
};
static DDHAL_CALLBACKS dd_cbs;
static DDRAWI_DIRECTDRAW_GBL dd_gbl;
static D3DHAL_GLOBALDRIVERDATA d3d_hal_data;
static D3DHAL_D3DEXTENDEDCAPS d3d_hal_extcaps;
static D3DHAL_CALLBACKS d3d_hal_cbs1;
static D3DHAL_CALLBACKS2 d3d_hal_cbs2;
/* in real windoze, these entry points are 16-bit, but we can work in 32-bit */
static BOOL DDAPI set_hal_info(LPDDHALINFO lpDDHalInfo, BOOL reset)
{
dd_cbs.HALDD = *lpDDHalInfo->lpDDCallbacks;
dd_cbs.HALDDSurface = *lpDDHalInfo->lpDDSurfaceCallbacks;
dd_cbs.HALDDPalette = *lpDDHalInfo->lpDDPaletteCallbacks;
if (lpDDHalInfo->lpDDExeBufCallbacks)
dd_cbs.HALDDExeBuf = *lpDDHalInfo->lpDDExeBufCallbacks;
dd_gbl.lpDDCBtmp = &dd_cbs;
dd_gbl.ddCaps = lpDDHalInfo->ddCaps;
dd_gbl.dwMonitorFrequency = lpDDHalInfo->dwMonitorFrequency;
dd_gbl.vmiData = lpDDHalInfo->vmiData;
dd_gbl.dwModeIndex = lpDDHalInfo->dwModeIndex;
/* FIXME: dwNumFourCC */
dd_gbl.lpdwFourCC = lpDDHalInfo->lpdwFourCC;
dd_gbl.dwNumModes = lpDDHalInfo->dwNumModes;
dd_gbl.lpModeInfo = lpDDHalInfo->lpModeInfo;
/* FIXME: dwFlags */
dd_gbl.dwPDevice = (DWORD)lpDDHalInfo->lpPDevice;
dd_gbl.hInstance = lpDDHalInfo->hInstance;
/* DirectX 2 */
if (lpDDHalInfo->lpD3DGlobalDriverData)
memcpy(&d3d_hal_data, (LPVOID)lpDDHalInfo->lpD3DGlobalDriverData, sizeof(D3DDEVICEDESC_V1));
else
memset(&d3d_hal_data, 0, sizeof(D3DDEVICEDESC_V1));
dd_gbl.lpD3DGlobalDriverData = (ULONG_PTR)&d3d_hal_data;
if (lpDDHalInfo->lpD3DHALCallbacks)
memcpy(&d3d_hal_cbs1, (LPVOID)lpDDHalInfo->lpD3DHALCallbacks, sizeof(D3DHAL_CALLBACKS));
else
memset(&d3d_hal_cbs1, 0, sizeof(D3DDEVICEDESC_V1));
dd_gbl.lpD3DHALCallbacks = (ULONG_PTR)&d3d_hal_cbs1;
if (lpDDHalInfo->dwFlags & DDHALINFO_GETDRIVERINFOSET) {
DDHAL_GETDRIVERINFODATA data;
data.dwSize = sizeof(DDHAL_GETDRIVERINFODATA);
data.dwFlags = 0; /* ? */
data.dwContext = hal_driverdata.dwContext; /* ? */
data.guidInfo = GUID_D3DExtendedCaps;
data.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
data.lpvData = &d3d_hal_extcaps;
data.dwActualSize = 0;
data.ddRVal = 0;
lpDDHalInfo->GetDriverInfo(&data);
d3d_hal_extcaps.dwSize = data.dwActualSize;
dd_gbl.lpD3DExtendedCaps = (ULONG_PTR)&d3d_hal_extcaps;
data.guidInfo = GUID_D3DCallbacks2;
data.dwExpectedSize = sizeof(D3DHAL_CALLBACKS2);
data.lpvData = &d3d_hal_cbs2;
data.dwActualSize = 0;
data.ddRVal = 0;
lpDDHalInfo->GetDriverInfo(&data);
d3d_hal_cbs2.dwSize = data.dwActualSize;
dd_gbl.lpD3DHALCallbacks2 = (ULONG_PTR)&d3d_hal_cbs2;
}
#ifdef HAVE_OPENGL
if (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) {
/*GL_DirectDraw_Init(&dd_gbl);*/
}
#endif
return FALSE;
}
static DDHALDDRAWFNS hal_funcs = {
sizeof(DDHALDDRAWFNS),
set_hal_info,
NULL, /* VidMemAlloc */
NULL /* VidMemFree */
};
/* Called from DllInit, which is synchronised so there are no threading
* concerns. */
static BOOL initialize(void)
{
DCICMD cmd;
INT ncmd = DCICOMMAND;
BOOL ret;
HDC dc = CreateDCA("DISPLAY", NULL, NULL, NULL);
INT ver = Escape(dc, QUERYESCSUPPORT, sizeof(ncmd), (LPVOID)&ncmd, NULL);
if (ver != DD_HAL_VERSION) {
DeleteDC(dc);
TRACE("DirectDraw HAL not available\n");
return FALSE;
}
cmd.dwVersion = DD_VERSION;
cmd.dwReserved = 0;
/* the DDNEWCALLBACKFNS is supposed to give the 16-bit driver entry points
* in ddraw16.dll, but since Wine doesn't have or use 16-bit display drivers,
* we'll just work in 32-bit, who'll notice... */
cmd.dwCommand = DDNEWCALLBACKFNS;
cmd.dwParam1 = (DWORD)&hal_funcs;
ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, 0, NULL);
/* next, exchange version information */
cmd.dwCommand = DDVERSIONINFO;
cmd.dwParam1 = DD_RUNTIME_VERSION; /* not sure what should *really* go here */
ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_version), (LPVOID)&hal_version);
/* get 32-bit driver data (dll name and entry point) */
cmd.dwCommand = DDGET32BITDRIVERNAME;
ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_driverdata), (LPVOID)&hal_driverdata);
/* we're supposed to load the DLL in hal_driverdata.szName, then GetProcAddress
* the hal_driverdata.szEntryPoint, and call it with hal_driverdata.dwContext
* as a parameter... but since this is only more remains from the 16-bit world,
* we'll ignore it */
/* finally, initialize the driver object */
cmd.dwCommand = DDCREATEDRIVEROBJECT;
ret = ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_instance), (LPVOID)&hal_instance);
if (ret) {
/* the driver should have called our set_hal_info now */
if (!dd_gbl.lpDDCBtmp) ret = FALSE;
}
/* init done */
DeleteDC(dc);
TRACE("%s DirectDraw HAL\n", ret ? "enabling" : "disabling");
return ret;
}
static void cleanup(void)
{
DDHAL_DESTROYDRIVERDATA data;
data.lpDD = NULL;
data.ddRVal = 0;
data.DestroyDriver = dd_cbs.HALDD.DestroyDriver;
data.DestroyDriver(&data);
}
static DWORD choose_mode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
DWORD dwRefreshRate, DWORD dwFlags)
{
int best = -1;
int i;
if (!dd_gbl.dwNumModes) return 0;
/* let's support HALs that cannot switch depths (XVidMode),
* these should return dwBPP == 0 for all their resolutions */
#define BPP_MATCH(dd, bpp) ((!(dd)) || ((dd) == bpp))
/* FIXME: we should try to match the refresh rate too */
/* Choose the smallest mode that is large enough. */
for (i=0; i < dd_gbl.dwNumModes; i++)
{
if (dd_gbl.lpModeInfo[i].dwWidth >= dwWidth &&
dd_gbl.lpModeInfo[i].dwHeight >= dwHeight &&
BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP))
{
if (best == -1) best = i;
else
{
if (dd_gbl.lpModeInfo[i].dwWidth < dd_gbl.lpModeInfo[best].dwWidth ||
dd_gbl.lpModeInfo[i].dwHeight < dd_gbl.lpModeInfo[best].dwHeight)
best = i;
}
}
}
if (best == -1)
{
TRACE("all modes too small\n");
/* ok, let's use the largest */
for (i=0; i < dd_gbl.dwNumModes; i++)
{
if (BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP))
{
if (best == -1) best = i;
else
{
if (dd_gbl.lpModeInfo[i].dwWidth > dd_gbl.lpModeInfo[best].dwWidth ||
dd_gbl.lpModeInfo[i].dwHeight > dd_gbl.lpModeInfo[best].dwHeight)
best = i;
}
}
}
}
#undef BPP_MATCH
if (best == -1)
{
ERR("requested color depth (%ld) not available, try reconfiguring X server\n", dwBPP);
return dd_gbl.dwModeIndex;
}
TRACE("using mode %d\n", best);
return best;
}
static HRESULT set_mode(IDirectDrawImpl *This, DWORD dwMode)
{
HRESULT hr = DD_OK;
if (dwMode != dd_gbl.dwModeIndex)
{
DDHAL_SETMODEDATA data;
data.lpDD = &dd_gbl;
data.dwModeIndex = dwMode;
data.ddRVal = 0;
data.SetMode = dd_cbs.HALDD.SetMode;
data.inexcl = 0;
data.useRefreshRate = FALSE;
if (data.SetMode)
data.SetMode(&data);
hr = data.ddRVal;
if (SUCCEEDED(hr))
dd_gbl.dwModeIndex = dwMode;
}
return hr;
}
static HRESULT set_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl)
{
DDHAL_SETEXCLUSIVEMODEDATA data;
data.lpDD = &dd_gbl;
data.dwEnterExcl = dwEnterExcl;
data.dwReserved = 0;
data.ddRVal = 0;
data.SetExclusiveMode = dd_cbs.HALDD.SetExclusiveMode;
if (data.SetExclusiveMode)
data.SetExclusiveMode(&data);
return data.ddRVal;
}
BOOL DDRAW_HAL_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
if (initialize())
DDRAW_register_driver(&hal_driver);
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
cleanup();
}
return TRUE;
}
/* Not called from the vtable. */
HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
{
HRESULT hr;
TRACE("(%p)\n", This);
hr = User_DirectDraw_Construct(This, ex);
if (FAILED(hr)) return hr;
This->local.lpGbl = &dd_gbl;
This->final_release = HAL_DirectDraw_final_release;
This->set_exclusive_mode = set_exclusive_mode;
This->create_palette = HAL_DirectDrawPalette_Create;
This->create_primary = HAL_DirectDraw_create_primary;
This->create_backbuffer = HAL_DirectDraw_create_backbuffer;
This->create_texture = HAL_DirectDraw_create_texture;
ICOM_INIT_INTERFACE(This, IDirectDraw7, HAL_DirectDraw_VTable);
/* merge HAL caps */
This->caps.dwCaps |= dd_gbl.ddCaps.dwCaps;
This->caps.dwCaps2 |= dd_gbl.ddCaps.dwCaps2;
This->caps.dwCKeyCaps |= dd_gbl.ddCaps.dwCKeyCaps;
This->caps.dwFXCaps |= dd_gbl.ddCaps.dwFXCaps;
This->caps.dwPalCaps |= dd_gbl.ddCaps.dwPalCaps;
/* FIXME: merge more caps */
This->caps.ddsCaps.dwCaps |= dd_gbl.ddCaps.ddsCaps.dwCaps;
This->caps.ddsCaps.dwCaps2 |= dd_gbl.ddsCapsMore.dwCaps2;
This->caps.ddsCaps.dwCaps3 |= dd_gbl.ddsCapsMore.dwCaps3;
This->caps.ddsCaps.dwCaps4 |= dd_gbl.ddsCapsMore.dwCaps4;
This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps;
return S_OK;
}
/* This function is called from DirectDrawCreate(Ex) on the most-derived
* class to start construction.
* Not called from the vtable. */
HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
IUnknown* pUnkOuter, BOOL ex)
{
HRESULT hr;
IDirectDrawImpl* This;
TRACE("\n");
assert(pUnkOuter == NULL);
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(IDirectDrawImpl)
+ sizeof(HAL_DirectDrawImpl));
if (This == NULL) return E_OUTOFMEMORY;
/* Note that this relation does *not* hold true if the DD object was
* CoCreateInstanced then Initialized. */
This->private = (HAL_DirectDrawImpl *)(This+1);
hr = HAL_DirectDraw_Construct(This, ex);
if (FAILED(hr))
HeapFree(GetProcessHeap(), 0, This);
else
*pIface = ICOM_INTERFACE(This, IDirectDraw7);
return hr;
}
/* This function is called from Uninit_DirectDraw_Initialize on the
* most-derived-class to start initialization.
* Not called from the vtable. */
HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid)
{
HRESULT hr;
TRACE("\n");
This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(HAL_DirectDrawImpl));
if (This->private == NULL) return E_OUTOFMEMORY;
hr = HAL_DirectDraw_Construct(This, TRUE); /* XXX ex? */
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, This->private);
return hr;
}
return DD_OK;
}
/* Called from an internal function pointer. */
void HAL_DirectDraw_final_release(IDirectDrawImpl *This)
{
if (dd_gbl.dwFlags & DDRAWI_MODECHANGED) set_mode(This, dd_gbl.dwModeIndexOrig);
User_DirectDraw_final_release(This);
}
HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This,
const DDSURFACEDESC2* pDDSD,
LPDIRECTDRAWSURFACE7* ppSurf,
IUnknown* pUnkOuter)
{
if (This->cooperative_level & DDSCL_EXCLUSIVE)
return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
else
return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
}
HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
const DDSURFACEDESC2* pDDSD,
LPDIRECTDRAWSURFACE7* ppSurf,
IUnknown* pUnkOuter,
IDirectDrawSurfaceImpl* primary)
{
if (This->cooperative_level & DDSCL_EXCLUSIVE)
return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
else
return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter);
}
HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,
const DDSURFACEDESC2* pDDSD,
LPDIRECTDRAWSURFACE7* ppSurf,
LPUNKNOWN pOuter,
DWORD dwMipMapLevel)
{
return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);
}
HRESULT WINAPI
HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
LPDDDEVICEIDENTIFIER2 pDDDI,
DWORD dwFlags)
{
*pDDDI = hal_device;
return DD_OK;
}
HRESULT WINAPI
HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
{
ICOM_THIS(IDirectDrawImpl, iface);
HRESULT hr;
TRACE("(%p)\n", iface);
if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) return DD_OK;
hr = Main_DirectDraw_RestoreDisplayMode(iface);
if (SUCCEEDED(hr)) {
hr = set_mode(This, dd_gbl.dwModeIndexOrig);
if (SUCCEEDED(hr)) dd_gbl.dwFlags &= ~DDRAWI_MODECHANGED;
}
return hr;
}
HRESULT WINAPI
HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
DWORD dwHeight, DWORD dwBPP,
DWORD dwRefreshRate, DWORD dwFlags)
{
ICOM_THIS(IDirectDrawImpl, iface);
HRESULT hr;
TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags);
hr = User_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP,
dwRefreshRate, dwFlags);
if (SUCCEEDED(hr)) {
if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) dd_gbl.dwModeIndexOrig = dd_gbl.dwModeIndex;
hr = set_mode(This, choose_mode(dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags));
if (SUCCEEDED(hr)) dd_gbl.dwFlags |= DDRAWI_MODECHANGED;
}
return hr;
}
static ICOM_VTABLE(IDirectDraw7) HAL_DirectDraw_VTable =
{
Main_DirectDraw_QueryInterface,
Main_DirectDraw_AddRef,
Main_DirectDraw_Release,
Main_DirectDraw_Compact,
Main_DirectDraw_CreateClipper,
Main_DirectDraw_CreatePalette,
Main_DirectDraw_CreateSurface,
Main_DirectDraw_DuplicateSurface,
User_DirectDraw_EnumDisplayModes,
Main_DirectDraw_EnumSurfaces,
Main_DirectDraw_FlipToGDISurface,
Main_DirectDraw_GetCaps,
Main_DirectDraw_GetDisplayMode,
Main_DirectDraw_GetFourCCCodes,
Main_DirectDraw_GetGDISurface,
Main_DirectDraw_GetMonitorFrequency,
Main_DirectDraw_GetScanLine,
Main_DirectDraw_GetVerticalBlankStatus,
Main_DirectDraw_Initialize,
HAL_DirectDraw_RestoreDisplayMode,
Main_DirectDraw_SetCooperativeLevel,
HAL_DirectDraw_SetDisplayMode,
Main_DirectDraw_WaitForVerticalBlank,
Main_DirectDraw_GetAvailableVidMem,
Main_DirectDraw_GetSurfaceFromDC,
Main_DirectDraw_RestoreAllSurfaces,
Main_DirectDraw_TestCooperativeLevel,
HAL_DirectDraw_GetDeviceIdentifier,
Main_DirectDraw_StartModeTest,
Main_DirectDraw_EvaluateMode
};
/* Copyright 2001 TransGaming Technologies, Inc. */
#ifndef WINE_DDRAW_DDRAW_HAL_H_INCLUDED
#define WINE_DDRAW_DDRAW_HAL_H_INCLUDED
#define HAL_DDRAW_PRIV(ddraw) \
((HAL_DirectDrawImpl*)((ddraw)->private))
#define HAL_DDRAW_PRIV_VAR(name,ddraw) \
HAL_DirectDrawImpl* name = HAL_DDRAW_PRIV(ddraw)
typedef struct
{
DWORD next_vofs;
} HAL_DirectDrawImpl_Part;
typedef struct
{
User_DirectDrawImpl_Part user;
HAL_DirectDrawImpl_Part hal;
} HAL_DirectDrawImpl;
void HAL_DirectDraw_final_release(IDirectDrawImpl* This);
HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This,
const DDSURFACEDESC2* pDDSD,
LPDIRECTDRAWSURFACE7* ppSurf,
LPUNKNOWN pOuter);
HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
const DDSURFACEDESC2* pDDSD,
LPDIRECTDRAWSURFACE7* ppSurf,
LPUNKNOWN pOuter,
IDirectDrawSurfaceImpl* primary);
HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,
const DDSURFACEDESC2* pDDSD,
LPDIRECTDRAWSURFACE7* ppSurf,
LPUNKNOWN pOuter,
DWORD dwMipMapLevel);
HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex);
HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
IUnknown* pUnkOuter, BOOL ex);
HRESULT WINAPI
HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
LPDDDEVICEIDENTIFIER2 pDDDI,
DWORD dwFlags);
HRESULT WINAPI
HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
DWORD dwHeight, DWORD dwBPP,
DWORD dwRefreshRate, DWORD dwFlags);
HRESULT WINAPI
HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface);
#endif
/* DirectDrawPalette HAL driver
*
* Copyright 2001 TransGaming Technologies Inc.
*/
#include "config.h"
#include "winerror.h"
#include "debugtools.h"
#include <assert.h>
#include <string.h>
#include "ddraw_private.h"
#include "dpalette/main.h"
#include "dpalette/hal.h"
#include "ddraw/main.h"
DEFAULT_DEBUG_CHANNEL(ddraw);
static ICOM_VTABLE(IDirectDrawPalette) DDRAW_HAL_Palette_VTable;
/******************************************************************************
* IDirectDrawPalette
*/
HRESULT HAL_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
IDirectDrawImpl* pDD, DWORD dwFlags)
{
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
DDHAL_CREATEPALETTEDATA data;
HRESULT hr;
hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags);
if (FAILED(hr)) return hr;
This->final_release = HAL_DirectDrawPalette_final_release;
ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_HAL_Palette_VTable);
/* initialize HAL palette */
data.lpDD = dd_gbl;
data.lpDDPalette = &This->global;
data.lpColorTable = NULL;
data.ddRVal = 0;
data.CreatePalette = dd_gbl->lpDDCBtmp->HALDD.CreatePalette;
if (data.CreatePalette)
data.CreatePalette(&data);
return DD_OK;
}
HRESULT
HAL_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
LPDIRECTDRAWPALETTE* ppPalette,
LPUNKNOWN pUnkOuter)
{
IDirectDrawPaletteImpl* This;
HRESULT hr;
if (pUnkOuter != NULL)
return CLASS_E_NOAGGREGATION; /* unchecked */
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
if (This == NULL) return E_OUTOFMEMORY;
hr = HAL_DirectDrawPalette_Construct(This, pDD, dwFlags);
if (FAILED(hr))
HeapFree(GetProcessHeap(), 0, This);
else
*ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette);
return hr;
}
HRESULT WINAPI
HAL_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
DWORD dwStart, DWORD dwCount,
LPPALETTEENTRY palent)
{
ICOM_THIS(IDirectDrawPaletteImpl,iface);
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->local.lpDD_lcl->lpGbl;
DDHAL_SETENTRIESDATA data;
TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount,
palent);
data.lpDD = dd_gbl;
data.lpDDPalette = &This->global;
data.dwBase = dwStart;
data.dwNumEntries = dwCount;
data.lpEntries = palent;
data.ddRVal = 0;
data.SetEntries = dd_gbl->lpDDCBtmp->HALDDPalette.SetEntries;
if (data.SetEntries)
data.SetEntries(&data);
return Main_DirectDrawPalette_SetEntries(iface, dwFlags, dwStart, dwCount, palent);
}
void HAL_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This)
{
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->local.lpDD_lcl->lpGbl;
DDHAL_DESTROYPALETTEDATA data;
/* destroy HAL palette */
data.lpDD = dd_gbl;
data.lpDDPalette = &This->global;
data.ddRVal = 0;
data.DestroyPalette = dd_gbl->lpDDCBtmp->HALDDPalette.DestroyPalette;
if (data.DestroyPalette)
data.DestroyPalette(&data);
Main_DirectDrawPalette_final_release(This);
}
static ICOM_VTABLE(IDirectDrawPalette) DDRAW_HAL_Palette_VTable =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
Main_DirectDrawPalette_QueryInterface,
Main_DirectDrawPalette_AddRef,
Main_DirectDrawPalette_Release,
Main_DirectDrawPalette_GetCaps,
Main_DirectDrawPalette_GetEntries,
Main_DirectDrawPalette_Initialize,
HAL_DirectDrawPalette_SetEntries
};
/* Copyright 2000-2001 TransGaming Technologies Inc. */
#ifndef WINE_DDRAW_DPALETTE_HAL_H_INCLUDED
#define WINE_DDRAW_DPALETTE_HAL_H_INCLUDED
HRESULT HAL_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This,
IDirectDrawImpl* pDD, DWORD dwFlags);
void HAL_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This);
HRESULT
HAL_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags,
LPDIRECTDRAWPALETTE* ppPalette,
LPUNKNOWN pUnkOuter);
HRESULT WINAPI
HAL_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags,
DWORD dwStart, DWORD dwCount,
LPPALETTEENTRY palent);
#endif
/* DirectDrawSurface HAL driver
*
* Copyright 2001 TransGaming Technologies Inc.
*/
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include "debugtools.h"
#include "ddraw_private.h"
#include "ddraw/user.h"
#include "ddraw/hal.h"
#include "dsurface/main.h"
#include "dsurface/dib.h"
#include "dsurface/user.h"
#include "dsurface/hal.h"
DEFAULT_DEBUG_CHANNEL(ddraw);
static ICOM_VTABLE(IDirectDrawSurface7) HAL_IDirectDrawSurface7_VTable;
static HRESULT HAL_DirectDrawSurface_create_surface(IDirectDrawSurfaceImpl* This,
IDirectDrawImpl* pDD)
{
HAL_PRIV_VAR(priv, This);
HAL_DDRAW_PRIV_VAR(ddpriv, pDD);
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
LPDDRAWI_DDRAWSURFACE_LCL local = &This->local;
DDHAL_CREATESURFACEDATA data;
HRESULT hr;
data.lpDD = dd_gbl;
data.lpDDSurfaceDesc = (LPDDSURFACEDESC)&This->surface_desc;
data.lplpSList = &local;
data.dwSCnt = 1;
data.ddRVal = 0;
data.CreateSurface = dd_gbl->lpDDCBtmp->HALDD.CreateSurface;
hr = data.CreateSurface(&data);
if (hr == DDHAL_DRIVER_HANDLED) {
if (This->global.fpVidMem < 4) {
/* grab framebuffer data from current_mode */
priv->hal.fb_pitch = dd_gbl->vmiData.lDisplayPitch;
priv->hal.fb_vofs = ddpriv->hal.next_vofs;
priv->hal.fb_addr = ((LPBYTE)dd_gbl->vmiData.fpPrimary) +
dd_gbl->vmiData.lDisplayPitch * priv->hal.fb_vofs;
TRACE("vofs=%ld, addr=%p\n", priv->hal.fb_vofs, priv->hal.fb_addr);
ddpriv->hal.next_vofs += This->surface_desc.dwHeight;
This->global.fpVidMem = (FLATPTR)priv->hal.fb_addr;
}
This->surface_desc.lpSurface = (LPVOID)This->global.fpVidMem;
This->surface_desc.dwFlags |= DDSD_LPSURFACE;
if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) {
This->surface_desc.u1.dwLinearSize = This->global.u4.dwLinearSize;
This->surface_desc.dwFlags |= DDSD_LINEARSIZE;
} else {
This->surface_desc.u1.lPitch = This->global.u4.lPitch;
This->surface_desc.dwFlags |= DDSD_PITCH;
}
}
else priv->hal.need_late = TRUE;
return data.ddRVal;
}
static inline BOOL HAL_IsUser(IDirectDrawSurfaceImpl* This)
{
HAL_PRIV_VAR(priv, This);
if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_EXECUTEBUFFER))
return FALSE;
if (priv->hal.fb_addr)
return FALSE;
return TRUE;
}
HRESULT
HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
IDirectDrawImpl* pDD,
const DDSURFACEDESC2* pDDSD)
{
HAL_PRIV_VAR(priv, This);
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
HRESULT hr;
TRACE("(%p,%p,%p)\n",This,pDD,pDDSD);
/* copy surface_desc, we may want to modify it before DIB construction */
This->surface_desc = *pDDSD;
/* the driver may want to dereference these pointers */
This->local.lpSurfMore = &This->more;
This->local.lpGbl = &This->global;
This->gmore = &This->global_more;
if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
hr = HAL_DirectDrawSurface_create_surface(This, pDD);
if (FAILED(hr)) return hr;
hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
if (FAILED(hr)) return hr;
}
else if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) {
FIXME("create execute buffer\n");
return DDERR_GENERIC;
}
else {
if (!(dd_gbl->dwFlags & DDRAWI_MODECHANGED)) {
/* force a mode set (HALs like DGA may need it) */
hr = HAL_DirectDraw_SetDisplayMode(ICOM_INTERFACE(pDD, IDirectDraw7),
pDD->width, pDD->height,
pDD->pixelformat.u1.dwRGBBitCount,
0, 0);
if (FAILED(hr)) return hr;
}
if (dd_gbl->vmiData.fpPrimary) {
hr = HAL_DirectDrawSurface_create_surface(This, pDD);
if (FAILED(hr)) return hr;
if (priv->hal.need_late) {
/* this doesn't make sense... driver error? */
ERR("driver failed to create framebuffer surface\n");
return DDERR_GENERIC;
}
hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
if (FAILED(hr)) return hr;
} else {
/* no framebuffer, construct User-based primary */
hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD);
if (FAILED(hr)) return hr;
/* must notify HAL *after* creating User-based primary */
/* (or use CreateSurfaceEx, which we don't yet) */
hr = HAL_DirectDrawSurface_create_surface(This, pDD);
if (FAILED(hr)) return hr;
priv->hal.need_late = FALSE;
}
}
ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
HAL_IDirectDrawSurface7_VTable);
This->final_release = HAL_DirectDrawSurface_final_release;
This->late_allocate = HAL_DirectDrawSurface_late_allocate;
This->duplicate_surface = HAL_DirectDrawSurface_duplicate_surface;
This->flip_data = HAL_DirectDrawSurface_flip_data;
This->flip_update = HAL_DirectDrawSurface_flip_update;
This->set_palette = HAL_DirectDrawSurface_set_palette;
This->get_display_window = HAL_DirectDrawSurface_get_display_window;
return DD_OK;
}
HRESULT
HAL_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
const DDSURFACEDESC2 *pDDSD,
LPDIRECTDRAWSURFACE7 *ppSurf,
IUnknown *pUnkOuter)
{
IDirectDrawSurfaceImpl* This;
HRESULT hr;
assert(pUnkOuter == NULL);
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(*This) + sizeof(HAL_DirectDrawSurfaceImpl));
if (This == NULL) return E_OUTOFMEMORY;
This->private = (HAL_DirectDrawSurfaceImpl*)(This+1);
hr = HAL_DirectDrawSurface_Construct(This, pDD, pDDSD);
if (FAILED(hr))
HeapFree(GetProcessHeap(), 0, This);
else
*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);
return hr;
}
void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
{
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
DDHAL_DESTROYSURFACEDATA data;
/* destroy HAL surface */
data.lpDD = dd_gbl;
data.lpDDSurface = &This->local;
data.ddRVal = 0;
data.DestroySurface = dd_gbl->lpDDCBtmp->HALDDSurface.DestroySurface;
data.DestroySurface(&data);
if (HAL_IsUser(This)) {
User_DirectDrawSurface_final_release(This);
} else {
DIB_DirectDrawSurface_final_release(This);
}
}
HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
{
HAL_PRIV_VAR(priv, This);
if (priv->hal.need_late) {
priv->hal.need_late = FALSE;
return HAL_DirectDrawSurface_create_surface(This, This->ddraw_owner);
}
return DD_OK;
}
void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
IDirectDrawPaletteImpl* pal)
{
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
DDHAL_SETPALETTEDATA data;
DIB_DirectDrawSurface_set_palette(This, pal);
data.lpDD = dd_gbl;
data.lpDDSurface = &This->local;
data.lpDDPalette = &pal->global;
data.ddRVal = 0;
data.Attach = TRUE; /* what's this? */
data.SetPalette = dd_gbl->lpDDCBtmp->HALDDSurface.SetPalette;
if (data.SetPalette)
data.SetPalette(&data);
}
HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
LPDIRECTDRAWSURFACE7* ppDup)
{
return HAL_DirectDrawSurface_Create(This->ddraw_owner,
&This->surface_desc, ppDup, NULL);
}
void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect)
{
if (HAL_IsUser(This)) {
User_DirectDrawSurface_lock_update(This, pRect);
} else {
Main_DirectDrawSurface_lock_update(This, pRect);
}
}
void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect)
{
if (HAL_IsUser(This)) {
User_DirectDrawSurface_unlock_update(This, pRect);
} else {
Main_DirectDrawSurface_unlock_update(This, pRect);
}
}
BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
IDirectDrawSurfaceImpl* back,
DWORD dwFlags)
{
HAL_PRIV_VAR(front_priv, front);
HAL_PRIV_VAR(back_priv, back);
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = front->more.lpDD_lcl->lpGbl;
DDHAL_FLIPDATA data;
BOOL ret;
{
DWORD tmp;
tmp = front_priv->hal.fb_vofs;
front_priv->hal.fb_vofs = back_priv->hal.fb_vofs;
back_priv->hal.fb_vofs = tmp;
}
{
LPVOID tmp;
tmp = front_priv->hal.fb_addr;
front_priv->hal.fb_addr = back_priv->hal.fb_addr;
back_priv->hal.fb_addr = tmp;
}
if (HAL_IsUser(front)) {
ret = User_DirectDrawSurface_flip_data(front, back, dwFlags);
} else {
ret = DIB_DirectDrawSurface_flip_data(front, back, dwFlags);
}
data.lpDD = dd_gbl;
data.lpSurfCurr = &front->local;
data.lpSurfTarg = &back->local;
data.lpSurfCurrLeft = NULL;
data.lpSurfTargLeft = NULL;
data.dwFlags = dwFlags;
data.ddRVal = 0;
data.Flip = dd_gbl->lpDDCBtmp->HALDDSurface.Flip;
if (data.Flip)
if (data.Flip(&data) == DDHAL_DRIVER_HANDLED) ret = FALSE;
return ret;
}
void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags)
{
if (HAL_IsUser(This)) {
User_DirectDrawSurface_flip_update(This, dwFlags);
}
}
HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
{
return 0;
}
static ICOM_VTABLE(IDirectDrawSurface7) HAL_IDirectDrawSurface7_VTable =
{
Main_DirectDrawSurface_QueryInterface,
Main_DirectDrawSurface_AddRef,
Main_DirectDrawSurface_Release,
Main_DirectDrawSurface_AddAttachedSurface,
Main_DirectDrawSurface_AddOverlayDirtyRect,
DIB_DirectDrawSurface_Blt,
Main_DirectDrawSurface_BltBatch,
DIB_DirectDrawSurface_BltFast,
Main_DirectDrawSurface_DeleteAttachedSurface,
Main_DirectDrawSurface_EnumAttachedSurfaces,
Main_DirectDrawSurface_EnumOverlayZOrders,
Main_DirectDrawSurface_Flip,
Main_DirectDrawSurface_GetAttachedSurface,
Main_DirectDrawSurface_GetBltStatus,
Main_DirectDrawSurface_GetCaps,
Main_DirectDrawSurface_GetClipper,
Main_DirectDrawSurface_GetColorKey,
Main_DirectDrawSurface_GetDC,
Main_DirectDrawSurface_GetFlipStatus,
Main_DirectDrawSurface_GetOverlayPosition,
Main_DirectDrawSurface_GetPalette,
Main_DirectDrawSurface_GetPixelFormat,
Main_DirectDrawSurface_GetSurfaceDesc,
Main_DirectDrawSurface_Initialize,
Main_DirectDrawSurface_IsLost,
Main_DirectDrawSurface_Lock,
Main_DirectDrawSurface_ReleaseDC,
DIB_DirectDrawSurface_Restore,
Main_DirectDrawSurface_SetClipper,
Main_DirectDrawSurface_SetColorKey,
Main_DirectDrawSurface_SetOverlayPosition,
Main_DirectDrawSurface_SetPalette,
Main_DirectDrawSurface_Unlock,
Main_DirectDrawSurface_UpdateOverlay,
Main_DirectDrawSurface_UpdateOverlayDisplay,
Main_DirectDrawSurface_UpdateOverlayZOrder,
Main_DirectDrawSurface_GetDDInterface,
Main_DirectDrawSurface_PageLock,
Main_DirectDrawSurface_PageUnlock,
DIB_DirectDrawSurface_SetSurfaceDesc,
Main_DirectDrawSurface_SetPrivateData,
Main_DirectDrawSurface_GetPrivateData,
Main_DirectDrawSurface_FreePrivateData,
Main_DirectDrawSurface_GetUniquenessValue,
Main_DirectDrawSurface_ChangeUniquenessValue,
Main_DirectDrawSurface_SetPriority,
Main_DirectDrawSurface_GetPriority,
Main_DirectDrawSurface_SetLOD,
Main_DirectDrawSurface_GetLOD
};
/* Copyright 2000-2001 TransGaming Technologies Inc. */
#ifndef DDRAW_DSURFACE_HAL_H_INCLUDED
#define DDRAW_DSURFACE_HAL_H_INCLUDED
#define HAL_PRIV(surf) ((HAL_DirectDrawSurfaceImpl*)((surf)->private))
#define HAL_PRIV_VAR(name,surf) \
HAL_DirectDrawSurfaceImpl* name = HAL_PRIV(surf)
struct HAL_DirectDrawSurfaceImpl_Part
{
DWORD need_late;
LPVOID fb_addr;
DWORD fb_pitch, fb_vofs;
};
typedef struct
{
struct DIB_DirectDrawSurfaceImpl_Part dib;
struct User_DirectDrawSurfaceImpl_Part user;
struct HAL_DirectDrawSurfaceImpl_Part hal;
} HAL_DirectDrawSurfaceImpl;
HRESULT
HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
IDirectDrawImpl* pDD,
const DDSURFACEDESC2* pDDSD);
HRESULT
HAL_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
const DDSURFACEDESC2 *pDDSD,
LPDIRECTDRAWSURFACE7 *ppSurf,
IUnknown *pUnkOuter);
void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This);
void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
IDirectDrawPaletteImpl* pal);
void HAL_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
IDirectDrawPaletteImpl* pal,
DWORD dwStart, DWORD dwCount,
LPPALETTEENTRY palent);
HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
LPDIRECTDRAWSURFACE7* ppDup);
void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
IDirectDrawSurfaceImpl* back,
DWORD dwFlags);
void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This,
DWORD dwFlags);
HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This);
#endif
......@@ -2,7 +2,7 @@
*
* Copyright 1997-1999 Marcus Meissner
* Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
* Copyright 2000 TransGaming Technologies Inc.
* Copyright 2000-2001 TransGaming Technologies Inc.
*
* This file contains the (internal) driver registration functions,
* driver enumeration APIs and DirectDraw creation functions.
......@@ -479,15 +479,9 @@ BOOL WINAPI DDRAW_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
/* If we were sufficiently cool, DDraw drivers would just be COM
* objects, registered with a particular component category. */
DDRAW_HAL_Init(hInstDLL, fdwReason, lpv);
DDRAW_User_Init(hInstDLL, fdwReason, lpv);
#ifdef HAVE_LIBXXF86VM
DDRAW_XVidMode_Init(hInstDLL, fdwReason, lpv);
#endif
#ifdef HAVE_LIBXXF86DGA2
DDRAW_XF86DGA2_Init(hInstDLL, fdwReason, lpv);
#endif
if (DDRAW_num_drivers > 0)
DDRAW_default_driver = DDRAW_ChooseDefaultDriver();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment