From 7d155d6706552faa643b3f38cc4c17aad178d892 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 17 Dec 2001 20:58:06 +0000 Subject: [PATCH] Changed DC hook and abort proc handling to avoid having to allocate thunks dynamically. --- dlls/gdi/gdi32.spec | 1 + dlls/gdi/printdrv.c | 34 ++++++++++++++++----- graphics/escape.c | 2 +- include/gdi.h | 3 +- include/wine/wingdi16.h | 7 +++-- objects/.cvsignore | 4 +++ objects/Makefile.in | 7 ++++- objects/dc.c | 66 +++++++++++++++++++++-------------------- windows/dce.c | 4 +-- 9 files changed, 79 insertions(+), 49 deletions(-) diff --git a/dlls/gdi/gdi32.spec b/dlls/gdi/gdi32.spec index 81c8aa203d7..3f15020929e 100644 --- a/dlls/gdi/gdi32.spec +++ b/dlls/gdi/gdi32.spec @@ -421,3 +421,4 @@ debug_channels (bitblt bitmap clipping dc ddraw driver enhmetafile font gdi # @ stdcall CreateMetaFile16(str) CreateMetaFile16 @ stdcall CloseMetaFile16(long) CloseMetaFile16 +@ stdcall SetDCHook(long ptr long) SetDCHook diff --git a/dlls/gdi/printdrv.c b/dlls/gdi/printdrv.c index 9402fa65db3..acf9eb25ada 100644 --- a/dlls/gdi/printdrv.c +++ b/dlls/gdi/printdrv.c @@ -17,6 +17,7 @@ #include #include #include "winbase.h" +#include "winuser.h" #include "wine/winbase16.h" #include "wine/wingdi16.h" #include "winspool.h" @@ -24,7 +25,6 @@ #include "winreg.h" #include "debugtools.h" #include "gdi.h" -#include "callback.h" #include "heap.h" #include "file.h" @@ -250,14 +250,32 @@ extern WORD CALLBACK PRTDRV_CallTo16_word_ww(FARPROC16,WORD,WORD); /* ### stop build ### */ /********************************************************************** - * SetAbortProc (GDI.381) - * + * call_abort_proc16 */ -INT16 WINAPI SetAbortProc16(HDC16 hdc, SEGPTR abrtprc) +static BOOL CALLBACK call_abort_proc16( HDC hdc, INT code ) { - ABORTPROC proc32 = (ABORTPROC)THUNK_Alloc((FARPROC16)abrtprc, - (RELAY)PRTDRV_CallTo16_word_ww); - return SetAbortProc(hdc, proc32); + ABORTPROC16 proc16; + DC *dc = DC_GetDCPtr( hdc ); + + if (!dc) return FALSE; + proc16 = dc->pAbortProc16; + GDI_ReleaseObj( hdc ); + if (proc16) return PRTDRV_CallTo16_word_ww( (FARPROC16)proc16, hdc, code ); + return TRUE; +} + + +/********************************************************************** + * SetAbortProc (GDI.381) + */ +INT16 WINAPI SetAbortProc16(HDC16 hdc, ABORTPROC16 abrtprc) +{ + DC *dc = DC_GetDCPtr( hdc ); + + if (!dc) return FALSE; + dc->pAbortProc16 = abrtprc; + GDI_ReleaseObj( hdc ); + return SetAbortProc( hdc, call_abort_proc16 ); } /********************************************************************** @@ -268,7 +286,7 @@ INT WINAPI SetAbortProc(HDC hdc, ABORTPROC abrtprc) { DC *dc = DC_GetDCPtr( hdc ); - if(dc->pAbortProc) THUNK_Free((FARPROC)dc->pAbortProc); + if (!dc) return FALSE; dc->pAbortProc = abrtprc; GDI_ReleaseObj( hdc ); return TRUE; diff --git a/graphics/escape.c b/graphics/escape.c index 75b28c8ffc9..0271ae2c016 100644 --- a/graphics/escape.c +++ b/graphics/escape.c @@ -103,7 +103,7 @@ INT16 WINAPI Escape16( HDC16 hdc, INT16 escape, INT16 in_count, /* Escape(hdc,SETABORTPROC,ABORTPROC,NULL); */ case SETABORTPROC: - return SetAbortProc16( hdc, in_data ); + return SetAbortProc16( hdc, (ABORTPROC16)in_data ); /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFO16); * lpvOutData is actually a pointer to the DocInfo structure and used as diff --git a/include/gdi.h b/include/gdi.h index bb0eec13323..f0c9f680de1 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -46,8 +46,6 @@ typedef struct tagGDIOBJHDR } GDIOBJHDR; -typedef BOOL16 CALLBACK (*DCHOOKPROC)(HDC16,WORD,DWORD,LPARAM); - typedef struct tagGdiFont *GdiFont; typedef struct tagDC @@ -109,6 +107,7 @@ typedef struct tagDC INT DCOrgX; /* DC origin */ INT DCOrgY; ABORTPROC pAbortProc; /* AbortProc for Printing */ + ABORTPROC16 pAbortProc16; INT CursPosX; /* Current position */ INT CursPosY; INT ArcDirection; diff --git a/include/wine/wingdi16.h b/include/wine/wingdi16.h index 157801f2ad0..cbd0b83ade9 100644 --- a/include/wine/wingdi16.h +++ b/include/wine/wingdi16.h @@ -216,11 +216,13 @@ typedef struct FONTSIGNATURE ntmFontSig; } NEWTEXTMETRICEX16,*LPNEWTEXTMETRICEX16; +typedef BOOL16 CALLBACK (*DCHOOKPROC)(HDC16,WORD,DWORD,LPARAM); typedef INT16 CALLBACK (*FONTENUMPROC16)(SEGPTR,SEGPTR,UINT16,LPARAM); typedef INT16 CALLBACK (*FONTENUMPROCEX16)(SEGPTR,SEGPTR,UINT16,LPARAM); typedef VOID CALLBACK (*LINEDDAPROC16)(INT16,INT16,LPARAM); typedef INT16 CALLBACK (*GOBJENUMPROC16)(SEGPTR,LPARAM); + typedef struct { UINT16 gmBlackBoxX; @@ -505,7 +507,7 @@ BOOL16 WINAPI SelectClipPath16(HDC16,INT16); INT16 WINAPI SelectClipRgn16(HDC16,HRGN16); HGDIOBJ16 WINAPI SelectObject16(HDC16,HGDIOBJ16); INT16 WINAPI SelectVisRgn16(HDC16,HRGN16); -INT16 WINAPI SetAbortProc16(HDC16,SEGPTR); +INT16 WINAPI SetAbortProc16(HDC16,ABORTPROC16); INT16 WINAPI SetArcDirection16(HDC16,INT16); LONG WINAPI SetBitmapBits16(HBITMAP16,LONG,LPCVOID); DWORD WINAPI SetBitmapDimension16(HBITMAP16,INT16,INT16); @@ -514,7 +516,8 @@ COLORREF WINAPI SetBkColor16(HDC16,COLORREF); INT16 WINAPI SetBkMode16(HDC16,INT16); UINT16 WINAPI SetBoundsRect16(HDC16,const RECT16*,UINT16); DWORD WINAPI SetBrushOrg16(HDC16,INT16,INT16); -BOOL16 WINAPI SetDCHook(HDC16,FARPROC16,DWORD); +BOOL WINAPI SetDCHook(HDC,DCHOOKPROC,DWORD); +BOOL16 WINAPI SetDCHook16(HDC16,FARPROC16,DWORD); DWORD WINAPI SetDCOrg16(HDC16,INT16,INT16); VOID WINAPI SetDCState16(HDC16,HDC16); UINT16 WINAPI SetDIBColorTable16(HDC16,UINT16,UINT16,RGBQUAD*); diff --git a/objects/.cvsignore b/objects/.cvsignore index 6c4db5dab95..ce0b3286392 100644 --- a/objects/.cvsignore +++ b/objects/.cvsignore @@ -1,2 +1,6 @@ Makefile dc.glue.c +font.glue.c +gdiobj.glue.c +linedda.glue.c +metafile.glue.c diff --git a/objects/Makefile.in b/objects/Makefile.in index a198d091df1..9a77c2496ec 100644 --- a/objects/Makefile.in +++ b/objects/Makefile.in @@ -23,7 +23,12 @@ C_SRCS = \ region.c \ text.c -GLUE = dc.c +GLUE = \ + dc.c \ + font.c \ + gdiobj.c \ + linedda.c \ + metafile.c all: $(MODULE).o diff --git a/objects/dc.c b/objects/dc.c index 24b16ef6dc8..b06de93473e 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -13,7 +13,6 @@ #include "heap.h" #include "debugtools.h" #include "font.h" -#include "callback.h" #include "winerror.h" #include "windef.h" #include "wingdi.h" @@ -21,6 +20,9 @@ DEFAULT_DEBUG_CHANNEL(dc); +/* ### start build ### */ +extern WORD CALLBACK GDI_CallTo16_word_wwll(FARPROC16,WORD,WORD,LONG,LONG); +/* ### stop build ### */ /*********************************************************************** * DC_AllocDC @@ -773,8 +775,6 @@ BOOL WINAPI DeleteDC( HDC hdc ) if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc->hGCClipRgn) DeleteObject( dc->hGCClipRgn ); - if (dc->pAbortProc) THUNK_Free( (FARPROC)dc->pAbortProc ); - if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk ); if (dc->gdiFont) WineEngDecRefFont( dc->gdiFont ); PATH_DestroyGdiPath(&dc->path); @@ -1180,44 +1180,46 @@ BOOL WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1, } +/*********************************************************************** + * SetDCHook (GDI32.@) + * + * Note: this doesn't exist in Win32, we add it here because user32 needs it. + */ +BOOL WINAPI SetDCHook( HDC hdc, DCHOOKPROC hookProc, DWORD dwHookData ) +{ + DC *dc = DC_GetDCPtr( hdc ); + + if (!dc) return FALSE; + dc->dwHookData = dwHookData; + dc->hookThunk = hookProc; + GDI_ReleaseObj( hdc ); + return TRUE; +} + + +/* relay function to call the 16-bit DC hook proc */ +static BOOL16 WINAPI call_dc_hook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam ) +{ + FARPROC16 proc = NULL; + DC *dc = DC_GetDCPtr( hdc ); + if (!dc) return FALSE; + proc = dc->hookProc; + GDI_ReleaseObj( hdc ); + if (!proc) return FALSE; + return GDI_CallTo16_word_wwll( proc, hdc, code, data, lParam ); +} + /*********************************************************************** * 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 ) +BOOL16 WINAPI SetDCHook16( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData ) { DC *dc = DC_GetDCPtr( hdc ); 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_ReleaseObj( hdc ); - return TRUE; + return SetDCHook( hdc, call_dc_hook16, dwHookData ); } diff --git a/windows/dce.c b/windows/dce.c index 49d9ff4eb16..4f27e65dc44 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -68,7 +68,6 @@ static void DCE_DumpCache(void) */ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type ) { - FARPROC16 hookProc; DCE * dce; if (!(dce = HeapAlloc( GetProcessHeap(), 0, sizeof(DCE) ))) return NULL; @@ -81,8 +80,7 @@ DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type ) /* store DCE handle in DC hook data field */ - hookProc = GetProcAddress16( GetModuleHandle16("USER"), (LPCSTR)362 ); - SetDCHook( dce->hDC, hookProc, (DWORD)dce ); + SetDCHook( dce->hDC, DCHook16, (DWORD)dce ); dce->hwndCurrent = WIN_GetFullHandle( hWnd ); dce->hClipRgn = 0;