DC hook proc thunk management simplified.

This commit is contained in:
Ulrich Weigand 1999-09-20 18:47:14 +00:00 committed by Alexandre Julliard
parent 974fd10c69
commit f86aab84ba
7 changed files with 47 additions and 15 deletions

View File

@ -157,8 +157,8 @@ file gdi.exe
180 pascal16 SetDCState(word word) SetDCState16
181 pascal16 RectInRegionOld(word ptr) RectInRegion16
188 stub GetTextExtentEx
190 pascal16 SetDCHook(word segptr long) THUNK_SetDCHook
191 pascal GetDCHook(word ptr) THUNK_GetDCHook
190 pascal16 SetDCHook(word segptr long) SetDCHook
191 pascal GetDCHook(word ptr) GetDCHook
192 pascal16 SetHookFlags(word word) SetHookFlags16
193 pascal16 SetBoundsRect(word ptr word) SetBoundsRect16
194 pascal16 GetBoundsRect(word ptr word) GetBoundsRect16

View File

@ -137,15 +137,19 @@ typedef struct
BOOL vport2WorldValid; /* Is xformVport2World valid? */
} WIN_DC_INFO;
typedef BOOL16 (CALLBACK *DCHOOKPROC)(HDC16,WORD,DWORD,LPARAM);
typedef struct tagDC
{
GDIOBJHDR header;
GDIOBJHDR header;
HDC hSelf; /* Handle to this DC */
const struct tagDC_FUNCS *funcs; /* DC function table */
void *physDev; /* Physical device (driver-specific) */
void *physDev; /* Physical device (driver-specific) */
INT saveLevel;
DWORD dwHookData;
FARPROC16 hookProc;
DWORD dwHookData;
FARPROC16 hookProc; /* the original SEGPTR ... */
DCHOOKPROC hookThunk; /* ... and the thunk to call it */
INT wndOrgX; /* Window origin */
INT wndOrgY;

View File

@ -1 +1,2 @@
Makefile
dc.glue.c

View File

@ -24,6 +24,8 @@ C_SRCS = \
region.c \
text.c
GLUE = dc.c
all: $(MODULE).o
@MAKE_RULES@

View File

@ -15,8 +15,8 @@ DECLARE_DEBUG_CHANNEL(region)
#define UPDATE_DIRTY_DC(dc) \
do { \
if ((dc)->hookProc && !((dc)->w.flags & (DC_SAVED | DC_MEMORY))) \
(dc)->hookProc( (dc)->hSelf, DCHC_INVALIDVISRGN, (dc)->dwHookData, 0 ); \
if ((dc)->hookThunk && !((dc)->w.flags & (DC_SAVED | DC_MEMORY))) \
(dc)->hookThunk( (dc)->hSelf, DCHC_INVALIDVISRGN, (dc)->dwHookData, 0 ); \
} while(0)

View File

@ -99,6 +99,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
dc->saveLevel = 0;
dc->dwHookData = 0L;
dc->hookProc = NULL;
dc->hookThunk = NULL;
dc->wndOrgX = 0;
dc->wndOrgY = 0;
dc->wndExtX = 1;
@ -680,8 +681,8 @@ BOOL WINAPI DeleteDC( HDC hdc )
TRACE("%04x\n", hdc );
/* Call hook procedure to check whether is it OK to delete this DC */
if ( dc->hookProc && !(dc->w.flags & (DC_SAVED | DC_MEMORY))
&& dc->hookProc( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ) == FALSE )
if ( dc->hookThunk && !(dc->w.flags & (DC_SAVED | DC_MEMORY))
&& dc->hookThunk( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ) == FALSE )
{
GDI_HEAP_UNLOCK( hdc );
return FALSE;
@ -710,6 +711,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (dc->w.hVisRgn) DeleteObject( dc->w.hVisRgn );
if (dc->w.hGCClipRgn) DeleteObject( dc->w.hGCClipRgn );
if (dc->w.pAbortProc) THUNK_Free( (FARPROC)dc->w.pAbortProc );
if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk );
PATH_DestroyGdiPath(&dc->w.path);
return GDI_FreeObject( hdc );
@ -1201,16 +1203,35 @@ BOOL WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1,
/***********************************************************************
* SetDCHook (GDI.190)
*/
/* ### start build ### */
extern WORD CALLBACK GDI_CallTo16_word_wwll(FARPROC16,WORD,WORD,LONG,LONG);
/* ### stop build ### */
BOOL16 WINAPI SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
{
DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
TRACE("hookProc %08x, default is %08x\n",
(UINT)hookProc, (UINT)DCHook16 );
if (!dc) return FALSE;
/*
* Note: We store the original SEGPTR 'hookProc' as we need to be
* able to return it verbatim in GetDCHook,
*
* On the other hand, we still call THUNK_Alloc and store the
* 32-bit thunk into another DC member, because THUNK_Alloc
* recognizes the (typical) case that the 'hookProc' is indeed
* the 16-bit API entry point of a built-in routine (e.g. DCHook16)
*
* We could perform that test every time the hook is about to
* be called (or else we could live with the 32->16->32 detour),
* but this way is the most efficient ...
*/
dc->hookProc = hookProc;
dc->dwHookData = dwHookData;
THUNK_Free( (FARPROC)dc->hookThunk );
dc->hookThunk = (DCHOOKPROC)
THUNK_Alloc( hookProc, (RELAY)GDI_CallTo16_word_wwll );
GDI_HEAP_UNLOCK( hdc );
return TRUE;
}

View File

@ -27,7 +27,9 @@
#include "region.h"
#include "heap.h"
#include "local.h"
#include "module.h"
#include "debugtools.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
DEFAULT_DEBUG_CHANNEL(dc)
@ -71,6 +73,7 @@ static void DCE_DumpCache(void)
*/
DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
{
FARPROC16 hookProc;
DCE * dce;
WND* wnd;
@ -85,7 +88,8 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
/* store DCE handle in DC hook data field */
SetDCHook( dce->hDC, (FARPROC16)DCHook16, (DWORD)dce );
hookProc = (FARPROC16)NE_GetEntryPoint( GetModuleHandle16("USER"), 362 );
SetDCHook( dce->hDC, hookProc, (DWORD)dce );
dce->hwndCurrent = hWnd;
dce->hClipRgn = 0;