winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
October 2012
----- 2025 -----
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
2 participants
960 discussions
Start a n
N
ew thread
Jacek Caban : mshtml: Added HTMLImgElement::onabort implementation.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: 5e0f624c418b9668b03f3ee70a43e289aef91c59 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=5e0f624c418b9668b03f3ee70…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed Oct 17 12:18:30 2012 +0200 mshtml: Added HTMLImgElement::onabort implementation. --- dlls/mshtml/htmlevent.c | 7 ++++++- dlls/mshtml/htmlevent.h | 1 + dlls/mshtml/htmlimg.c | 12 ++++++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 94a9e7e..b2dfa61 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -45,6 +45,9 @@ struct event_target_t { handler_vector_t *event_table[EVENTID_LAST]; }; +static const WCHAR abortW[] = {'a','b','o','r','t',0}; +static const WCHAR onabortW[] = {'o','n','a','b','o','r','t',0}; + static const WCHAR beforeunloadW[] = {'b','e','f','o','r','e','u','n','l','o','a','d',0}; static const WCHAR onbeforeunloadW[] = {'o','n','b','e','f','o','r','e','u','n','l','o','a','d',0}; @@ -160,6 +163,8 @@ typedef struct { #define EVENT_HASDEFAULTHANDLERS 0x0020 static const event_info_t event_info[] = { + {abortW, onabortW, EVENTT_NONE, DISPID_EVMETH_ONABORT, + EVENT_NODEHANDLER}, {beforeunloadW, onbeforeunloadW, EVENTT_NONE, DISPID_EVMETH_ONBEFOREUNLOAD, EVENT_DEFAULTLISTENER|EVENT_FORWARDBODY}, {blurW, onblurW, EVENTT_HTML, DISPID_EVMETH_ONBLUR, @@ -216,7 +221,7 @@ static const event_info_t event_info[] = { EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_CANCELABLE} }; -static const eventid_t node_handled_list[] = { EVENTID_ERROR, EVENTID_LOAD }; +static const eventid_t node_handled_list[] = { EVENTID_ABORT, EVENTID_ERROR, EVENTID_LOAD }; eventid_t str_to_eid(LPCWSTR str) { diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 174d2f7..8aa8ed1 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -17,6 +17,7 @@ */ typedef enum { + EVENTID_ABORT, EVENTID_BEFOREUNLOAD, EVENTID_BLUR, EVENTID_CHANGE, diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index bc6ec80..4ca02fc 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -429,15 +429,19 @@ static HRESULT WINAPI HTMLImgElement_get_onerror(IHTMLImgElement *iface, VARIANT static HRESULT WINAPI HTMLImgElement_put_onabort(IHTMLImgElement *iface, VARIANT v) { HTMLImgElement *This = impl_from_IHTMLImgElement(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; + + TRACE("(%p)->()\n", This); + + return set_node_event(&This->element.node, EVENTID_ABORT, &v); } static HRESULT WINAPI HTMLImgElement_get_onabort(IHTMLImgElement *iface, VARIANT *p) { HTMLImgElement *This = impl_from_IHTMLImgElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_node_event(&This->element.node, EVENTID_ABORT, p); } static HRESULT WINAPI HTMLImgElement_put_name(IHTMLImgElement *iface, BSTR v)
1
0
0
0
Alexandre Julliard : gdi32: Get rid of the GDIOBJHDR type.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: df357093ccfd78156e7db3c0a7ff5bead6317341 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=df357093ccfd78156e7db3c0a…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:48:45 2012 +0200 gdi32: Get rid of the GDIOBJHDR type. --- dlls/gdi32/bitmap.c | 2 +- dlls/gdi32/brush.c | 3 +-- dlls/gdi32/dc.c | 2 +- dlls/gdi32/dib.c | 2 +- dlls/gdi32/enhmetafile.c | 3 +-- dlls/gdi32/font.c | 3 +-- dlls/gdi32/gdi_private.h | 6 ------ dlls/gdi32/gdiobj.c | 4 ++-- dlls/gdi32/palette.c | 3 +-- dlls/gdi32/pen.c | 5 ++--- 10 files changed, 11 insertions(+), 22 deletions(-) diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 0055fe4..821f879 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -211,7 +211,7 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) bmpobj->dib.dsBm = bm; bmpobj->dib.dsBm.bmBits = NULL; - if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs ))) + if (!(hbitmap = alloc_gdi_handle( bmpobj, OBJ_BITMAP, &bitmap_funcs ))) { HeapFree( GetProcessHeap(), 0, bmpobj ); return 0; diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index 0516a0f..4f0c17d 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -34,7 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); /* GDI logical brush object */ typedef struct { - GDIOBJHDR header; LOGBRUSH logbrush; struct brush_pattern pattern; } BRUSHOBJ; @@ -201,7 +200,7 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) ptr->logbrush = *brush; if (store_brush_pattern( &ptr->logbrush, &ptr->pattern ) && - (hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs ))) + (hbrush = alloc_gdi_handle( ptr, OBJ_BRUSH, &brush_funcs ))) { TRACE("%p\n", hbrush); return hbrush; diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 5a68aa6..8d4cde0 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -118,7 +118,7 @@ DC *alloc_dc_ptr( WORD magic ) reset_bounds( &dc->bounds ); - if (!(dc->hSelf = alloc_gdi_handle( &dc->header, magic, &dc_funcs ))) + if (!(dc->hSelf = alloc_gdi_handle( dc, magic, &dc_funcs ))) { HeapFree( GetProcessHeap(), 0, dc ); return NULL; diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 89ac980..e5361c1 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -1549,7 +1549,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, if (!bmp->dib.dsBm.bmBits) goto error; - if (!(ret = alloc_gdi_handle( &bmp->header, OBJ_BITMAP, &dib_funcs ))) goto error; + if (!(ret = alloc_gdi_handle( bmp, OBJ_BITMAP, &dib_funcs ))) goto error; if (bits) *bits = bmp->dib.dsBm.bmBits; return ret; diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c index ea0ce3b..796796e 100644 --- a/dlls/gdi32/enhmetafile.c +++ b/dlls/gdi32/enhmetafile.c @@ -50,7 +50,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile); typedef struct { - GDIOBJHDR header; ENHMETAHEADER *emh; BOOL on_disk; /* true if metafile is on disk */ } ENHMETAFILEOBJ; @@ -270,7 +269,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) metaObj->emh = emh; metaObj->on_disk = on_disk; - if (!(hmf = alloc_gdi_handle( &metaObj->header, OBJ_ENHMETAFILE, NULL ))) + if (!(hmf = alloc_gdi_handle( metaObj, OBJ_ENHMETAFILE, NULL ))) HeapFree( GetProcessHeap(), 0, metaObj ); return hmf; } diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 85a27f1..1f26772 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -110,7 +110,6 @@ static const struct gdi_obj_funcs font_funcs = typedef struct { - GDIOBJHDR header; LOGFONTW logfont; } FONTOBJ; @@ -447,7 +446,7 @@ HFONT WINAPI CreateFontIndirectExW( const ENUMLOGFONTEXDVW *penumex ) plf->lfOrientation/10., plf->lfEscapement/10., fontPtr); } - if (!(hFont = alloc_gdi_handle( &fontPtr->header, OBJ_FONT, &font_funcs ))) + if (!(hFont = alloc_gdi_handle( fontPtr, OBJ_FONT, &font_funcs ))) { HeapFree( GetProcessHeap(), 0, fontPtr ); return 0; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index c3e342a..2f4c297 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -57,15 +57,10 @@ struct gdi_obj_funcs BOOL (*pDeleteObject)( HGDIOBJ handle ); }; -typedef struct tagGDIOBJHDR -{ -} GDIOBJHDR; - typedef struct tagGdiFont GdiFont; typedef struct tagDC { - GDIOBJHDR header; HDC hSelf; /* Handle to this DC */ struct gdi_physdev nulldrv; /* physdev for the null driver */ PHYSDEV physDev; /* current top of the physdev stack */ @@ -180,7 +175,6 @@ static inline PHYSDEV find_dc_driver( DC *dc, const struct gdi_dc_funcs *funcs ) typedef struct tagBITMAPOBJ { - GDIOBJHDR header; DIBSECTION dib; SIZE size; /* For SetBitmapDimension() */ RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */ diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 46c9ec3..aa8db8c 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -744,7 +744,7 @@ HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *func */ void *free_gdi_handle( HGDIOBJ handle ) { - GDIOBJHDR *object = NULL; + void *object = NULL; struct gdi_handle_entry *entry; EnterCriticalSection( &gdi_section ); @@ -769,7 +769,7 @@ void *free_gdi_handle( HGDIOBJ handle ) */ void *GDI_GetObjPtr( HGDIOBJ handle, WORD type ) { - GDIOBJHDR *ptr = NULL; + void *ptr = NULL; struct gdi_handle_entry *entry; EnterCriticalSection( &gdi_section ); diff --git a/dlls/gdi32/palette.c b/dlls/gdi32/palette.c index afb723b..6a29c76 100644 --- a/dlls/gdi32/palette.c +++ b/dlls/gdi32/palette.c @@ -42,7 +42,6 @@ typedef BOOL (*unrealize_function)(HPALETTE); typedef struct tagPALETTEOBJ { - GDIOBJHDR header; unrealize_function unrealize; WORD version; /* palette version */ WORD count; /* count of palette entries */ @@ -130,7 +129,7 @@ HPALETTE WINAPI CreatePalette( return 0; } memcpy( palettePtr->entries, palette->palPalEntry, size ); - if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs ))) + if (!(hpalette = alloc_gdi_handle( palettePtr, OBJ_PAL, &palette_funcs ))) { HeapFree( GetProcessHeap(), 0, palettePtr->entries ); HeapFree( GetProcessHeap(), 0, palettePtr ); diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c index 94c3933..2ae2f2b 100644 --- a/dlls/gdi32/pen.c +++ b/dlls/gdi32/pen.c @@ -36,7 +36,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); /* GDI logical pen object */ typedef struct { - GDIOBJHDR header; struct brush_pattern pattern; EXTLOGPEN logpen; } PENOBJ; @@ -113,7 +112,7 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen ) break; } - if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_PEN, &pen_funcs ))) + if (!(hpen = alloc_gdi_handle( penPtr, OBJ_PEN, &pen_funcs ))) HeapFree( GetProcessHeap(), 0, penPtr ); return hpen; } @@ -203,7 +202,7 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, penPtr->logpen.elpNumEntries = style_count; memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD)); - if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_EXTPEN, &pen_funcs ))) + if (!(hpen = alloc_gdi_handle( penPtr, OBJ_EXTPEN, &pen_funcs ))) { free_brush_pattern( &penPtr->pattern ); HeapFree( GetProcessHeap(), 0, penPtr );
1
0
0
0
Alexandre Julliard : gdi32: Get rid of the METAFILEOBJ type, instead store a pointer to the metafile data.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: 3964aa4a8db926347d12dae84c07f037f3c4fac2 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=3964aa4a8db926347d12dae84…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:46:32 2012 +0200 gdi32: Get rid of the METAFILEOBJ type, instead store a pointer to the metafile data. --- dlls/gdi32/metafile.c | 158 ++++++++++++++++++------------------------------- 1 files changed, 58 insertions(+), 100 deletions(-) diff --git a/dlls/gdi32/metafile.c b/dlls/gdi32/metafile.c index fbc88d1..dbbffee 100644 --- a/dlls/gdi32/metafile.c +++ b/dlls/gdi32/metafile.c @@ -71,12 +71,6 @@ typedef struct } METAHEADERDISK; #include "poppack.h" -typedef struct -{ - GDIOBJHDR header; - METAHEADER *mh; -} METAFILEOBJ; - /****************************************************************** * MF_AddHandle @@ -108,31 +102,7 @@ static int MF_AddHandle(HANDLETABLE *ht, UINT htlen, HGDIOBJ hobj) */ HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) { - HMETAFILE hmf; - METAFILEOBJ *metaObj; - - if (!(metaObj = HeapAlloc( GetProcessHeap(), 0, sizeof(*metaObj) ))) return 0; - metaObj->mh = mh; - if (!(hmf = alloc_gdi_handle( &metaObj->header, OBJ_METAFILE, NULL ))) - HeapFree( GetProcessHeap(), 0, metaObj ); - return hmf; -} - -/****************************************************************** - * MF_GetMetaHeader - * - * Returns ptr to METAHEADER associated with HMETAFILE - */ -static METAHEADER *MF_GetMetaHeader( HMETAFILE hmf ) -{ - METAHEADER *ret = NULL; - METAFILEOBJ * metaObj = GDI_GetObjPtr( hmf, OBJ_METAFILE ); - if (metaObj) - { - ret = metaObj->mh; - GDI_ReleaseObj( hmf ); - } - return ret; + return alloc_gdi_handle( mh, OBJ_METAFILE, NULL ); } /****************************************************************** @@ -164,10 +134,9 @@ static POINT *convert_points( UINT count, const POINTS *pts ) BOOL WINAPI DeleteMetaFile( HMETAFILE hmf ) { - METAFILEOBJ * metaObj = free_gdi_handle( hmf ); - if (!metaObj) return FALSE; - HeapFree( GetProcessHeap(), 0, metaObj->mh ); - return HeapFree( GetProcessHeap(), 0, metaObj ); + METAHEADER *mh = free_gdi_handle( hmf ); + if (!mh) return FALSE; + return HeapFree( GetProcessHeap(), 0, mh ); } /****************************************************************** @@ -312,6 +281,24 @@ METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mh, LPCVOID filename, BOOL uni ) return mh; } +/* return a copy of the metafile bits, to be freed with HeapFree */ +static METAHEADER *get_metafile_bits( HMETAFILE hmf ) +{ + METAHEADER *ret, *mh = GDI_GetObjPtr( hmf, OBJ_METAFILE ); + + if (!mh) return NULL; + + if (mh->mtType != METAFILE_DISK) + { + ret = HeapAlloc( GetProcessHeap(), 0, mh->mtSize * 2 ); + if (ret) memcpy( ret, mh, mh->mtSize * 2 ); + } + else ret = MF_LoadDiskBasedMetaFile( mh ); + + GDI_ReleaseObj( hmf ); + return ret; +} + /****************************************************************** * CopyMetaFileW (GDI32.@) * @@ -331,33 +318,25 @@ METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mh, LPCVOID filename, BOOL uni ) */ HMETAFILE WINAPI CopyMetaFileW( HMETAFILE hSrcMetaFile, LPCWSTR lpFilename ) { - METAHEADER *mh = MF_GetMetaHeader( hSrcMetaFile ); - METAHEADER *mh2 = NULL; + METAHEADER *mh = get_metafile_bits( hSrcMetaFile ); HANDLE hFile; TRACE("(%p,%s)\n", hSrcMetaFile, debugstr_w(lpFilename)); if(!mh) return 0; - if(mh->mtType == METAFILE_DISK) - mh2 = MF_LoadDiskBasedMetaFile(mh); - else { - mh2 = HeapAlloc( GetProcessHeap(), 0, mh->mtSize * 2 ); - memcpy( mh2, mh, mh->mtSize * 2 ); - } - if(lpFilename) { /* disk based metafile */ DWORD w; if((hFile = CreateFileW(lpFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) { - HeapFree( GetProcessHeap(), 0, mh2 ); + HeapFree( GetProcessHeap(), 0, mh ); return 0; } - WriteFile(hFile, mh2, mh2->mtSize * 2, &w, NULL); + WriteFile(hFile, mh, mh->mtSize * 2, &w, NULL); CloseHandle(hFile); } - return MF_Create_HMETAFILE( mh2 ); + return MF_Create_HMETAFILE( mh ); } @@ -380,14 +359,23 @@ HMETAFILE WINAPI CopyMetaFileA( HMETAFILE hSrcMetaFile, LPCSTR lpFilename ) return ret; } -/******************************************************************* - * MF_PlayMetaFile +/****************************************************************** + * PlayMetaFile (GDI32.@) + * + * Renders the metafile specified by hmf in the DC specified by + * hdc. Returns FALSE on failure, TRUE on success. + * + * PARAMS + * hdc [I] handle of DC to render in + * hmf [I] handle of metafile to render * - * Helper for PlayMetaFile + * RETURNS + * Success: TRUE + * Failure: FALSE */ -static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh) +BOOL WINAPI PlayMetaFile( HDC hdc, HMETAFILE hmf ) { - + METAHEADER *mh = get_metafile_bits( hmf ); METARECORD *mr; HANDLETABLE *ht; unsigned int offset = 0; @@ -396,14 +384,8 @@ static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh) HBRUSH hBrush; HPALETTE hPal; HRGN hRgn; - BOOL loaded = FALSE; if (!mh) return FALSE; - if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */ - mh = MF_LoadDiskBasedMetaFile(mh); - if(!mh) return FALSE; - loaded = TRUE; - } /* save DC */ hPen = GetCurrentObject(hdc, OBJ_PEN); @@ -420,7 +402,11 @@ static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh) /* create the handle table */ ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HANDLETABLE) * mh->mtNoObjects); - if(!ht) return FALSE; + if(!ht) + { + HeapFree( GetProcessHeap(), 0, mh ); + return FALSE; + } /* loop through metafile playing records */ offset = mh->mtHeaderSize * 2; @@ -455,34 +441,12 @@ static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh) if(*(ht->objectHandle + i) != 0) DeleteObject(*(ht->objectHandle + i)); - /* free handle table */ HeapFree( GetProcessHeap(), 0, ht ); - if(loaded) - HeapFree( GetProcessHeap(), 0, mh ); + HeapFree( GetProcessHeap(), 0, mh ); return TRUE; } /****************************************************************** - * PlayMetaFile (GDI32.@) - * - * Renders the metafile specified by hmf in the DC specified by - * hdc. Returns FALSE on failure, TRUE on success. - * - * PARAMS - * hdc [I] handle of DC to render in - * hmf [I] handle of metafile to render - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI PlayMetaFile( HDC hdc, HMETAFILE hmf ) -{ - METAHEADER *mh = MF_GetMetaHeader( hmf ); - return MF_PlayMetaFile( hdc, mh ); -} - -/****************************************************************** * EnumMetaFile (GDI32.@) * * Loop through the metafile records in hmf, calling the user-specified @@ -495,7 +459,7 @@ BOOL WINAPI PlayMetaFile( HDC hdc, HMETAFILE hmf ) */ BOOL WINAPI EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc, LPARAM lpData) { - METAHEADER *mhTemp = NULL, *mh = MF_GetMetaHeader(hmf); + METAHEADER *mh = get_metafile_bits( hmf ); METARECORD *mr; HANDLETABLE *ht; BOOL result = TRUE; @@ -505,14 +469,9 @@ BOOL WINAPI EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc, LPARAM l HBRUSH hBrush; HFONT hFont; - TRACE("(%p,%p,%p,%p)\n", hdc, hmf, lpEnumFunc, (void*)lpData); + TRACE("(%p,%p,%p,%lx)\n", hdc, hmf, lpEnumFunc, lpData); + if (!mh) return 0; - if(mh->mtType == METAFILE_DISK) - { - /* Create a memory-based copy */ - if (!(mhTemp = MF_LoadDiskBasedMetaFile(mh))) return FALSE; - mh = mhTemp; - } /* save the current pen, brush and font */ hPen = GetCurrentObject(hdc, OBJ_PEN); @@ -534,7 +493,7 @@ BOOL WINAPI EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc, LPARAM l } TRACE("Calling EnumFunc with record type %x\n", mr->rdFunction); - if (!lpEnumFunc( hdc, ht, mr, mh->mtNoObjects, (LONG)lpData )) + if (!lpEnumFunc( hdc, ht, mr, mh->mtNoObjects, lpData )) { result = FALSE; break; @@ -553,10 +512,8 @@ BOOL WINAPI EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc, LPARAM l if(*(ht->objectHandle + i) != 0) DeleteObject(*(ht->objectHandle + i)); - /* free handle table */ HeapFree( GetProcessHeap(), 0, ht); - /* free a copy of metafile */ - HeapFree( GetProcessHeap(), 0, mhTemp ); + HeapFree( GetProcessHeap(), 0, mh); return result; } @@ -1129,7 +1086,7 @@ HMETAFILE WINAPI SetMetaFileBitsEx( UINT size, const BYTE *lpData ) */ UINT WINAPI GetMetaFileBitsEx( HMETAFILE hmf, UINT nSize, LPVOID buf ) { - METAHEADER *mh = MF_GetMetaHeader(hmf); + METAHEADER *mh = GDI_GetObjPtr( hmf, OBJ_METAFILE ); UINT mfSize; TRACE("(%p,%d,%p)\n", hmf, nSize, buf); @@ -1137,12 +1094,13 @@ UINT WINAPI GetMetaFileBitsEx( HMETAFILE hmf, UINT nSize, LPVOID buf ) if(mh->mtType == METAFILE_DISK) FIXME("Disk-based metafile?\n"); mfSize = mh->mtSize * 2; - if (!buf) { - TRACE("returning size %d\n", mfSize); - return mfSize; + if (buf) + { + if(mfSize > nSize) mfSize = nSize; + memmove(buf, mh, mfSize); } - if(mfSize > nSize) mfSize = nSize; - memmove(buf, mh, mfSize); + GDI_ReleaseObj( hmf ); + TRACE("returning size %d\n", mfSize); return mfSize; }
1
0
0
0
Alexandre Julliard : gdi32: Get rid of the RGNOBJ type, instead store a pointer to the region itself.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: 89ecf02ca5ab0ce07850162c383f1ebdbf522658 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=89ecf02ca5ab0ce07850162c3…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:28:25 2012 +0200 gdi32: Get rid of the RGNOBJ type, instead store a pointer to the region itself. --- dlls/gdi32/gdi_private.h | 7 ++- dlls/gdi32/region.c | 217 +++++++++++++++++++++------------------------- 2 files changed, 104 insertions(+), 120 deletions(-) Diff:
http://source.winehq.org/git/wine.git/?a=commitdiff;h=89ecf02ca5ab0ce078501…
1
0
0
0
Alexandre Julliard : gdi32: Store the object flags directly in the GDI handle table.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: dfeeedcf744f43edb146586a27ff321f857122ca URL:
http://source.winehq.org/git/wine.git/?a=commit;h=dfeeedcf744f43edb146586a2…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:20:46 2012 +0200 gdi32: Store the object flags directly in the GDI handle table. --- dlls/gdi32/gdi_private.h | 4 +--- dlls/gdi32/gdiobj.c | 34 ++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index cb2f9cd..792cf63 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -59,8 +59,6 @@ struct gdi_obj_funcs typedef struct tagGDIOBJHDR { - WORD system : 1; /* system object flag */ - WORD deleted : 1; /* whether DeleteObject has been called on this object */ } GDIOBJHDR; typedef struct tagGdiFont GdiFont; @@ -310,7 +308,7 @@ extern BOOL WineEngInit(void) DECLSPEC_HIDDEN; extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN; /* gdiobj.c */ -extern HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN; +extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN; extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN; extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 4fe72a9..46c9ec3 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -49,11 +49,13 @@ struct hdc_list struct gdi_handle_entry { - GDIOBJHDR *obj; /* pointer to the object-specific data */ + void *obj; /* pointer to the object-specific data */ const struct gdi_obj_funcs *funcs; /* type-specific functions */ struct hdc_list *hdcs; /* list of HDCs interested in this object */ WORD type; /* object type (one of the OBJ_* constants) */ WORD selcount; /* number of times the object is selected in a DC */ + WORD system : 1; /* system object flag */ + WORD deleted : 1; /* whether DeleteObject has been called on this object */ }; static struct gdi_handle_entry gdi_handles[MAX_GDI_HANDLES]; @@ -479,9 +481,11 @@ static const struct DefaultFontInfo default_fonts[] = */ void CDECL __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set) { - GDIOBJHDR *ptr = GDI_GetObjPtr( handle, 0 ); - ptr->system = !!set; - GDI_ReleaseObj( handle ); + struct gdi_handle_entry *entry; + + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) entry->system = !!set; + LeaveCriticalSection( &gdi_section ); } /****************************************************************************** @@ -572,10 +576,10 @@ BOOL GDI_dec_ref_count( HGDIOBJ handle ) if ((entry = handle_entry( handle ))) { assert( entry->selcount ); - if (!--entry->selcount && entry->obj->deleted) + if (!--entry->selcount && entry->deleted) { /* handle delayed DeleteObject*/ - entry->obj->deleted = 0; + entry->deleted = 0; LeaveCriticalSection( &gdi_section ); TRACE( "executing delayed DeleteObject for %p\n", handle ); DeleteObject( handle ); @@ -686,7 +690,7 @@ static void dump_gdi_objects( void ) } TRACE( "handle %p obj %p type %s selcount %u deleted %u\n", entry_to_handle( entry ), entry->obj, gdi_obj_type( entry->type ), - entry->selcount, entry->obj->deleted ); + entry->selcount, entry->deleted ); } LeaveCriticalSection( &gdi_section ); } @@ -696,7 +700,7 @@ static void dump_gdi_objects( void ) * * Allocate a GDI handle for an object, which must have been allocated on the process heap. */ -HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) +HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) { struct gdi_handle_entry *entry; HGDIOBJ ret; @@ -704,10 +708,6 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs assert( type ); /* type 0 is reserved to mark free entries */ - /* initialize the object header */ - obj->system = 0; - obj->deleted = 0; - EnterCriticalSection( &gdi_section ); for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++) if (!gdi_handles[i].type) goto found; @@ -726,6 +726,8 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs entry->hdcs = NULL; entry->type = type; entry->selcount = 0; + entry->system = 0; + entry->deleted = 0; next_gdi_handle = i; ret = entry_to_handle( entry ); LeaveCriticalSection( &gdi_section ); @@ -837,7 +839,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) return FALSE; } - if (entry->obj->system) + if (entry->system) { TRACE("Preserving system object %p\n", obj); LeaveCriticalSection( &gdi_section ); @@ -850,7 +852,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) if (entry->selcount) { TRACE("delayed for %p because object in use, count %u\n", obj, entry->selcount ); - entry->obj->deleted = 1; /* mark for delete */ + entry->deleted = 1; /* mark for delete */ } else funcs = entry->funcs; @@ -891,7 +893,7 @@ void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) TRACE("obj %p hdc %p\n", obj, hdc); EnterCriticalSection( &gdi_section ); - if ((entry = handle_entry( obj )) && !entry->obj->system) + if ((entry = handle_entry( obj )) && !entry->system) { for (phdc = entry->hdcs; phdc; phdc = phdc->next) if (phdc->hdc == hdc) break; @@ -919,7 +921,7 @@ void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) TRACE("obj %p hdc %p\n", obj, hdc); EnterCriticalSection( &gdi_section ); - if ((entry = handle_entry( obj )) && !entry->obj->system) + if ((entry = handle_entry( obj )) && !entry->system) { for (pphdc = &entry->hdcs; *pphdc; pphdc = &(*pphdc)->next) if ((*pphdc)->hdc == hdc)
1
0
0
0
Alexandre Julliard : gdi32: Store the object selection count directly in the GDI handle table.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: b95dd7e831215ca80b341332598df600bd148a36 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=b95dd7e831215ca80b3413325…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:17:56 2012 +0200 gdi32: Store the object selection count directly in the GDI handle table. --- dlls/gdi32/bitmap.c | 2 +- dlls/gdi32/dib.c | 2 +- dlls/gdi32/gdi_private.h | 2 +- dlls/gdi32/gdiobj.c | 56 ++++++++++++++++++++++++++++++--------------- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index 38bc172..0055fe4 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -436,7 +436,7 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) goto done; } - if (bitmap->header.selcount && (handle != GetStockObject(DEFAULT_BITMAP))) + if (handle != GetStockObject(DEFAULT_BITMAP) && GDI_get_ref_count( handle )) { WARN( "Bitmap already selected in another DC\n" ); GDI_ReleaseObj( handle ); diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index eed57e8..89ac980 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -1589,7 +1589,7 @@ static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc ) goto done; } - if (bitmap->header.selcount) + if (GDI_get_ref_count( handle )) { WARN( "Bitmap already selected in another DC\n" ); GDI_ReleaseObj( handle ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 5dadbc2..cb2f9cd 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -61,7 +61,6 @@ typedef struct tagGDIOBJHDR { WORD system : 1; /* system object flag */ WORD deleted : 1; /* whether DeleteObject has been called on this object */ - DWORD selcount; /* number of times the object is selected in a DC */ } GDIOBJHDR; typedef struct tagGdiFont GdiFont; @@ -316,6 +315,7 @@ extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN; extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN; extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN; +extern UINT GDI_get_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index afc0c59..4fe72a9 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -53,6 +53,7 @@ struct gdi_handle_entry const struct gdi_obj_funcs *funcs; /* type-specific functions */ struct hdc_list *hdcs; /* list of HDCs interested in this object */ WORD type; /* object type (one of the OBJ_* constants) */ + WORD selcount; /* number of times the object is selected in a DC */ }; static struct gdi_handle_entry gdi_handles[MAX_GDI_HANDLES]; @@ -524,21 +525,36 @@ static UINT get_default_charset( void ) /*********************************************************************** + * GDI_get_ref_count + * + * Retrieve the reference count of a GDI object. + * Note: the object must be locked otherwise the count is meaningless. + */ +UINT GDI_get_ref_count( HGDIOBJ handle ) +{ + struct gdi_handle_entry *entry; + UINT ret = 0; + + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) ret = entry->selcount; + LeaveCriticalSection( &gdi_section ); + return ret; +} + + +/*********************************************************************** * GDI_inc_ref_count * * Increment the reference count of a GDI object. */ HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) { - GDIOBJHDR *header; + struct gdi_handle_entry *entry; - if ((header = GDI_GetObjPtr( handle, 0 ))) - { - header->selcount++; - GDI_ReleaseObj( handle ); - } + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) entry->selcount++; else handle = 0; - + LeaveCriticalSection( &gdi_section ); return handle; } @@ -550,22 +566,24 @@ HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) */ BOOL GDI_dec_ref_count( HGDIOBJ handle ) { - GDIOBJHDR *header; + struct gdi_handle_entry *entry; - if ((header = GDI_GetObjPtr( handle, 0 ))) + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) { - assert( header->selcount ); - if (!--header->selcount && header->deleted) + assert( entry->selcount ); + if (!--entry->selcount && entry->obj->deleted) { /* handle delayed DeleteObject*/ - header->deleted = 0; - GDI_ReleaseObj( handle ); + entry->obj->deleted = 0; + LeaveCriticalSection( &gdi_section ); TRACE( "executing delayed DeleteObject for %p\n", handle ); DeleteObject( handle ); + return TRUE; } - else GDI_ReleaseObj( handle ); } - return header != NULL; + LeaveCriticalSection( &gdi_section ); + return entry != NULL; } @@ -668,7 +686,7 @@ static void dump_gdi_objects( void ) } TRACE( "handle %p obj %p type %s selcount %u deleted %u\n", entry_to_handle( entry ), entry->obj, gdi_obj_type( entry->type ), - entry->obj->selcount, entry->obj->deleted ); + entry->selcount, entry->obj->deleted ); } LeaveCriticalSection( &gdi_section ); } @@ -689,7 +707,6 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs /* initialize the object header */ obj->system = 0; obj->deleted = 0; - obj->selcount = 0; EnterCriticalSection( &gdi_section ); for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++) @@ -708,6 +725,7 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs entry->funcs = funcs; entry->hdcs = NULL; entry->type = type; + entry->selcount = 0; next_gdi_handle = i; ret = entry_to_handle( entry ); LeaveCriticalSection( &gdi_section ); @@ -829,9 +847,9 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) hdcs_head = entry->hdcs; entry->hdcs = NULL; - if (entry->obj->selcount) + if (entry->selcount) { - TRACE("delayed for %p because object in use, count %u\n", obj, entry->obj->selcount ); + TRACE("delayed for %p because object in use, count %u\n", obj, entry->selcount ); entry->obj->deleted = 1; /* mark for delete */ } else funcs = entry->funcs;
1
0
0
0
Alexandre Julliard : gdi32: Process the object HDC list outside of the critical section.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: 5f14ff42a80d03200dfd6eca4485bdb0ce75617c URL:
http://source.winehq.org/git/wine.git/?a=commit;h=5f14ff42a80d03200dfd6eca4…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:08:11 2012 +0200 gdi32: Process the object HDC list outside of the critical section. --- dlls/gdi32/gdiobj.c | 37 +++++++++++++++++-------------------- 1 files changed, 17 insertions(+), 20 deletions(-) diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 750e95b..afc0c59 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -810,7 +810,7 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) { struct gdi_handle_entry *entry; struct hdc_list *hdcs_head; - const struct gdi_obj_funcs *funcs; + const struct gdi_obj_funcs *funcs = NULL; EnterCriticalSection( &gdi_section ); if (!(entry = handle_entry( obj ))) @@ -826,41 +826,38 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) return TRUE; } - while ((hdcs_head = entry->hdcs) != NULL) + hdcs_head = entry->hdcs; + entry->hdcs = NULL; + + if (entry->obj->selcount) { + TRACE("delayed for %p because object in use, count %u\n", obj, entry->obj->selcount ); + entry->obj->deleted = 1; /* mark for delete */ + } + else funcs = entry->funcs; + + LeaveCriticalSection( &gdi_section ); + + while (hdcs_head) + { + struct hdc_list *next = hdcs_head->next; DC *dc = get_dc_ptr(hdcs_head->hdc); - entry->hdcs = hdcs_head->next; TRACE("hdc %p has interest in %p\n", hdcs_head->hdc, obj); - if(dc) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pDeleteObject ); - LeaveCriticalSection( &gdi_section ); physdev->funcs->pDeleteObject( physdev, obj ); - EnterCriticalSection( &gdi_section ); /* and grab it again */ - entry = handle_entry( obj ); release_dc_ptr( dc ); } HeapFree(GetProcessHeap(), 0, hdcs_head); - if (!entry) return FALSE; + hdcs_head = next; } - if (entry->obj->selcount) - { - TRACE("delayed for %p because object in use, count %u\n", obj, entry->obj->selcount ); - entry->obj->deleted = 1; /* mark for delete */ - LeaveCriticalSection( &gdi_section ); - return TRUE; - } - - funcs = entry->funcs; - LeaveCriticalSection( &gdi_section ); - TRACE("%p\n", obj ); if (funcs && funcs->pDeleteObject) return funcs->pDeleteObject( obj ); - return FALSE; + return TRUE; } /***********************************************************************
1
0
0
0
Alexandre Julliard : gdi32: Store the HDC list directly in the GDI handle table.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: 2e693d00c9bc38009d305b04b6425ce7b67ceffd URL:
http://source.winehq.org/git/wine.git/?a=commit;h=2e693d00c9bc38009d305b04b…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 13:03:18 2012 +0200 gdi32: Store the HDC list directly in the GDI handle table. --- dlls/gdi32/gdi_private.h | 11 +----- dlls/gdi32/gdiobj.c | 87 ++++++++++++++++++++------------------------- 2 files changed, 41 insertions(+), 57 deletions(-) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 36566b1..5dadbc2 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -57,18 +57,11 @@ struct gdi_obj_funcs BOOL (*pDeleteObject)( HGDIOBJ handle ); }; -struct hdc_list -{ - HDC hdc; - struct hdc_list *next; -}; - typedef struct tagGDIOBJHDR { WORD system : 1; /* system object flag */ WORD deleted : 1; /* whether DeleteObject has been called on this object */ DWORD selcount; /* number of times the object is selected in a DC */ - struct hdc_list *hdcs; } GDIOBJHDR; typedef struct tagGdiFont GdiFont; @@ -325,8 +318,8 @@ extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN; extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN; extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; -extern BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN; -extern BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN; +extern void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN; +extern void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN; /* metafile.c */ extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 2e32de9..750e95b 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -41,10 +41,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); #define FIRST_GDI_HANDLE 16 #define MAX_GDI_HANDLES 16384 +struct hdc_list +{ + HDC hdc; + struct hdc_list *next; +}; + struct gdi_handle_entry { GDIOBJHDR *obj; /* pointer to the object-specific data */ const struct gdi_obj_funcs *funcs; /* type-specific functions */ + struct hdc_list *hdcs; /* list of HDCs interested in this object */ WORD type; /* object type (one of the OBJ_* constants) */ }; @@ -683,7 +690,6 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs obj->system = 0; obj->deleted = 0; obj->selcount = 0; - obj->hdcs = NULL; EnterCriticalSection( &gdi_section ); for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++) @@ -700,6 +706,7 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs entry = &gdi_handles[i]; entry->obj = obj; entry->funcs = funcs; + entry->hdcs = NULL; entry->type = type; next_gdi_handle = i; ret = entry_to_handle( entry ); @@ -819,11 +826,11 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) return TRUE; } - while ((hdcs_head = entry->obj->hdcs) != NULL) + while ((hdcs_head = entry->hdcs) != NULL) { DC *dc = get_dc_ptr(hdcs_head->hdc); - entry->obj->hdcs = hdcs_head->next; + entry->hdcs = hdcs_head->next; TRACE("hdc %p has interest in %p\n", hdcs_head->hdc, obj); if(dc) @@ -861,70 +868,54 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj ) * * Call this if the dc requires DeleteObject notification */ -BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) +void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) { - GDIOBJHDR * header; - struct hdc_list **pphdc; + struct gdi_handle_entry *entry; + struct hdc_list *phdc; TRACE("obj %p hdc %p\n", obj, hdc); - if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE; - - if (header->system) + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( obj )) && !entry->obj->system) { - GDI_ReleaseObj(obj); - return FALSE; - } - - for(pphdc = &header->hdcs; *pphdc; pphdc = &(*pphdc)->next) - if((*pphdc)->hdc == hdc) - break; + for (phdc = entry->hdcs; phdc; phdc = phdc->next) + if (phdc->hdc == hdc) break; - if(!*pphdc) { - *pphdc = HeapAlloc(GetProcessHeap(), 0, sizeof(**pphdc)); - (*pphdc)->hdc = hdc; - (*pphdc)->next = NULL; + if (!phdc) + { + phdc = HeapAlloc(GetProcessHeap(), 0, sizeof(*phdc)); + phdc->hdc = hdc; + phdc->next = entry->hdcs; + entry->hdcs = phdc; + } } - - GDI_ReleaseObj(obj); - return TRUE; + LeaveCriticalSection( &gdi_section ); } /*********************************************************************** * GDI_hdc_not_using_object * */ -BOOL GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) +void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) { - GDIOBJHDR * header; - struct hdc_list *phdc, **prev; + struct gdi_handle_entry *entry; + struct hdc_list **pphdc; TRACE("obj %p hdc %p\n", obj, hdc); - if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE; - - if (header->system) + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( obj )) && !entry->obj->system) { - GDI_ReleaseObj(obj); - return FALSE; + for (pphdc = &entry->hdcs; *pphdc; pphdc = &(*pphdc)->next) + if ((*pphdc)->hdc == hdc) + { + struct hdc_list *phdc = *pphdc; + *pphdc = phdc->next; + HeapFree(GetProcessHeap(), 0, phdc); + break; + } } - - phdc = header->hdcs; - prev = &header->hdcs; - - while(phdc) { - if(phdc->hdc == hdc) { - *prev = phdc->next; - HeapFree(GetProcessHeap(), 0, phdc); - phdc = *prev; - } else { - prev = &phdc->next; - phdc = phdc->next; - } - } - - GDI_ReleaseObj(obj); - return TRUE; + LeaveCriticalSection( &gdi_section ); } /***********************************************************************
1
0
0
0
Alexandre Julliard : gdi32: Store the object function table directly in the GDI handle table.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: cf3cafdc18d1f839f67e0237cfbb608944746b1d URL:
http://source.winehq.org/git/wine.git/?a=commit;h=cf3cafdc18d1f839f67e0237c…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 12:43:23 2012 +0200 gdi32: Store the object function table directly in the GDI handle table. --- dlls/gdi32/gdi_private.h | 1 - dlls/gdi32/gdiobj.c | 133 +++++++++++++++++++++------------------------- 2 files changed, 60 insertions(+), 74 deletions(-) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 9c926d4..36566b1 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -68,7 +68,6 @@ typedef struct tagGDIOBJHDR WORD system : 1; /* system object flag */ WORD deleted : 1; /* whether DeleteObject has been called on this object */ DWORD selcount; /* number of times the object is selected in a DC */ - const struct gdi_obj_funcs *funcs; struct hdc_list *hdcs; } GDIOBJHDR; diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 0cd182a..2e32de9 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -44,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); struct gdi_handle_entry { GDIOBJHDR *obj; /* pointer to the object-specific data */ + const struct gdi_obj_funcs *funcs; /* type-specific functions */ WORD type; /* object type (one of the OBJ_* constants) */ }; @@ -682,7 +683,6 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs obj->system = 0; obj->deleted = 0; obj->selcount = 0; - obj->funcs = funcs; obj->hdcs = NULL; EnterCriticalSection( &gdi_section ); @@ -699,6 +699,7 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs found: entry = &gdi_handles[i]; entry->obj = obj; + entry->funcs = funcs; entry->type = type; next_gdi_handle = i; ret = entry_to_handle( entry ); @@ -728,11 +729,6 @@ void *free_gdi_handle( HGDIOBJ handle ) entry->type = 0; } LeaveCriticalSection( &gdi_section ); - - if (object) - { - object->funcs = NULL; - } return object; } @@ -805,60 +801,59 @@ void GDI_CheckNotLock(void) */ BOOL WINAPI DeleteObject( HGDIOBJ obj ) { - /* Check if object is valid */ - + struct gdi_handle_entry *entry; struct hdc_list *hdcs_head; const struct gdi_obj_funcs *funcs; - GDIOBJHDR * header; - - if (HIWORD(obj)) return FALSE; - if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE; + EnterCriticalSection( &gdi_section ); + if (!(entry = handle_entry( obj ))) + { + LeaveCriticalSection( &gdi_section ); + return FALSE; + } - if (header->system) + if (entry->obj->system) { TRACE("Preserving system object %p\n", obj); - GDI_ReleaseObj( obj ); + LeaveCriticalSection( &gdi_section ); return TRUE; } - while ((hdcs_head = header->hdcs) != NULL) + while ((hdcs_head = entry->obj->hdcs) != NULL) { DC *dc = get_dc_ptr(hdcs_head->hdc); - header->hdcs = hdcs_head->next; + entry->obj->hdcs = hdcs_head->next; TRACE("hdc %p has interest in %p\n", hdcs_head->hdc, obj); if(dc) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pDeleteObject ); - GDI_ReleaseObj( obj ); /* release the GDI lock */ + LeaveCriticalSection( &gdi_section ); physdev->funcs->pDeleteObject( physdev, obj ); - header = GDI_GetObjPtr( obj, 0 ); /* and grab it again */ + EnterCriticalSection( &gdi_section ); /* and grab it again */ + entry = handle_entry( obj ); release_dc_ptr( dc ); } HeapFree(GetProcessHeap(), 0, hdcs_head); - if (!header) return FALSE; + if (!entry) return FALSE; } - if (header->selcount) + if (entry->obj->selcount) { - TRACE("delayed for %p because object in use, count %u\n", obj, header->selcount ); - header->deleted = 1; /* mark for delete */ - GDI_ReleaseObj( obj ); + TRACE("delayed for %p because object in use, count %u\n", obj, entry->obj->selcount ); + entry->obj->deleted = 1; /* mark for delete */ + LeaveCriticalSection( &gdi_section ); return TRUE; } - TRACE("%p\n", obj ); + funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - /* Delete object */ + TRACE("%p\n", obj ); - funcs = header->funcs; - GDI_ReleaseObj( obj ); - if (funcs && funcs->pDeleteObject) - return funcs->pDeleteObject( obj ); - else - return FALSE; + if (funcs && funcs->pDeleteObject) return funcs->pDeleteObject( obj ); + return FALSE; } /*********************************************************************** @@ -950,26 +945,25 @@ HGDIOBJ WINAPI GetStockObject( INT obj ) */ INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer ) { - const struct gdi_obj_funcs *funcs; - GDIOBJHDR * ptr; + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; INT result = 0; TRACE("%p %d %p\n", handle, count, buffer ); - if (!(ptr = GDI_GetObjPtr( handle, 0 ))) return 0; - funcs = ptr->funcs; - GDI_ReleaseObj( handle ); + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - if (funcs && funcs->pGetObjectA) + if (funcs) { - if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ + if (!funcs->pGetObjectA) + SetLastError( ERROR_INVALID_HANDLE ); + else if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ SetLastError( ERROR_NOACCESS ); else result = funcs->pGetObjectA( handle, count, buffer ); } - else - SetLastError( ERROR_INVALID_HANDLE ); - return result; } @@ -978,25 +972,25 @@ INT WINAPI GetObjectA( HGDIOBJ handle, INT count, LPVOID buffer ) */ INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ) { - const struct gdi_obj_funcs *funcs; - GDIOBJHDR * ptr; + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; INT result = 0; + TRACE("%p %d %p\n", handle, count, buffer ); - if (!(ptr = GDI_GetObjPtr( handle, 0 ))) return 0; - funcs = ptr->funcs; - GDI_ReleaseObj( handle ); + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - if (funcs && funcs->pGetObjectW) + if (funcs) { - if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ + if (!funcs->pGetObjectW) + SetLastError( ERROR_INVALID_HANDLE ); + else if (buffer && ((ULONG_PTR)buffer >> 16) == 0) /* catch apps getting argument order wrong */ SetLastError( ERROR_NOACCESS ); else result = funcs->pGetObjectW( handle, count, buffer ); } - else - SetLastError( ERROR_INVALID_HANDLE ); - return result; } @@ -1083,19 +1077,17 @@ HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type) */ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj ) { - HGDIOBJ ret = 0; - GDIOBJHDR *header; + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; TRACE( "(%p,%p)\n", hdc, hObj ); - header = GDI_GetObjPtr( hObj, 0 ); - if (header) - { - const struct gdi_obj_funcs *funcs = header->funcs; - GDI_ReleaseObj( hObj ); - if (funcs && funcs->pSelectObject) ret = funcs->pSelectObject( hObj, hdc ); - } - return ret; + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( hObj ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); + + if (funcs && funcs->pSelectObject) return funcs->pSelectObject( hObj, hdc ); + return 0; } @@ -1104,20 +1096,15 @@ HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj ) */ BOOL WINAPI UnrealizeObject( HGDIOBJ obj ) { - BOOL result = FALSE; - GDIOBJHDR * header = GDI_GetObjPtr( obj, 0 ); + struct gdi_handle_entry *entry; + const struct gdi_obj_funcs *funcs = NULL; - if (header) - { - const struct gdi_obj_funcs *funcs = header->funcs; + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( obj ))) funcs = entry->funcs; + LeaveCriticalSection( &gdi_section ); - GDI_ReleaseObj( obj ); - if (funcs && funcs->pUnrealizeObject) - result = header->funcs->pUnrealizeObject( obj ); - else - result = TRUE; - } - return result; + if (funcs && funcs->pUnrealizeObject) return funcs->pUnrealizeObject( obj ); + return funcs != NULL; }
1
0
0
0
Alexandre Julliard : gdi32: Store the object type directly in the GDI handle table.
by Alexandre Julliard
17 Oct '12
17 Oct '12
Module: wine Branch: master Commit: 2bdf447744b3d380ed266e7627976612ec58ffe2 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=2bdf447744b3d380ed266e762…
Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Oct 17 12:25:28 2012 +0200 gdi32: Store the object type directly in the GDI handle table. --- dlls/gdi32/dc.c | 14 +++-- dlls/gdi32/enhmfdrv/init.c | 2 +- dlls/gdi32/gdi_private.h | 1 - dlls/gdi32/gdiobj.c | 114 +++++++++++++++++++++++-------------------- dlls/gdi32/mfdrv/init.c | 2 +- dlls/gdi32/pen.c | 4 +- 6 files changed, 73 insertions(+), 64 deletions(-) diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 1f089de..5a68aa6 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -55,16 +55,18 @@ static inline DC *get_dc_obj( HDC hdc ) DC *dc = GDI_GetObjPtr( hdc, 0 ); if (!dc) return NULL; - if ((dc->header.type != OBJ_DC) && - (dc->header.type != OBJ_MEMDC) && - (dc->header.type != OBJ_METADC) && - (dc->header.type != OBJ_ENHMETADC)) + switch (GetObjectType( hdc )) { + case OBJ_DC: + case OBJ_MEMDC: + case OBJ_METADC: + case OBJ_ENHMETADC: + return dc; + default: GDI_ReleaseObj( hdc ); SetLastError( ERROR_INVALID_HANDLE ); - dc = NULL; + return NULL; } - return dc; } diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index bd4c906..57a4d18 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -435,7 +435,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ TRACE("(%p)\n", hdc ); if (!(dc = get_dc_ptr( hdc ))) return NULL; - if (dc->header.type != OBJ_ENHMETADC) + if (GetObjectType( hdc ) != OBJ_ENHMETADC) { release_dc_ptr( dc ); return NULL; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 5b79526..9c926d4 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -65,7 +65,6 @@ struct hdc_list typedef struct tagGDIOBJHDR { - WORD type; /* object type (one of the OBJ_* constants) */ WORD system : 1; /* system object flag */ WORD deleted : 1; /* whether DeleteObject has been called on this object */ DWORD selcount; /* number of times the object is selected in a DC */ diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c index 9da5533..0cd182a 100644 --- a/dlls/gdi32/gdiobj.c +++ b/dlls/gdi32/gdiobj.c @@ -38,12 +38,34 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi); -#define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16)) +#define FIRST_GDI_HANDLE 16 +#define MAX_GDI_HANDLES 16384 -#define GDI_HEAP_SIZE 0xffe0 +struct gdi_handle_entry +{ + GDIOBJHDR *obj; /* pointer to the object-specific data */ + WORD type; /* object type (one of the OBJ_* constants) */ +}; +static struct gdi_handle_entry gdi_handles[MAX_GDI_HANDLES]; +static int next_gdi_handle; +static LONG debug_count; HMODULE gdi32_module = 0; +static inline HGDIOBJ entry_to_handle( struct gdi_handle_entry *entry ) +{ + unsigned int idx = entry - gdi_handles + FIRST_GDI_HANDLE; + return ULongToHandle( idx << 2 ); +} + +static inline struct gdi_handle_entry *handle_entry( HGDIOBJ handle ) +{ + unsigned int idx = (HandleToULong(handle) >> 2) - FIRST_GDI_HANDLE; + + if (idx < MAX_GDI_HANDLES && gdi_handles[idx].type) return &gdi_handles[idx]; + return NULL; +} + /*********************************************************************** * GDI stock objects */ @@ -600,22 +622,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) return TRUE; } -#define FIRST_GDI_HANDLE 16 -#define MAX_GDI_HANDLES ((GDI_HEAP_SIZE >> 2) - FIRST_GDI_HANDLE) -static GDIOBJHDR *gdi_handles[MAX_GDI_HANDLES]; -static int next_gdi_handle; -static LONG debug_count; - -static inline HGDIOBJ index_to_handle( int index ) -{ - return ULongToHandle( (index + FIRST_GDI_HANDLE) << 2); -} - -static inline int handle_to_index( HGDIOBJ handle ) -{ - return (HandleToULong(handle) >> 2) - FIRST_GDI_HANDLE; -} - static const char *gdi_obj_type( unsigned type ) { switch ( type ) @@ -640,21 +646,21 @@ static const char *gdi_obj_type( unsigned type ) static void dump_gdi_objects( void ) { - int i; + struct gdi_handle_entry *entry; TRACE( "%u objects:\n", MAX_GDI_HANDLES ); EnterCriticalSection( &gdi_section ); - for (i = 0; i < MAX_GDI_HANDLES; i++) + for (entry = gdi_handles; entry < gdi_handles + MAX_GDI_HANDLES; entry++) { - if (!gdi_handles[i]) + if (!entry->type) { - TRACE( "index %d handle %p FREE\n", i, index_to_handle( i )); + TRACE( "handle %p FREE\n", entry_to_handle( entry )); continue; } TRACE( "handle %p obj %p type %s selcount %u deleted %u\n", - index_to_handle( i ), gdi_handles[i], gdi_obj_type( gdi_handles[i]->type ), - gdi_handles[i]->selcount, gdi_handles[i]->deleted ); + entry_to_handle( entry ), entry->obj, gdi_obj_type( entry->type ), + entry->obj->selcount, entry->obj->deleted ); } LeaveCriticalSection( &gdi_section ); } @@ -666,10 +672,13 @@ static void dump_gdi_objects( void ) */ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) { + struct gdi_handle_entry *entry; + HGDIOBJ ret; int i; + assert( type ); /* type 0 is reserved to mark free entries */ + /* initialize the object header */ - obj->type = type; obj->system = 0; obj->deleted = 0; obj->selcount = 0; @@ -678,9 +687,9 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs EnterCriticalSection( &gdi_section ); for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++) - if (!gdi_handles[i]) goto found; + if (!gdi_handles[i].type) goto found; for (i = 0; i <= next_gdi_handle; i++) - if (!gdi_handles[i]) goto found; + if (!gdi_handles[i].type) goto found; LeaveCriticalSection( &gdi_section ); ERR( "out of GDI object handles, expect a crash\n" ); @@ -688,13 +697,15 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs return 0; found: - gdi_handles[i] = obj; + entry = &gdi_handles[i]; + entry->obj = obj; + entry->type = type; next_gdi_handle = i; + ret = entry_to_handle( entry ); LeaveCriticalSection( &gdi_section ); - TRACE( "allocated %s %p %u/%u\n", - gdi_obj_type(type), index_to_handle( i ), + TRACE( "allocated %s %p %u/%u\n", gdi_obj_type(type), ret, InterlockedIncrement( &debug_count ), MAX_GDI_HANDLES ); - return index_to_handle( i ); + return ret; } @@ -706,20 +717,20 @@ HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs void *free_gdi_handle( HGDIOBJ handle ) { GDIOBJHDR *object = NULL; - int i = handle_to_index( handle ); + struct gdi_handle_entry *entry; - if (i >= 0 && i < MAX_GDI_HANDLES) + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) { - EnterCriticalSection( &gdi_section ); - object = gdi_handles[i]; - gdi_handles[i] = NULL; - LeaveCriticalSection( &gdi_section ); + TRACE( "freed %s %p %u/%u\n", gdi_obj_type( entry->type ), handle, + InterlockedDecrement( &debug_count ) + 1, MAX_GDI_HANDLES ); + object = entry->obj; + entry->type = 0; } + LeaveCriticalSection( &gdi_section ); + if (object) { - TRACE( "freed %s %p %u/%u\n", gdi_obj_type( object->type ), handle, - InterlockedDecrement( &debug_count ) + 1, MAX_GDI_HANDLES ); - object->type = 0; /* mark it as invalid */ object->funcs = NULL; } return object; @@ -736,14 +747,13 @@ void *free_gdi_handle( HGDIOBJ handle ) void *GDI_GetObjPtr( HGDIOBJ handle, WORD type ) { GDIOBJHDR *ptr = NULL; - int i = handle_to_index( handle ); + struct gdi_handle_entry *entry; EnterCriticalSection( &gdi_section ); - if (i >= 0 && i < MAX_GDI_HANDLES) + if ((entry = handle_entry( handle ))) { - ptr = gdi_handles[i]; - if (ptr && type && ptr->type != type) ptr = NULL; + if (!type || entry->type == type) ptr = entry->obj; } if (!ptr) @@ -995,17 +1005,15 @@ INT WINAPI GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ) */ DWORD WINAPI GetObjectType( HGDIOBJ handle ) { - GDIOBJHDR * ptr; - DWORD result; + struct gdi_handle_entry *entry; + DWORD result = 0; + + EnterCriticalSection( &gdi_section ); + if ((entry = handle_entry( handle ))) result = entry->type; + LeaveCriticalSection( &gdi_section ); - if (!(ptr = GDI_GetObjPtr( handle, 0 ))) - { - SetLastError( ERROR_INVALID_HANDLE ); - return 0; - } - result = ptr->type; - GDI_ReleaseObj( handle ); TRACE("%p -> %u\n", handle, result ); + if (!result) SetLastError( ERROR_INVALID_HANDLE ); return result; } diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c index f75637c..03cd22c 100644 --- a/dlls/gdi32/mfdrv/init.c +++ b/dlls/gdi32/mfdrv/init.c @@ -390,7 +390,7 @@ static DC *MFDRV_CloseMetaFile( HDC hdc ) TRACE("(%p)\n", hdc ); if (!(dc = get_dc_ptr( hdc ))) return NULL; - if (dc->header.type != OBJ_METADC) + if (GetObjectType( hdc ) != OBJ_METADC) { release_dc_ptr( dc ); return NULL; diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c index 6695ee9..94c3933 100644 --- a/dlls/gdi32/pen.c +++ b/dlls/gdi32/pen.c @@ -236,7 +236,7 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc ) struct brush_pattern *pattern; PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectPen ); - switch (pen->header.type) + switch (GetObjectType( handle )) { case OBJ_PEN: pattern = NULL; @@ -293,7 +293,7 @@ static INT PEN_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ) if (!pen) return 0; - switch (pen->header.type) + switch (GetObjectType( handle )) { case OBJ_PEN: {
1
0
0
0
← Newer
1
...
39
40
41
42
43
44
45
...
96
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
Results per page:
10
25
50
100
200