From 44d33b6fec1e7f0019d31d7a7fbc9688659c3435 Mon Sep 17 00:00:00 2001 From: Michael Jennings Date: Sun, 17 Sep 2000 18:35:14 +0000 Subject: [PATCH] Sun Sep 17 11:51:16 PDT 2000 Michael Jennings Added ability to track Imlib2-created pixmaps via libmej. SVN revision: 3507 --- ChangeLog | 5 +++ libmej/libmej.h | 14 +++++++++ libmej/mem.c | 84 +++++++++++++++++++++++++++++++++++-------------- src/pixmap.c | 3 ++ src/pixmap.h | 4 +-- 5 files changed, 83 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index f319358..b99c90f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3892,3 +3892,8 @@ Fri Sep 15 14:48:51 PDT 2000 Michael Jennings . ------------------------------------------------------------------------------- +Sun Sep 17 11:51:16 PDT 2000 Michael Jennings + + Added ability to track Imlib2-created pixmaps via libmej. + +------------------------------------------------------------------------------- diff --git a/libmej/libmej.h b/libmej/libmej.h index 501c48e..fa61f79 100644 --- a/libmej/libmej.h +++ b/libmej/libmej.h @@ -230,6 +230,13 @@ typedef struct memrec_struct { # define MALLOC_DUMP() libmej_dump_mem_tables() # define X_CREATE_PIXMAP(d, win, w, h, depth) libmej_x_create_pixmap(__FILE__, __LINE__, (d), (win), (w), (h), (depth)) # define X_FREE_PIXMAP(d, p) libmej_x_free_pixmap(#p, __FILE__, __LINE__, (d), (p)) +# ifdef HAVE_LIBIMLIB2 +# define IMLIB_REGISTER_PIXMAP(p) libmej_imlib_register_pixmap(#p, __FILE__, __LINE__, (p)) +# define IMLIB_FREE_PIXMAP(p) libmej_imlib_free_pixmap(#p, __FILE__, __LINE__, (p)) +# else +# define IMLIB_REGISTER_PIXMAP(p) NOP +# define IMLIB_FREE_PIXMAP(p) NOP +# endif # define PIXMAP_DUMP() libmej_dump_pixmap_tables() # define X_CREATE_GC(d, win, f, gcv) libmej_x_create_gc(__FILE__, __LINE__, (d), (win), (f), (gcv)) # define X_FREE_GC(d, gc) libmej_x_free_gc(#gc, __FILE__, __LINE__, (d), (gc)) @@ -247,6 +254,13 @@ typedef struct memrec_struct { # define MALLOC_DUMP() NOP # define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth)) # define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p)) +# ifdef HAVE_LIBIMLIB2 +# define IMLIB_REGISTER_PIXMAP(p) NOP +# define IMLIB_FREE_PIXMAP(p) imlib_free_pixmap_and_mask(p) +# else +# define IMLIB_REGISTER_PIXMAP(p) NOP +# define IMLIB_FREE_PIXMAP(p) NOP +# endif # define PIXMAP_DUMP() NOP # define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv)) # define X_FREE_GC(d, gc) XFreeGC((d), (gc)) diff --git a/libmej/mem.c b/libmej/mem.c index c959ed3..a2dc1a2 100644 --- a/libmej/mem.c +++ b/libmej/mem.c @@ -31,8 +31,9 @@ static const char cvs_ident[] = "$Id$"; #include "libmej.h" static void memrec_add_var(memrec_t *, const char *, unsigned long, void *, size_t); -static void memrec_rem_var(memrec_t *, const char *, const char *, unsigned long, void *); -static void memrec_chg_var(memrec_t *, const char *, const char *, unsigned long, void *, void *, size_t); +static ptr_t *memrec_find_var(memrec_t *, const void *); +static void memrec_rem_var(memrec_t *, const char *, const char *, unsigned long, const void *); +static void memrec_chg_var(memrec_t *, const char *, const char *, unsigned long, const void *, void *, size_t); static void memrec_dump_pointers(memrec_t *); static void memrec_dump_resources(memrec_t *); @@ -79,49 +80,53 @@ memrec_add_var(memrec_t *memrec, const char *filename, unsigned long line, void p->line = line; } -static void -memrec_rem_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, void *ptr) +static ptr_t * +memrec_find_var(memrec_t *memrec, const void *ptr) { - register ptr_t *p = NULL; + register ptr_t *p; register unsigned long i; ASSERT(memrec != NULL); - for (i = 0; i < memrec->cnt; i++) { - if (memrec->ptrs[i].ptr == ptr) { - p = memrec->ptrs + i; - break; + REQUIRE_RVAL(ptr != NULL, NULL); + + for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) { + if (p->ptr == ptr) { + D_MEM(("Found pointer #%lu stored at %8p (from %8p)\n", i + 1, p, memrec->ptrs)); + return p; } } - if (!p) { + return NULL; +} + +static void +memrec_rem_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *ptr) +{ + register ptr_t *p; + + ASSERT(memrec != NULL); + + if ((p = memrec_find_var(memrec, ptr)) == NULL) { D_MEM(("ERROR: File %s, line %d attempted to free variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line, var, ptr)); return; } memrec->cnt--; D_MEM(("Removing variable %s (%8p) of size %lu\n", var, ptr, p->size)); - D_MEM(("Pointer #%lu is stored at %8p (from %8p)\n", i + 1, p, memrec->ptrs)); - memmove(p, p + 1, sizeof(ptr_t) * (memrec->cnt - i)); + memmove(p, p + 1, sizeof(ptr_t) * (memrec->cnt - (p - memrec->ptrs))); memrec->ptrs = (ptr_t *) realloc(memrec->ptrs, sizeof(ptr_t) * memrec->cnt); } static void -memrec_chg_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, void *oldp, void *newp, size_t size) +memrec_chg_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size) { - register ptr_t *p = NULL; - register unsigned long i; + register ptr_t *p; ASSERT(memrec != NULL); - for (i = 0; i < memrec->cnt; i++) { - if (memrec->ptrs[i].ptr == oldp) { - p = memrec->ptrs + i; - break; - } - } - if (i == memrec->cnt) { + + if ((p = memrec_find_var(memrec, oldp)) == NULL) { D_MEM(("ERROR: File %s, line %d attempted to realloc variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line, var, oldp)); return; } D_MEM(("Changing variable %s (%8p, %lu -> %8p, %lu)\n", var, oldp, p->size, newp, size)); - D_MEM(("Pointer #%lu stored at %8p (from %8p)\n", i + 1, p, memrec->ptrs)); p->ptr = newp; p->size = size; strncpy(p->file, filename, LIBMEJ_FNAME_LEN); @@ -351,7 +356,7 @@ libmej_x_create_pixmap(const char *filename, unsigned long line, Display *d, Dra void libmej_x_free_pixmap(const char *var, const char *filename, unsigned long line, Display *d, Pixmap p) { - D_MEM(("libmej_x_free_pixmap() called for variable %s (0x%08x) at %s:%lu\n", var, p, filename, line)); + D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", var, p, filename, line)); if (p) { if (DEBUG_LEVEL >= DEBUG_MEM) { memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p); @@ -362,6 +367,37 @@ libmej_x_free_pixmap(const char *var, const char *filename, unsigned long line, } } +void +libmej_imlib_register_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p) +{ + D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", var, p, filename, line)); + if (p) { + if (DEBUG_LEVEL >= DEBUG_MEM) { + if (!memrec_find_var(&pixmap_rec, (void *) p)) { + memrec_add_var(&pixmap_rec, filename, line, (void *) p, 1); + } else { + D_MEM(("Pixmap 0x%08x already registered.\n")); + } + } + } else { + D_MEM(("ERROR: Refusing to register a NULL pixmap\n")); + } +} + +void +libmej_imlib_free_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p) +{ + D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", var, p, filename, line)); + if (p) { + if (DEBUG_LEVEL >= DEBUG_MEM) { + memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p); + } + imlib_free_pixmap_and_mask(p); + } else { + D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); + } +} + void libmej_dump_pixmap_tables(void) { diff --git a/src/pixmap.c b/src/pixmap.c index edb6bea..2b0ad95 100644 --- a/src/pixmap.c +++ b/src/pixmap.c @@ -593,6 +593,7 @@ create_viewport_pixmap(simage_t *simg, Drawable d, int x, int y, unsigned short reset_simage(simg, RESET_ALL_SIMG); return None; } + IMLIB_REGISTER_PIXMAP(viewport_pixmap); D_PIXMAP(("Created viewport_pixmap == 0x%08x\n", viewport_pixmap)); } else { XGetGeometry(Xdisplay, viewport_pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); @@ -730,6 +731,7 @@ paste_simage(simage_t *simg, unsigned char which, Drawable d, unsigned short x, reset_simage(simg, RESET_ALL_SIMG); return; } + IMLIB_REGISTER_PIXMAP(pmap); gc = LIBMEJ_X_CREATE_GC(0, NULL); if (mask) { XSetClipMask(Xdisplay, gc, mask); @@ -1028,6 +1030,7 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h shaped_window_apply_mask(win, simg->pmap->mask); } if (simg->pmap->pixmap != None) { + IMLIB_REGISTER_PIXMAP(simg->pmap->pixmap); if (pixmap != None && pixmap != simg->pmap->pixmap) { IMLIB_FREE_PIXMAP(pixmap); } diff --git a/src/pixmap.h b/src/pixmap.h index 72a221e..b9036ae 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -45,7 +45,7 @@ typedef void *Imlib_Color_Modifier; # define background_is_auto() (images[image_bg].mode & MODE_AUTO) # define background_is_pixmap() (background_is_image() || (images[image_bg].mode & (MODE_TRANS | MODE_VIEWPORT | MODE_AUTO))) # define delete_simage(simg) do { \ - imlib_free_pixmap_and_mask((simg)->pmap->pixmap); \ + IMLIB_FREE_PIXMAP((simg)->pmap->pixmap); \ imlib_context_set_image((simg)->iml->im); \ imlib_free_image_and_decache(); \ (simg)->pmap->pixmap = None; (simg)->iml->im = NULL; \ @@ -54,7 +54,6 @@ typedef void *Imlib_Color_Modifier; # define CONVERT_TINT_RED(t) (((t) & 0xff0000) >> 16) # define CONVERT_TINT_GREEN(t) (((t) & 0x00ff00) >> 8) # define CONVERT_TINT_BLUE(t) ((t) & 0x0000ff) -# define IMLIB_FREE_PIXMAP(p) do {D_PIXMAP(("Freeing pixmap: imlib_free_pixmap_and_mask(0x%08x)\n", (p))); imlib_free_pixmap_and_mask(p);} while (0) #else # define background_is_image() (0) # define background_is_trans() (0) @@ -63,7 +62,6 @@ typedef void *Imlib_Color_Modifier; # define background_is_pixmap() (0) # define get_image_type_string(t) ((char *) "") # define delete_simage(simg) NOP -# define IMLIB_FREE_PIXMAP(p) NOP #endif #define LIBMEJ_X_CREATE_PIXMAP(w, h) X_CREATE_PIXMAP(Xdisplay, (TermWin.parent ? TermWin.parent : Xroot), (w), (h), Xdepth) #define LIBMEJ_X_FREE_PIXMAP(p) X_FREE_PIXMAP(Xdisplay, p)