Added XrStatusInvalidRestore. Fixed XrSurface memory leak.

This commit is contained in:
Carl Worth 2002-10-28 09:00:10 +00:00
parent 84da6c1f7f
commit f64ebf489b
13 changed files with 113 additions and 52 deletions

View file

@ -1,3 +1,12 @@
2002-10-28 Carl Worth <cworth@east.isi.edu>
* xrstate.c (_XrStatePop): Added error case for XrRestore without
matching XrSave.
* xrsurface.c (_XrSurfaceInit, _XrSurfaceReference)
(_XrSurfaceDereference): Added reference counting to XrSurface to
patch a memory leak.
2002-10-26 Carl Worth <cworth@isi.edu>
* xrtransform.c (_XrTransformDistance):

3
Xr.h
View file

@ -200,7 +200,8 @@ XrShowText(XrState *xrs, const char *utf8);
typedef enum _XrStatus {
XrStatusSuccess = 0,
XrStatusNoMemory
XrStatusNoMemory,
XrStatusInvalidRestore
} XrStatus;
XrStatus

View file

@ -200,7 +200,8 @@ XrShowText(XrState *xrs, const char *utf8);
typedef enum _XrStatus {
XrStatusSuccess = 0,
XrStatusNoMemory
XrStatusNoMemory,
XrStatusInvalidRestore
} XrStatus;
XrStatus

View file

@ -56,9 +56,6 @@ XrSave(XrState *xrs)
void
XrRestore(XrState *xrs)
{
/* XXX: BUG: Calling XrRestore without a matching XrSave shoud
flag an error. Also, in order to prevent crashes, XrStatePop
should not be called in that case. */
if (xrs->status)
return;

View file

@ -65,8 +65,8 @@ _XrGStateInit(XrGState *gstate, Display *dpy)
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
_XrSurfaceInit(&gstate->surface, dpy);
_XrSurfaceInit(&gstate->src, dpy);
_XrColorInit(&gstate->color);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
@ -93,8 +93,8 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
memcpy (gstate->dashes, other->dashes, other->ndashes * sizeof (double));
}
_XrSurfaceInit(&gstate->src, gstate->dpy);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceReference(&gstate->surface);
_XrSurfaceReference(&gstate->src);
status = _XrPathInitCopy(&gstate->path, &other->path);
if (status)
@ -118,9 +118,11 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
void
_XrGStateDeinit(XrGState *gstate)
{
_XrSurfaceDereference(&gstate->src);
_XrSurfaceDereference(&gstate->surface);
_XrColorDeinit(&gstate->color);
_XrSurfaceDeinit(&gstate->src);
_XrSurfaceDeinit(&gstate->surface);
_XrTransformDeinit(&gstate->ctm);
_XrTransformDeinit(&gstate->ctm_inverse);
@ -563,7 +565,16 @@ _XrGStateFill(XrGState *gstate)
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8)
{
/* XXX: NYI */
/*
XftDrawStringUtf8(gstate->xft_draw,
gstate->xft_color,
gstate->font,
gstate->current_pt.x,
gstate->current_pt.y,
utf8,
strlen(utf8));
*/
return XrStatusSuccess;
}

View file

@ -175,7 +175,8 @@ typedef struct _XrSurface {
XcFormat *xcformat;
XcSurface *xcsurface;
XcSurface *alpha;
unsigned int ref_count;
} XrSurface;
typedef struct _XrColor {
@ -454,6 +455,12 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
void
_XrSurfaceInit(XrSurface *surface, Display *dpy);
void
_XrSurfaceReference(XrSurface *surface);
void
_XrSurfaceDereference(XrSurface *surface);
void
_XrSurfaceDeinit(XrSurface *surface);

View file

@ -95,12 +95,13 @@ _XrStatePop(XrState *xrs)
{
XrGState *top;
if (xrs->stack) {
top = xrs->stack;
xrs->stack = top->next;
if (xrs->stack == NULL)
return XrStatusInvalidRestore;
_XrGStateDestroy(top);
}
top = xrs->stack;
xrs->stack = top->next;
_XrGStateDestroy(top);
return XrStatusSuccess;
}

View file

@ -45,21 +45,30 @@ _XrSurfaceInit(XrSurface *surface, Display *dpy)
surface->xcformat = 0;
surface->xcsurface = 0;
surface->alpha = 0;
surface->ref_count = 0;
}
void
_XrSurfaceReference(XrSurface *surface)
{
surface->ref_count++;
}
void
_XrSurfaceDereference(XrSurface *surface)
{
if (surface->ref_count == 0)
_XrSurfaceDeinit(surface);
else
surface->ref_count--;
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
/* XXX: BUG: I'm not sure how to correctly deal with this. With the
semantics of XrSave, we can share the surface, but we do want
the last one freed eventually. Maybe I can reference count --
or maybe I can free the surface when I finally push to the
bottom of the stack.
if (surface->surface) {
XcFreeSurface(surface->dpy, surface->surface);
} */
if (surface->xcsurface)
XcFreeSurface(surface->dpy, surface->xcsurface);
}
void

3
xr.c
View file

@ -56,9 +56,6 @@ XrSave(XrState *xrs)
void
XrRestore(XrState *xrs)
{
/* XXX: BUG: Calling XrRestore without a matching XrSave shoud
flag an error. Also, in order to prevent crashes, XrStatePop
should not be called in that case. */
if (xrs->status)
return;

View file

@ -65,8 +65,8 @@ _XrGStateInit(XrGState *gstate, Display *dpy)
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
_XrSurfaceInit(&gstate->surface, dpy);
_XrSurfaceInit(&gstate->src, dpy);
_XrColorInit(&gstate->color);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
@ -93,8 +93,8 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
memcpy (gstate->dashes, other->dashes, other->ndashes * sizeof (double));
}
_XrSurfaceInit(&gstate->src, gstate->dpy);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceReference(&gstate->surface);
_XrSurfaceReference(&gstate->src);
status = _XrPathInitCopy(&gstate->path, &other->path);
if (status)
@ -118,9 +118,11 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
void
_XrGStateDeinit(XrGState *gstate)
{
_XrSurfaceDereference(&gstate->src);
_XrSurfaceDereference(&gstate->surface);
_XrColorDeinit(&gstate->color);
_XrSurfaceDeinit(&gstate->src);
_XrSurfaceDeinit(&gstate->surface);
_XrTransformDeinit(&gstate->ctm);
_XrTransformDeinit(&gstate->ctm_inverse);
@ -563,7 +565,16 @@ _XrGStateFill(XrGState *gstate)
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8)
{
/* XXX: NYI */
/*
XftDrawStringUtf8(gstate->xft_draw,
gstate->xft_color,
gstate->font,
gstate->current_pt.x,
gstate->current_pt.y,
utf8,
strlen(utf8));
*/
return XrStatusSuccess;
}

View file

@ -175,7 +175,8 @@ typedef struct _XrSurface {
XcFormat *xcformat;
XcSurface *xcsurface;
XcSurface *alpha;
unsigned int ref_count;
} XrSurface;
typedef struct _XrColor {
@ -454,6 +455,12 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
void
_XrSurfaceInit(XrSurface *surface, Display *dpy);
void
_XrSurfaceReference(XrSurface *surface);
void
_XrSurfaceDereference(XrSurface *surface);
void
_XrSurfaceDeinit(XrSurface *surface);

View file

@ -95,12 +95,13 @@ _XrStatePop(XrState *xrs)
{
XrGState *top;
if (xrs->stack) {
top = xrs->stack;
xrs->stack = top->next;
if (xrs->stack == NULL)
return XrStatusInvalidRestore;
_XrGStateDestroy(top);
}
top = xrs->stack;
xrs->stack = top->next;
_XrGStateDestroy(top);
return XrStatusSuccess;
}

View file

@ -45,21 +45,30 @@ _XrSurfaceInit(XrSurface *surface, Display *dpy)
surface->xcformat = 0;
surface->xcsurface = 0;
surface->alpha = 0;
surface->ref_count = 0;
}
void
_XrSurfaceReference(XrSurface *surface)
{
surface->ref_count++;
}
void
_XrSurfaceDereference(XrSurface *surface)
{
if (surface->ref_count == 0)
_XrSurfaceDeinit(surface);
else
surface->ref_count--;
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
/* XXX: BUG: I'm not sure how to correctly deal with this. With the
semantics of XrSave, we can share the surface, but we do want
the last one freed eventually. Maybe I can reference count --
or maybe I can free the surface when I finally push to the
bottom of the stack.
if (surface->surface) {
XcFreeSurface(surface->dpy, surface->surface);
} */
if (surface->xcsurface)
XcFreeSurface(surface->dpy, surface->xcsurface);
}
void