diff --git a/include/gdi.h b/include/gdi.h index 18a5ed36a4e..704c094d1b4 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -527,6 +527,7 @@ extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj ); extern BOOL GDI_FreeObject( HGDIOBJ, void *obj ); extern void *GDI_GetObjPtr( HGDIOBJ, WORD ); extern void GDI_ReleaseObj( HGDIOBJ ); +extern void GDI_CheckNotLock(void); extern const DC_FUNCTIONS *DRIVER_load_driver( LPCSTR name ); extern const DC_FUNCTIONS *DRIVER_get_driver( const DC_FUNCTIONS *funcs ); diff --git a/objects/dc.c b/objects/dc.c index 56b353d66da..2521e0a0eab 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -551,6 +551,8 @@ HDC WINAPI CreateDCA( LPCSTR driver, LPCSTR device, LPCSTR output, const DC_FUNCTIONS *funcs; char buf[300]; + GDI_CheckNotLock(); + if (!device || !DRIVER_GetDriverName( device, buf, sizeof(buf) )) strcpy(buf, driver); @@ -654,23 +656,24 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) DC *dc, *origDC; const DC_FUNCTIONS *funcs; - if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = DRIVER_get_driver(origDC->funcs); + GDI_CheckNotLock(); + + if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) + { + funcs = origDC->funcs; + GDI_ReleaseObj( hdc ); /* can't hold the lock while loading the driver */ + funcs = DRIVER_get_driver( funcs ); + } else funcs = DRIVER_load_driver( "DISPLAY" ); - if (!funcs) - { - if (origDC) GDI_ReleaseObj( hdc ); - return 0; - } + if (!funcs) return 0; if (!(dc = DC_AllocDC( funcs ))) { DRIVER_release_driver( funcs ); - if (origDC) GDI_ReleaseObj( hdc ); return 0; } - TRACE("(%04x): returning %04x\n", hdc, dc->hSelf ); @@ -681,16 +684,15 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) /* Copy the driver-specific physical device info into * the new DC. The driver may use this read-only info * while creating the compatible DC below. */ - if (origDC) - dc->physDev = origDC->physDev; + if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) dc->physDev = origDC->physDev; if (dc->funcs->pCreateDC && !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL )) { WARN("creation aborted by device\n"); GDI_FreeObject( dc->hSelf, dc ); - DRIVER_release_driver( funcs ); if (origDC) GDI_ReleaseObj( hdc ); + DRIVER_release_driver( funcs ); return 0; } @@ -715,11 +717,15 @@ BOOL16 WINAPI DeleteDC16( HDC16 hdc ) */ BOOL WINAPI DeleteDC( HDC hdc ) { - DC * dc = GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) return FALSE; + const DC_FUNCTIONS *funcs = NULL; + DC * dc; TRACE("%04x\n", hdc ); + GDI_CheckNotLock(); + + if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; + /* Call hook procedure to check whether is it OK to delete this DC */ if (dc->hookThunk && !(dc->flags & (DC_SAVED | DC_MEMORY))) { @@ -749,8 +755,8 @@ BOOL WINAPI DeleteDC( HDC hdc ) SelectObject( hdc, GetStockObject(BLACK_PEN) ); SelectObject( hdc, GetStockObject(WHITE_BRUSH) ); SelectObject( hdc, GetStockObject(SYSTEM_FONT) ); + funcs = dc->funcs; if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc); - DRIVER_release_driver( dc->funcs ); } if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); @@ -760,7 +766,9 @@ BOOL WINAPI DeleteDC( HDC hdc ) if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk ); PATH_DestroyGdiPath(&dc->path); - return GDI_FreeObject( hdc, dc ); + GDI_FreeObject( hdc, dc ); + if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */ + return TRUE; } diff --git a/objects/dib.c b/objects/dib.c index 9d36870f931..fe56472b2ef 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -160,14 +160,18 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, if(!dc) return FALSE; if(dc->funcs->pStretchDIBits) - heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst, - heightDst, xSrc, ySrc, widthSrc, - heightSrc, bits, info, wUsage, - dwRop); - else { /* use StretchBlt */ + { + heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst, + heightDst, xSrc, ySrc, widthSrc, + heightSrc, bits, info, wUsage, dwRop); + GDI_ReleaseObj( hdc ); + } + else /* use StretchBlt */ + { HBITMAP hBitmap, hOldBitmap; HDC hdcMem; + GDI_ReleaseObj( hdc ); hdcMem = CreateCompatibleDC( hdc ); if (info->bmiHeader.biCompression == BI_RLE4 || info->bmiHeader.biCompression == BI_RLE8) { @@ -212,7 +216,6 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, DeleteDC( hdcMem ); DeleteObject( hBitmap ); } - GDI_ReleaseObj( hdc ); return heightSrc; } diff --git a/objects/gdiobj.c b/objects/gdiobj.c index 1bd60ecaf33..e05c890483c 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -271,6 +271,9 @@ static void ReadFontInformation( RegCloseKey(hkey); } +static int stock_font_height[STOCK_LAST+1]; +static int stock_font_width[STOCK_LAST+1]; + /*********************************************************************** * Because the stock fonts have their structure initialized with * a height of 0 to keep them independent of mapping mode, simply @@ -278,20 +281,26 @@ static void ReadFontInformation( * These "FixStockFontSizeXXX()" methods will get the correct * size for the fonts. */ -static void GetFontMetrics(HFONT handle, LPTEXTMETRICA lptm) +static void init_stock_fonts_metrics(void) { - HDC hdc; - HFONT hOldFont; + int i; + TEXTMETRICA tm; + HDC hdc; + static int done; - hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); + if (done) return; + done = 1; + hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); - hOldFont = (HFONT)SelectObject(hdc, handle); - - GetTextMetricsA(hdc, lptm); - - SelectObject(hdc, hOldFont); - - DeleteDC(hdc); + for (i = 0; i <= STOCK_LAST; i++) + { + if (GetObjectType( GetStockObject(i) ) != OBJ_FONT) continue; + SelectObject( hdc, GetStockObject(i) ); + GetTextMetricsA( hdc, &tm ); + stock_font_height[i] = tm.tmHeight; + stock_font_width[i] = tm.tmAveCharWidth; + } + DeleteDC(hdc); } static inline void FixStockFontSize16( @@ -299,7 +308,6 @@ static inline void FixStockFontSize16( INT16 count, LPVOID buffer) { - TEXTMETRICA tm; LOGFONT16* pLogFont = (LOGFONT16*)buffer; /* @@ -309,10 +317,8 @@ static inline void FixStockFontSize16( if ( (count >= 2*sizeof(INT16)) && (pLogFont->lfHeight == 0) ) { - GetFontMetrics(handle, &tm); - - pLogFont->lfHeight = tm.tmHeight; - pLogFont->lfWidth = tm.tmAveCharWidth; + pLogFont->lfHeight = stock_font_height[handle-FIRST_STOCK_HANDLE]; + pLogFont->lfWidth = stock_font_width[handle-FIRST_STOCK_HANDLE]; } } @@ -321,7 +327,6 @@ static inline void FixStockFontSizeA( INT count, LPVOID buffer) { - TEXTMETRICA tm; LOGFONTA* pLogFont = (LOGFONTA*)buffer; /* @@ -331,10 +336,8 @@ static inline void FixStockFontSizeA( if ( (count >= 2*sizeof(INT)) && (pLogFont->lfHeight == 0) ) { - GetFontMetrics(handle, &tm); - - pLogFont->lfHeight = tm.tmHeight; - pLogFont->lfWidth = tm.tmAveCharWidth; + pLogFont->lfHeight = stock_font_height[handle-FIRST_STOCK_HANDLE]; + pLogFont->lfWidth = stock_font_width[handle-FIRST_STOCK_HANDLE]; } } @@ -575,6 +578,15 @@ void GDI_ReleaseObj( HGDIOBJ handle ) } +/*********************************************************************** + * GDI_CheckNotLock + */ +void GDI_CheckNotLock(void) +{ + _CheckNotSysLevel( &GDI_level ); +} + + /*********************************************************************** * DeleteObject (GDI.69) * SysDeleteObject (GDI.605) @@ -668,6 +680,8 @@ INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer ) TRACE("%04x %d %p\n", handle, count, buffer ); if (!count) return 0; + if (handle >= FIRST_STOCK_FONT && handle <= LAST_STOCK_FONT) init_stock_fonts_metrics(); + if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) @@ -710,6 +724,8 @@ INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer ) TRACE("%08x %d %p\n", handle, count, buffer ); if (!count) return 0; + if (handle >= FIRST_STOCK_FONT && handle <= LAST_STOCK_FONT) init_stock_fonts_metrics(); + if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) @@ -766,6 +782,8 @@ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer ) TRACE("%08x %d %p\n", handle, count, buffer ); if (!count) return 0; + if (handle >= FIRST_STOCK_FONT && handle <= LAST_STOCK_FONT) init_stock_fonts_metrics(); + if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic))