hal.c

来自「Wine-20031016」· C语言 代码 · 共 587 行 · 第 1/2 页

C
587
字号
/*	DirectDraw HAL driver * * 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 <assert.h>#include <stdarg.h>#include <stdlib.h>#include "wine/debug.h"#include "windef.h"#include "winbase.h"#include "wingdi.h"#include "ddraw.h"#include "ddrawi.h"#include "d3dhal.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"WINE_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 WINAPI 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;    dd_gbl.dwNumFourCC	         = lpDDHalInfo->ddCaps.dwNumFourCCCodes;    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;    }    if( opengl_initialized &&            (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) ) {        /*GL_DirectDraw_Init(&dd_gbl);*/    }    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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?