Commit 169e36b9 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Implemented the XF86DGA2 driver for the ddraw HAL.

Entered some basic HAL device capabilities data. Added a GetDriverInfo handler.
parent 2a4c68bd
......@@ -7,6 +7,7 @@ EXTRALIBS = $(LIBTSX11) $(X_LIBS) $(XLIB)
IMPORTS = user32 gdi32 kernel32
C_SRCS = \
dga2.c \
x11ddraw.c \
x11drv_main.c \
xvidmode.c
......
/*
* DirectDraw DGA2 interface
*
* Copyright 2001 TransGaming Technologies, Inc.
*/
#include "config.h"
#ifdef HAVE_LIBXXF86DGA2
#include "ts_xlib.h"
#include "ts_xf86dga2.h"
#include "x11drv.h"
#include "x11ddraw.h"
#include "dga2.h"
#include "windef.h"
#include "wingdi.h"
#include "ddrawi.h"
#include "debugtools.h"
#include "options.h"
DEFAULT_DEBUG_CHANNEL(x11drv);
LPDDHALMODEINFO xf86dga2_modes;
unsigned xf86dga2_mode_count;
static XDGAMode* modes;
static int dga_event, dga_error;
static void convert_mode(XDGAMode *mode, LPDDHALMODEINFO info)
{
info->dwWidth = mode->viewportWidth;
info->dwHeight = mode->viewportHeight;
info->wRefreshRate = mode->verticalRefresh;
info->lPitch = mode->bytesPerScanline;
info->dwBPP = (mode->depth < 24) ? mode->depth : mode->bitsPerPixel;
info->wFlags = (mode->depth == 8) ? DDMODEINFO_PALETTIZED : 0;
info->dwRBitMask = mode->redMask;
info->dwGBitMask = mode->greenMask;
info->dwBBitMask = mode->blueMask;
info->dwAlphaBitMask = 0;
TRACE(" width=%ld, height=%ld, bpp=%ld, refresh=%d\n", \
info->dwWidth, info->dwHeight, info->dwBPP, info->wRefreshRate); \
}
void X11DRV_XF86DGA2_Init(void)
{
int nmodes, major, minor, i;
if (xf86dga2_modes) return; /* already initialized? */
/* if in desktop mode, don't use DGA */
if (X11DRV_GetXRootWindow() != DefaultRootWindow(display)) return;
if (!PROFILE_GetWineIniBool("x11drv", "UseDGA", 1)) return;
if (!TSXDGAQueryExtension(display, &dga_event, &dga_error)) return;
if (!TSXDGAQueryVersion(display, &major, &minor)) return;
if (major < 2) return; /* only bother with DGA 2+ */
/* test that it works */
if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
TRACE("disabling XF86DGA2 (insufficient permissions?)\n");
return;
}
TSXDGACloseFramebuffer(display, DefaultScreen(display));
/* retrieve modes */
modes = TSXDGAQueryModes(display, DefaultScreen(display), &nmodes);
if (!modes) return;
TRACE("DGA modes: count=%d\n", nmodes);
xf86dga2_mode_count = nmodes+1;
xf86dga2_modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DDHALMODEINFO) * (nmodes+1));
/* make dummy mode for exiting DGA */
memset(&xf86dga2_modes[0], 0, sizeof(xf86dga2_modes[0]));
/* convert modes to DDHALMODEINFO format */
for (i=0; i<nmodes; i++)
convert_mode(&modes[i], &xf86dga2_modes[i+1]);
TRACE("Enabling DGA\n");
}
void X11DRV_XF86DGA2_Cleanup(void)
{
if (modes) TSXFree(modes);
}
static XDGADevice *dga_dev;
static VIDMEM dga_mem = {
VIDMEM_ISRECTANGULAR | VIDMEM_ISHEAP
};
static DWORD PASCAL X11DRV_XF86DGA2_SetMode(LPDDHAL_SETMODEDATA data)
{
LPDDRAWI_DIRECTDRAW_LCL ddlocal = data->lpDD->lpExclusiveOwner;
DWORD vram;
data->ddRVal = DD_OK;
if (data->dwModeIndex) {
/* enter DGA */
XDGADevice *new_dev = NULL;
if (dga_dev || TSXDGAOpenFramebuffer(display, DefaultScreen(display)))
new_dev = TSXDGASetMode(display, DefaultScreen(display), modes[data->dwModeIndex-1].num);
if (new_dev) {
TSXDGASetViewport(display, DefaultScreen(display), 0, 0, XDGAFlipImmediate);
if (dga_dev) {
VirtualFree(dga_dev->data, 0, MEM_RELEASE);
TSXFree(dga_dev);
} else {
TSXDGASelectInput(display, DefaultScreen(display),
KeyPressMask|KeyReleaseMask|
ButtonPressMask|ButtonReleaseMask|
PointerMotionMask);
X11DRV_EVENT_SetDGAStatus(ddlocal->hWnd, dga_event);
X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_RELATIVE);
}
dga_dev = new_dev;
vram = dga_dev->mode.bytesPerScanline * dga_dev->mode.imageHeight;
VirtualAlloc(dga_dev->data, vram, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
dga_mem.fpStart = (FLATPTR)dga_dev->data;
dga_mem.u1.dwWidth = dga_dev->mode.bytesPerScanline;
dga_mem.u2.dwHeight = dga_dev->mode.imageHeight;
X11DRV_DDHAL_SwitchMode(data->dwModeIndex, dga_dev->data, &dga_mem);
X11DRV_DD_IsDirect = TRUE;
}
else {
ERR("failed\n");
if (!dga_dev) TSXDGACloseFramebuffer(display, DefaultScreen(display));
data->ddRVal = DDERR_GENERIC;
}
}
else if (dga_dev) {
/* exit DGA */
X11DRV_DD_IsDirect = FALSE;
X11DRV_DDHAL_SwitchMode(0, NULL, NULL);
TSXDGASetMode(display, DefaultScreen(display), 0);
VirtualFree(dga_dev->data, 0, MEM_RELEASE);
X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_ABSOLUTE);
X11DRV_EVENT_SetDGAStatus(0, -1);
TSXFree(dga_dev);
TSXDGACloseFramebuffer(display, DefaultScreen(display));
dga_dev = NULL;
}
return DDHAL_DRIVER_HANDLED;
}
static LPDDHAL_CREATESURFACE X11DRV_XF86DGA2_old_create_surface;
static DWORD PASCAL X11DRV_XF86DGA2_CreateSurface(LPDDHAL_CREATESURFACEDATA data)
{
LPDDRAWI_DDRAWSURFACE_LCL lcl = *data->lplpSList;
LPDDRAWI_DDRAWSURFACE_GBL gbl = lcl->lpGbl;
LPDDSURFACEDESC2 desc = (LPDDSURFACEDESC2)data->lpDDSurfaceDesc;
HRESULT hr = DDHAL_DRIVER_NOTHANDLED;
if (X11DRV_XF86DGA2_old_create_surface)
hr = X11DRV_XF86DGA2_old_create_surface(data);
if (desc->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER)) {
gbl->fpVidMem = 0; /* tell ddraw to allocate the memory */
hr = DDHAL_DRIVER_HANDLED;
}
return hr;
}
static DWORD PASCAL X11DRV_XF86DGA2_CreatePalette(LPDDHAL_CREATEPALETTEDATA data)
{
data->lpDDPalette->u1.dwReserved1 = TSXDGACreateColormap(display, DefaultScreen(display), dga_dev, AllocAll);
if (data->lpColorTable)
X11DRV_DDHAL_SetPalEntries(data->lpDDPalette->u1.dwReserved1, 0, 256,
data->lpColorTable);
data->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
static DWORD PASCAL X11DRV_XF86DGA2_Flip(LPDDHAL_FLIPDATA data)
{
if (data->lpSurfCurr == X11DRV_DD_Primary) {
DWORD ofs = data->lpSurfCurr->lpGbl->fpVidMem - dga_mem.fpStart;
TSXDGASetViewport(display, DefaultScreen(display),
(ofs % dga_dev->mode.bytesPerScanline)*8/dga_dev->mode.bitsPerPixel,
ofs / dga_dev->mode.bytesPerScanline,
XDGAFlipImmediate);
}
data->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
static DWORD PASCAL X11DRV_XF86DGA2_SetPalette(LPDDHAL_SETPALETTEDATA data)
{
if ((data->lpDDSurface == X11DRV_DD_Primary) &&
data->lpDDPalette && data->lpDDPalette->u1.dwReserved1) {
TSXDGAInstallColormap(display, DefaultScreen(display), data->lpDDPalette->u1.dwReserved1);
}
data->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
int X11DRV_XF86DGA2_CreateDriver(LPDDHALINFO info)
{
if (!xf86dga2_mode_count) return 0; /* no DGA */
info->dwNumModes = xf86dga2_mode_count;
info->lpModeInfo = xf86dga2_modes;
info->dwModeIndex = 0;
X11DRV_XF86DGA2_old_create_surface = info->lpDDCallbacks->CreateSurface;
info->lpDDCallbacks->SetMode = X11DRV_XF86DGA2_SetMode;
info->lpDDCallbacks->CreateSurface = X11DRV_XF86DGA2_CreateSurface;
info->lpDDCallbacks->CreatePalette = X11DRV_XF86DGA2_CreatePalette;
info->lpDDSurfaceCallbacks->Flip = X11DRV_XF86DGA2_Flip;
info->lpDDSurfaceCallbacks->SetPalette = X11DRV_XF86DGA2_SetPalette;
return TRUE;
}
#endif /* HAVE_LIBXXF86DGA2 */
/*
* DirectDraw HAL XVidMode interface
*
* Copyright 2001 TransGaming Technologies, Inc.
*/
#ifndef __WINE_DGA2_H
#define __WINE_DGA2_H
#include "config.h"
#ifdef HAVE_LIBXXF86DGA2
#include "ddrawi.h"
extern LPDDHALMODEINFO xf86dga2_modes;
extern unsigned xf86dga2_mode_count;
void X11DRV_XF86DGA2_Init(void);
void X11DRV_XF86DGA2_Cleanup(void);
int X11DRV_XF86DGA2_CreateDriver(LPDDHALINFO info);
#endif /* HAVE_LIBXXF86DGA2 */
#endif /* __WINE_DGA2_H */
......@@ -9,6 +9,7 @@
#include "x11drv.h"
#include "x11ddraw.h"
#include "xvidmode.h"
#include "dga2.h"
#include "windef.h"
#include "wingdi.h"
......@@ -20,6 +21,7 @@ DEFAULT_DEBUG_CHANNEL(x11drv);
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;
......@@ -48,6 +50,7 @@ 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");
......@@ -84,6 +87,7 @@ static DWORD PASCAL X11DRV_DDHAL_DestroySurface(LPDDHAL_DESTROYSURFACEDATA data)
{
if (data->lpDDSurface == X11DRV_DD_Primary) {
X11DRV_DD_Primary = NULL;
X11DRV_DD_PrimaryWnd = 0;
X11DRV_DD_PrimaryGbl = NULL;
SetPrimaryDIB(0);
X11DRV_DD_UserClass = 0;
......@@ -149,6 +153,28 @@ static DDHAL_DDPALETTECALLBACKS hal_ddpalcallbacks = {
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,
......@@ -157,18 +183,77 @@ static DDHALINFO hal_info = {
{ /* vmiData */
0 /* fpPrimary */
},
{ /* ddCaps */
sizeof(DDCORECAPS)
{ /* 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 */
NULL, /* GetDriverInfo */
X11DRV_DDHAL_GetDriverInfo,
0, /* dwModeIndex */
NULL, /* lpdwFourCC */
0, /* dwNumModes */
NULL, /* lpModeInfo */
DDHALINFO_ISPRIMARYDISPLAY | DDHALINFO_MODEXILLEGAL, /* dwFlags */
NULL, /* lpPDevice */
0 /* hInstance */
DDHALINFO_ISPRIMARYDISPLAY | DDHALINFO_MODEXILLEGAL | DDHALINFO_GETDRIVERINFOSET, /* dwFlags */
&x11device,
0, /* hInstance */
0, /* lpD3DGlobalDriverData */
0, /* lpD3DHALCallbacks */
NULL /* lpDDExeBufCallbacks */
};
static LPDDHALDDRAWFNS ddraw_fns;
......@@ -217,13 +302,16 @@ INT X11DRV_DCICommand(INT cbInput, LPVOID lpInData, LPVOID lpOutData)
/* FIXME: get x11drv's hInstance */
#ifdef HAVE_LIBXXF86DGA2
/*if (!X11DRV_XF86DGA2_CreateDriver(&hal_info))*/
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;
......@@ -233,7 +321,7 @@ INT X11DRV_DCICommand(INT cbInput, LPVOID lpInData, LPVOID lpOutData)
return 0;
}
void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr)
void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr, LPVIDMEM fb_mem)
{
LPDDHALMODEINFO info = &hal_info.lpModeInfo[dwModeIndex];
......@@ -249,6 +337,8 @@ void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr)
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();
}
......
......@@ -10,12 +10,23 @@
extern LPDDRAWI_DDRAWSURFACE_LCL X11DRV_DD_Primary;
extern LPDDRAWI_DDRAWSURFACE_GBL X11DRV_DD_PrimaryGbl;
extern HWND X11DRV_DD_PrimaryWnd;
extern HBITMAP X11DRV_DD_PrimaryDIB;
extern BOOL X11DRV_DD_IsDirect;
void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr);
void X11DRV_DDHAL_SwitchMode(DWORD dwModeIndex, LPVOID fb_addr, LPVIDMEM fb_mem);
void X11DRV_DDHAL_SetPalEntries(Colormap pal, DWORD dwBase, DWORD dwNumEntries,
LPPALETTEENTRY lpEntries);
typedef struct _X11DRIVERINFO {
const GUID * lpGuid;
DWORD dwSize;
LPVOID lpvData;
struct _X11DRIVERINFO*lpNext;
} X11DRIVERINFO,*LPX11DRIVERINFO;
typedef struct _X11DEVICE {
LPX11DRIVERINFO lpInfo;
} X11DEVICE,*LPX11DEVICE;
#endif /* __WINE_X11DDRAW_H */
......@@ -39,6 +39,7 @@ static int *ph_errno = &h_errno;
#include "wine_gl.h"
#include "x11drv.h"
#include "xvidmode.h"
#include "dga2.h"
DEFAULT_DEBUG_CHANNEL(x11drv);
......@@ -422,6 +423,14 @@ static void process_attach(void)
/* initialize XVidMode */
X11DRV_XF86VM_Init();
#endif
#ifdef HAVE_LIBXXF86DGA2
/* initialize DGA2 */
X11DRV_XF86DGA2_Init();
#endif
#ifdef HAVE_OPENGL
/* initialize GLX */
/*X11DRV_GLX_Init();*/
#endif
/* load display.dll */
LoadLibrary16( "display" );
......@@ -445,6 +454,14 @@ static void process_detach(void)
TSXChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent |
KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
#ifdef HAVE_OPENGL
/* cleanup GLX */
/*X11DRV_GLX_Cleanup();*/
#endif
#ifdef HAVE_LIBXXF86DGA2
/* cleanup DGA2 */
X11DRV_XF86DGA2_Cleanup();
#endif
#ifdef HAVE_LIBXXF86VM
/* cleanup XVidMode */
X11DRV_XF86VM_Cleanup();
......
......@@ -132,7 +132,7 @@ void X11DRV_XF86VM_SetExclusiveMode(int lock)
static DWORD PASCAL X11DRV_XF86VM_SetMode(LPDDHAL_SETMODEDATA data)
{
X11DRV_XF86VM_SetCurrentMode(data->dwModeIndex);
X11DRV_DDHAL_SwitchMode(data->dwModeIndex, NULL);
X11DRV_DDHAL_SwitchMode(data->dwModeIndex, NULL, NULL);
data->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
......@@ -143,7 +143,7 @@ int X11DRV_XF86VM_CreateDriver(LPDDHALINFO info)
info->dwNumModes = xf86vm_mode_count;
info->lpModeInfo = xf86vm_modes;
X11DRV_DDHAL_SwitchMode(X11DRV_XF86VM_GetCurrentMode(), NULL);
X11DRV_DDHAL_SwitchMode(X11DRV_XF86VM_GetCurrentMode(), NULL, NULL);
info->lpDDCallbacks->SetMode = X11DRV_XF86VM_SetMode;
return TRUE;
}
......
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