Mike McCormack <mike@xxxxxxxxxxxxxxx> Use the handle deletion mechanism in wmfs -- Huw Davies huw@xxxxxxxxxxxxxxx Index: dlls/gdi/mfdrv/graphics.c =================================================================== RCS file: /home/wine/wine/dlls/gdi/mfdrv/graphics.c,v retrieving revision 1.7 diff -u -r1.7 graphics.c --- dlls/gdi/mfdrv/graphics.c 12 May 2003 03:27:24 -0000 1.7 +++ dlls/gdi/mfdrv/graphics.c 25 Nov 2003 17:19:19 -0000 @@ -335,7 +335,7 @@ WARN("MFDRV_WriteRecord failed\n"); return -1; } - return MFDRV_AddHandleDC( dev ); + return MFDRV_AddHandle( dev, hrgn ); } @@ -378,7 +378,7 @@ if(iRgn == -1) return FALSE; iBrush = MFDRV_CreateBrushIndirect( dev, hbrush ); - if(iBrush == -1) + if(!iBrush) return FALSE; return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush ); } @@ -394,7 +394,7 @@ if(iRgn == -1) return FALSE; iBrush = MFDRV_CreateBrushIndirect( dev, hbrush ); - if(iBrush == -1) + if(!iBrush) return FALSE; return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y ); } Index: dlls/gdi/mfdrv/init.c =================================================================== RCS file: /home/wine/wine/dlls/gdi/mfdrv/init.c,v retrieving revision 1.27 diff -u -r1.27 init.c --- dlls/gdi/mfdrv/init.c 25 Nov 2003 05:03:09 -0000 1.27 +++ dlls/gdi/mfdrv/init.c 25 Nov 2003 17:19:19 -0000 @@ -48,7 +48,7 @@ NULL, /* pCreateDIBSection */ NULL, /* pDeleteBitmap */ NULL, /* pDeleteDC */ - NULL, /* pDeleteObject */ + MFDRV_DeleteObject, /* pDeleteObject */ NULL, /* pDescribePixelFormat */ NULL, /* pDeviceCapabilities */ MFDRV_Ellipse, /* pEllipse */ @@ -182,7 +182,10 @@ return NULL; } - physDev->nextHandle = 0; + physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0])); + physDev->handles_size = HANDLE_LIST_INC; + physDev->cur_handles = 0; + physDev->hFile = 0; physDev->mh->mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD); @@ -203,8 +206,13 @@ { METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; DC *dc = physDev->dc; + DWORD index; if (physDev->mh) HeapFree( GetProcessHeap(), 0, physDev->mh ); + for(index = 0; index < physDev->handles_size; index++) + if(physDev->handles[index]) + GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc); + HeapFree( GetProcessHeap(), 0, physDev->handles ); HeapFree( GetProcessHeap(), 0, physDev ); dc->physDev = NULL; GDI_FreeObject( dc->hSelf, dc ); @@ -532,20 +540,6 @@ return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); } - -/****************************************************************** - * MFDRV_AddHandleDC - * - * Note: this function assumes that we never delete objects. - * If we do someday, we'll need to maintain a table to re-use deleted - * handles. - */ -int MFDRV_AddHandleDC( PHYSDEV dev ) -{ - METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; - physDev->mh->mtNoObjects++; - return physDev->nextHandle++; -} /********************************************************************** * MFDRV_ExtEscape Index: dlls/gdi/mfdrv/metafiledrv.h =================================================================== RCS file: /home/wine/wine/dlls/gdi/mfdrv/metafiledrv.h,v retrieving revision 1.10 diff -u -r1.10 metafiledrv.h --- dlls/gdi/mfdrv/metafiledrv.h 5 Sep 2003 23:08:38 -0000 1.10 +++ dlls/gdi/mfdrv/metafiledrv.h 25 Nov 2003 17:19:19 -0000 @@ -35,10 +35,13 @@ HDC hdc; DC *dc; METAHEADER *mh; /* Pointer to metafile header */ - UINT nextHandle; /* Next handle number */ + UINT handles_size, cur_handles; + HGDIOBJ *handles; HANDLE hFile; /* Handle for disk based MetaFile */ } METAFILEDRV_PDEVICE; +#define HANDLE_LIST_INC 20 + extern BOOL MFDRV_MetaParam0(PHYSDEV dev, short func); extern BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1); @@ -52,7 +55,7 @@ short param3, short param4, short param5, short param6, short param7, short param8); extern BOOL MFDRV_WriteRecord(PHYSDEV dev, METARECORD *mr, DWORD rlen); -extern int MFDRV_AddHandleDC( PHYSDEV dev ); +extern UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj ); extern INT16 MFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ); /* Metafile driver functions */ @@ -68,6 +71,7 @@ INT bottom, INT xstart, INT ystart, INT xend, INT yend ); extern BOOL MFDRV_CloseFigure( PHYSDEV dev ); +extern BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ); extern BOOL MFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ); extern BOOL MFDRV_EndPath( PHYSDEV dev ); Index: dlls/gdi/mfdrv/objects.c =================================================================== RCS file: /home/wine/wine/dlls/gdi/mfdrv/objects.c,v retrieving revision 1.8 diff -u -r1.8 objects.c --- dlls/gdi/mfdrv/objects.c 30 Aug 2003 00:15:12 -0000 1.8 +++ dlls/gdi/mfdrv/objects.c 25 Nov 2003 17:19:19 -0000 @@ -29,6 +29,89 @@ WINE_DEFAULT_DEBUG_CHANNEL(metafile); +/****************************************************************** + * MFDRV_AddHandle + */ +UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj ) +{ + METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; + INT16 index; + + for(index = 0; index < physDev->handles_size; index++) + if(physDev->handles[index] == 0) break; + if(index == physDev->handles_size) { + physDev->handles_size += HANDLE_LIST_INC; + physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + physDev->handles, + physDev->handles_size * sizeof(physDev->handles[0])); + } + physDev->handles[index] = obj; + + physDev->cur_handles++; + if(physDev->cur_handles > physDev->mh->mtNoObjects) + physDev->mh->mtNoObjects++; + + return index ; /* index 0 is not reserved for metafiles */ +} + +/****************************************************************** + * MFDRV_FindObject + */ +static INT16 MFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj ) +{ + METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; + INT16 index; + + for(index = 0; index < physDev->handles_size; index++) + if(physDev->handles[index] == obj) break; + + if(index == physDev->handles_size) return -1; + + return index ; +} + + +/****************************************************************** + * MFDRV_DeleteObject + */ +BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) +{ + METARECORD mr; + METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; + INT16 index; + BOOL ret = TRUE; + + index = MFDRV_FindObject(dev, obj); + if( index < 0 ) + return 0; + + mr.rdSize = sizeof mr / 2; + mr.rdFunction = META_DELETEOBJECT; + mr.rdParm[0] = index; + + if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 )) + ret = FALSE; + + physDev->handles[index] = 0; + physDev->cur_handles--; + return ret; +} + + +/*********************************************************************** + * MFDRV_SelectObject + */ +static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index) +{ + METARECORD mr; + + mr.rdSize = sizeof mr / 2; + mr.rdFunction = META_SELECTOBJECT; + mr.rdParm[0] = index; + + return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ); +} + /*********************************************************************** * MFDRV_SelectBitmap @@ -45,11 +128,11 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) { - INT16 index = -1; DWORD size; METARECORD *mr; LOGBRUSH logbrush; METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; + BOOL r; if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1; @@ -68,7 +151,7 @@ mr = HeapAlloc( GetProcessHeap(), 0, size ); mr->rdSize = size / 2; mr->rdFunction = META_CREATEBRUSHINDIRECT; - memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16)); + memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16)); break; } case BS_PATTERN: @@ -136,14 +219,14 @@ } default: FIXME("Unkonwn brush style %x\n", logbrush.lbStyle); - return -1; + return 0; } - index = MFDRV_AddHandleDC( dev ); - if(!MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)) - index = -1; + r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); HeapFree(GetProcessHeap(), 0, mr); + if( !r ) + return -1; done: - return index; + return MFDRV_AddHandle( dev, hBrush ); } @@ -152,39 +235,35 @@ */ HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) { + METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; INT16 index; - METARECORD mr; - index = MFDRV_CreateBrushIndirect( dev, hbrush ); - if(index == -1) return 0; - - mr.rdSize = sizeof(mr) / 2; - mr.rdFunction = META_SELECTOBJECT; - mr.rdParm[0] = index; - return MFDRV_WriteRecord( dev, &mr, mr.rdSize * 2) ? hbrush : 0; + index = MFDRV_FindObject(dev, hbrush); + if( index < 0 ) + { + index = MFDRV_CreateBrushIndirect( dev, hbrush ); + if( index < 0 ) + return 0; + GDI_hdc_using_object(hbrush, physDev->hdc); + } + return MFDRV_SelectObject( dev, index ) ? hbrush : HGDI_ERROR; } /****************************************************************** * MFDRV_CreateFontIndirect */ -static BOOL MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont) +static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont) { - int index; char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2; mr->rdFunction = META_CREATEFONTINDIRECT; memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16)); - if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return FALSE; - - mr->rdSize = sizeof(METARECORD) / 2; - mr->rdFunction = META_SELECTOBJECT; - - if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE; - *(mr->rdParm) = index; - return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); + if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) + return 0; + return MFDRV_AddHandle( dev, hFont ); } @@ -193,33 +272,37 @@ */ HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont ) { + METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; LOGFONT16 lf16; + INT16 index; - if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 )) return HGDI_ERROR; - if (MFDRV_CreateFontIndirect(dev, hfont, &lf16)) return 0; - return HGDI_ERROR; + index = MFDRV_FindObject(dev, hfont); + if( index < 0 ) + { + if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 )) + return HGDI_ERROR; + index = MFDRV_CreateFontIndirect(dev, hfont, &lf16); + if( index < 0 ) + return HGDI_ERROR; + GDI_hdc_using_object(hfont, physDev->hdc); + } + return MFDRV_SelectObject( dev, index ) ? hfont : HGDI_ERROR; } /****************************************************************** * MFDRV_CreatePenIndirect */ -static BOOL MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen) +static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen) { - int index; char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2; mr->rdFunction = META_CREATEPENINDIRECT; memcpy(&(mr->rdParm), logpen, sizeof(*logpen)); - if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return FALSE; - - mr->rdSize = sizeof(METARECORD) / 2; - mr->rdFunction = META_SELECTOBJECT; - - if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE; - *(mr->rdParm) = index; - return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); + if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) + return 0; + return MFDRV_AddHandle( dev, hPen ); } @@ -228,11 +311,21 @@ */ HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen ) { + METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; LOGPEN16 logpen; + INT16 index; - if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen )) return 0; - if (MFDRV_CreatePenIndirect( dev, hpen, &logpen )) return hpen; - return 0; + index = MFDRV_FindObject(dev, hpen); + if( index < 0 ) + { + if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen )) + return 0; + index = MFDRV_CreatePenIndirect( dev, hpen, &logpen ); + if( index < 0 ) + return 0; + GDI_hdc_using_object(hpen, physDev->hdc); + } + return MFDRV_SelectObject( dev, index ) ? hpen : HGDI_ERROR; } @@ -258,7 +351,7 @@ mr->rdSize = sizeof(METARECORD) / sizeof(WORD); mr->rdFunction = META_SELECTPALETTE; - if ((index = MFDRV_AddHandleDC( dev )) == -1) ret = FALSE; + if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE; else { *(mr->rdParm) = index;