forked from Mirrors/wine-wine
gdi32: Store the HDC list directly in the GDI handle table.
parent
cf3cafdc18
commit
2e693d00c9
|
@ -57,18 +57,11 @@ struct gdi_obj_funcs
|
||||||
BOOL (*pDeleteObject)( HGDIOBJ handle );
|
BOOL (*pDeleteObject)( HGDIOBJ handle );
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hdc_list
|
|
||||||
{
|
|
||||||
HDC hdc;
|
|
||||||
struct hdc_list *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct tagGDIOBJHDR
|
typedef struct tagGDIOBJHDR
|
||||||
{
|
{
|
||||||
WORD system : 1; /* system object flag */
|
WORD system : 1; /* system object flag */
|
||||||
WORD deleted : 1; /* whether DeleteObject has been called on this object */
|
WORD deleted : 1; /* whether DeleteObject has been called on this object */
|
||||||
DWORD selcount; /* number of times the object is selected in a DC */
|
DWORD selcount; /* number of times the object is selected in a DC */
|
||||||
struct hdc_list *hdcs;
|
|
||||||
} GDIOBJHDR;
|
} GDIOBJHDR;
|
||||||
|
|
||||||
typedef struct tagGdiFont GdiFont;
|
typedef struct tagGdiFont GdiFont;
|
||||||
|
@ -325,8 +318,8 @@ extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
|
||||||
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
|
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
|
||||||
extern HGDIOBJ GDI_inc_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 BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
|
extern void 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_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* metafile.c */
|
/* metafile.c */
|
||||||
extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) DECLSPEC_HIDDEN;
|
extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -41,10 +41,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdi);
|
||||||
#define FIRST_GDI_HANDLE 16
|
#define FIRST_GDI_HANDLE 16
|
||||||
#define MAX_GDI_HANDLES 16384
|
#define MAX_GDI_HANDLES 16384
|
||||||
|
|
||||||
|
struct hdc_list
|
||||||
|
{
|
||||||
|
HDC hdc;
|
||||||
|
struct hdc_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct gdi_handle_entry
|
struct gdi_handle_entry
|
||||||
{
|
{
|
||||||
GDIOBJHDR *obj; /* pointer to the object-specific data */
|
GDIOBJHDR *obj; /* pointer to the object-specific data */
|
||||||
const struct gdi_obj_funcs *funcs; /* type-specific functions */
|
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 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->system = 0;
|
||||||
obj->deleted = 0;
|
obj->deleted = 0;
|
||||||
obj->selcount = 0;
|
obj->selcount = 0;
|
||||||
obj->hdcs = NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection( &gdi_section );
|
EnterCriticalSection( &gdi_section );
|
||||||
for (i = next_gdi_handle + 1; i < MAX_GDI_HANDLES; i++)
|
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 = &gdi_handles[i];
|
||||||
entry->obj = obj;
|
entry->obj = obj;
|
||||||
entry->funcs = funcs;
|
entry->funcs = funcs;
|
||||||
|
entry->hdcs = NULL;
|
||||||
entry->type = type;
|
entry->type = type;
|
||||||
next_gdi_handle = i;
|
next_gdi_handle = i;
|
||||||
ret = entry_to_handle( entry );
|
ret = entry_to_handle( entry );
|
||||||
|
@ -819,11 +826,11 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((hdcs_head = entry->obj->hdcs) != NULL)
|
while ((hdcs_head = entry->hdcs) != NULL)
|
||||||
{
|
{
|
||||||
DC *dc = get_dc_ptr(hdcs_head->hdc);
|
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);
|
TRACE("hdc %p has interest in %p\n", hdcs_head->hdc, obj);
|
||||||
|
|
||||||
if(dc)
|
if(dc)
|
||||||
|
@ -861,70 +868,54 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
|
||||||
*
|
*
|
||||||
* Call this if the dc requires DeleteObject notification
|
* 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 gdi_handle_entry *entry;
|
||||||
struct hdc_list **pphdc;
|
struct hdc_list *phdc;
|
||||||
|
|
||||||
TRACE("obj %p hdc %p\n", obj, hdc);
|
TRACE("obj %p hdc %p\n", obj, hdc);
|
||||||
|
|
||||||
if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE;
|
EnterCriticalSection( &gdi_section );
|
||||||
|
if ((entry = handle_entry( obj )) && !entry->obj->system)
|
||||||
if (header->system)
|
|
||||||
{
|
{
|
||||||
GDI_ReleaseObj(obj);
|
for (phdc = entry->hdcs; phdc; phdc = phdc->next)
|
||||||
return FALSE;
|
if (phdc->hdc == hdc) break;
|
||||||
|
|
||||||
|
if (!phdc)
|
||||||
|
{
|
||||||
|
phdc = HeapAlloc(GetProcessHeap(), 0, sizeof(*phdc));
|
||||||
|
phdc->hdc = hdc;
|
||||||
|
phdc->next = entry->hdcs;
|
||||||
|
entry->hdcs = phdc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection( &gdi_section );
|
||||||
for(pphdc = &header->hdcs; *pphdc; pphdc = &(*pphdc)->next)
|
|
||||||
if((*pphdc)->hdc == hdc)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!*pphdc) {
|
|
||||||
*pphdc = HeapAlloc(GetProcessHeap(), 0, sizeof(**pphdc));
|
|
||||||
(*pphdc)->hdc = hdc;
|
|
||||||
(*pphdc)->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDI_ReleaseObj(obj);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GDI_hdc_not_using_object
|
* 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 gdi_handle_entry *entry;
|
||||||
struct hdc_list *phdc, **prev;
|
struct hdc_list **pphdc;
|
||||||
|
|
||||||
TRACE("obj %p hdc %p\n", obj, hdc);
|
TRACE("obj %p hdc %p\n", obj, hdc);
|
||||||
|
|
||||||
if (!(header = GDI_GetObjPtr( obj, 0 ))) return FALSE;
|
EnterCriticalSection( &gdi_section );
|
||||||
|
if ((entry = handle_entry( obj )) && !entry->obj->system)
|
||||||
if (header->system)
|
|
||||||
{
|
{
|
||||||
GDI_ReleaseObj(obj);
|
for (pphdc = &entry->hdcs; *pphdc; pphdc = &(*pphdc)->next)
|
||||||
return FALSE;
|
if ((*pphdc)->hdc == hdc)
|
||||||
|
{
|
||||||
|
struct hdc_list *phdc = *pphdc;
|
||||||
|
*pphdc = phdc->next;
|
||||||
|
HeapFree(GetProcessHeap(), 0, phdc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection( &gdi_section );
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue