|
|
/*==========================================================================
* * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved. * * File: dci.c * Content: 16-bit DCI code * This was cut from DCIMAN to provide basic DCI services when * we don't have DirectDraw drivers * History: * Date By Reason * ==== == ====== * 19-jun-95 craige split out of DCIMAN.C, tweaked * 31-jul-95 craige added DCIIsBanked * 13-may-96 colinmc Bug 21192: DCI HDC being freed erroneously due to * process termination * ***************************************************************************/ #define _INC_DCIDDI
#include "ddraw16.h"
#undef _INC_DCIDDI
UINT wFlatSel; LPVOID pWin16Lock;
#undef WINAPI
#define WINAPI FAR PASCAL _loadds
#include "dciman.h"
static char szDISPLAY[] = "display";
/*
* define some types so we dont go insane, these structures are exactly the * same (dont need repacked) but it is nice to have different types * so we can read the code */ typedef LPDCISURFACEINFO LPDCISURFACEINFO16; typedef LPDCISURFACEINFO LPDCISURFACEINFO32;
typedef LPDCIOFFSCREEN LPDCIOFFSCREEN16; typedef LPDCIOFFSCREEN LPDCIOFFSCREEN32;
typedef LPDCIOVERLAY LPDCIOVERLAY16; typedef LPDCIOVERLAY LPDCIOVERLAY32;
#define PDCI16(pdci32) (LPDCISURFACEINFO16)(((LPDCISURFACEINFO32)(pdci32))->dwReserved2)
extern HINSTANCE hInstApp;
/*
* DCIOpenProvider * * only open the DISPLAY driver. */ HDC WINAPI DCIOpenProvider(void) { HDC hdc; UINT u;
u = SetErrorMode(SEM_NOOPENFILEERRORBOX); hdc = CreateDC( szDISPLAY, NULL, NULL, NULL ); SetErrorMode(u);
/*
* now check for the Escape */ if (hdc) { u = DCICOMMAND; if( Escape(hdc, QUERYESCSUPPORT,sizeof(u),(LPCSTR)&u,NULL) == 0 ) { /*
* driver does not do escape, punt it. */ DeleteDC(hdc); hdc = NULL; } }
if (hdc) { /*
* Reparent it to prevent it going away when the app. dies. */ SetObjectOwner(hdc, hInstApp); }
return hdc;
} /* DCIOpenProvider */
/*
* DCICloseProvider */ void WINAPI DCICloseProvider(HDC hdc) { if( hdc ) { DeleteDC(hdc); }
} /* DCICloseProvider */
/*
* dciSendCommand */ static int dciSendCommand( HDC hdc, VOID FAR *pcmd, int nSize, VOID FAR * FAR * lplpOut ) { if( lplpOut ) { *lplpOut = NULL; }
return Escape( hdc, DCICOMMAND, nSize, (LPCSTR)pcmd, lplpOut );
} /* dciSendCommand */
/*
* DCICreatePrimary */ int WINAPI DCICreatePrimary(HDC hdc, LPDCISURFACEINFO FAR *lplpSurface) { DCICREATEINPUT ci; DCIRVAL err; HDC hdcScreen;
ci.cmd.dwCommand = (DWORD)DCICREATEPRIMARYSURFACE; ci.cmd.dwParam1 = 0; ci.cmd.dwParam2 = 0; ci.cmd.dwVersion = (DWORD)DCI_VERSION; ci.cmd.dwReserved = 0; ci.dwDCICaps = DCI_PRIMARY | DCI_VISIBLE;
DPF( 4, "DCICreatePrimary" );
/*
* for the primary surface we always use the display driver over * a external provider. */ hdcScreen = GetDC( NULL ); err = dciSendCommand(hdcScreen, &ci, sizeof(DCICREATEINPUT), lplpSurface); ReleaseDC( NULL, hdcScreen );
if( err != DCI_OK || *lplpSurface == NULL ) { err = dciSendCommand(hdc, &ci, sizeof(DCICREATEINPUT), lplpSurface); }
return err;
} /* DCICreatePrimary */
/*
* DCIDestroy */ void WINAPI DCIDestroy(LPDCISURFACEINFO pdci) { if( (DWORD)pdci->DestroySurface == 0xFFFFFFFF ) { pdci = PDCI16(pdci); }
if( pdci->DestroySurface != NULL ) { pdci->DestroySurface(pdci); }
} /* DCIDestroy */
/*
* DCIEndAccess */ void WINAPI DCIEndAccess( LPDCISURFACEINFO pdci ) { if( (DWORD)pdci->DestroySurface == 0xFFFFFFFF) { pdci = PDCI16( pdci ); }
if( pdci->EndAccess != NULL ) { pdci->EndAccess( pdci ); }
LeaveSysLevel( pWin16Lock );
} /* DCIEndAccess */
/*
* dciSurface16to32 * * convert a DCI16 bit structure to a 32bit structure */ static int dciSurface16to32( LPDCISURFACEINFO16 pdci16, LPDCISURFACEINFO32 pdci32 ) { DPF( 4, "dciSurface16to32" ); if( pdci16 == NULL ) { DPF( 1, "pdci16=NULL" ); return DCI_FAIL_GENERIC; }
if( pdci32 == NULL ) { DPF( 1, "pdci32=NULL" ); return DCI_FAIL_GENERIC; }
if (pdci16->dwSize < sizeof(DCISURFACEINFO)) { //
// invalid DCISURCACEINFO.
//
pdci16->dwSize = sizeof(DCISURFACEINFO); }
if (pdci16->dwSize > sizeof(DCIOFFSCREEN)) { //
// invalid DCISURCACEINFO.
//
return DCI_FAIL_GENERIC; }
_fmemcpy(pdci32, pdci16, (UINT) pdci32->dwSize); // copy the info.
pdci32->dwReserved2 = (DWORD)(LPVOID)pdci16;
if (pdci16->BeginAccess != NULL) { (DWORD)pdci32->BeginAccess = 0xFFFFFFFF; // you cant call these, but they
(DWORD)pdci32->EndAccess = 0xFFFFFFFF; // must be non-zero
}
(DWORD)pdci32->DestroySurface = 0xFFFFFFFF; // must be non-zero
/*
* now we need to convert the pointer to a 0:32 (ie flat pointer) * we can only do this if the provider has *not* set the 1632_ACCESS bit. * * if the 1632_ACCESS bit is set, call VFlatD to see if we can * enable linear access mode. */ if( pdci16->wSelSurface != 0 ) { if( pdci16->dwDCICaps & DCI_1632_ACCESS ) { if( pdci16->wSelSurface == VFDQuerySel()) { if( (wFlatSel == 0) && VFDBeginLinearAccess() ) { wFlatSel = AllocSelector(SELECTOROF((LPVOID)&pdci16)); SetSelectorBase(wFlatSel, 0); SetSelLimit(wFlatSel, 0xFFFFFFFF); }
if (wFlatSel != 0) { pdci32->dwOffSurface += VFDQueryBase(); pdci32->wSelSurface = wFlatSel; // 0;
pdci32->dwDCICaps &= ~DCI_1632_ACCESS; } } } else { /*
* convert the 16:32 pointer to a flat pointer. */ pdci32->dwOffSurface += GetSelectorBase(pdci16->wSelSurface); pdci32->wSelSurface = 0; pdci32->wReserved = 0; } } else { // selector is zero so the address is flat already
// clear DCI_1632_ACCESS for broken providers?
pdci32->dwDCICaps &= ~DCI_1632_ACCESS; // !!!needed?
}
return DCI_OK;
} /* dciSurface16to32 */
/*
* DCIBeginAccess */ DCIRVAL WINAPI DCIBeginAccess( LPDCISURFACEINFO pdci, int x, int y, int dx, int dy ) { int err; RECT rc;
rc.left = x; rc.top = y; rc.right = x+dx; rc.bottom = y+dy;
if( (DWORD)pdci->DestroySurface == 0xFFFFFFFF ) { LPDCISURFACEINFO16 pdci16 = PDCI16(pdci);
if( pdci16->BeginAccess != NULL ) { err = pdci16->BeginAccess( pdci16, &rc ); } else { err = DCI_OK; }
if( err > 0 ) { err = dciSurface16to32(pdci16, pdci); } } else { if( pdci->BeginAccess != NULL ) { err = pdci->BeginAccess(pdci, &rc); } else { err = DCI_OK; } }
if( err >= 0 ) { EnterSysLevel( pWin16Lock ); } return err;
} /* DCIBeginAccess */
/*
* DCICreatePrimary */ int WINAPI DCICreatePrimary32(HDC hdc, LPDCISURFACEINFO32 pdci32) { LPDCISURFACEINFO pdci16; int rc;
DPF( 4, "DCICreatePrimary32" );
rc = DCICreatePrimary(hdc, &pdci16);
if( rc == DCI_OK ) { rc = dciSurface16to32( pdci16, pdci32 ); }
return rc;
} /* DCICreatePrimary */
/*
* DCIIsBanked */ BOOL DDAPI DCIIsBanked( HDC hdc ) { LPDCISURFACEINFO pdci16; int rc;
rc = DCICreatePrimary(hdc, &pdci16); if( rc == DCI_OK ) { if( !IsBadReadPtr( pdci16, sizeof( *pdci16 ) ) ) { if( pdci16->dwDCICaps & DCI_1632_ACCESS ) { rc = TRUE; } else { rc = FALSE; } DCIDestroy( pdci16 ); } else { rc = FALSE; } return rc; } return FALSE;
} /* DCIIsBanked */
#pragma optimize("", off)
void SetSelLimit(UINT sel, DWORD limit) { if( limit >= 1024*1024l ) { limit = ((limit+4096) & ~4095) - 1; }
_asm { mov ax,0008h ; DPMI set limit mov bx,sel mov dx,word ptr limit[0] mov cx,word ptr limit[2] int 31h } } /* SetSelLimit */ #pragma optimize("", on)
|