From f86aab84ba6a2ae13d1006a33d61c5a7b6be34d8 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 20 Sep 1999 18:47:14 +0000 Subject: [PATCH] DC hook proc thunk management simplified. --- if1632/gdi.spec | 4 ++-- include/gdi.h | 12 ++++++++---- objects/.cvsignore | 1 + objects/Makefile.in | 2 ++ objects/clipping.c | 4 ++-- objects/dc.c | 33 +++++++++++++++++++++++++++------ windows/dce.c | 6 +++++- 7 files changed, 47 insertions(+), 15 deletions(-) diff --git a/if1632/gdi.spec b/if1632/gdi.spec index 7c09bea6944..9bfee33599d 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -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 diff --git a/include/gdi.h b/include/gdi.h index 0c9f295ef1e..da3a5781ff4 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -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; diff --git a/objects/.cvsignore b/objects/.cvsignore index f3c7a7c5da6..6c4db5dab95 100644 --- a/objects/.cvsignore +++ b/objects/.cvsignore @@ -1 +1,2 @@ Makefile +dc.glue.c diff --git a/objects/Makefile.in b/objects/Makefile.in index 02a4311dfe9..1a9202b804d 100644 --- a/objects/Makefile.in +++ b/objects/Makefile.in @@ -24,6 +24,8 @@ C_SRCS = \ region.c \ text.c +GLUE = dc.c + all: $(MODULE).o @MAKE_RULES@ diff --git a/objects/clipping.c b/objects/clipping.c index 841ad8a36cd..0484e3ebaad 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -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) diff --git a/objects/dc.c b/objects/dc.c index 7d074bc6afd..1dfb530aab1 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -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; } diff --git a/windows/dce.c b/windows/dce.c index e825596db43..2e24db52a68 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -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;