-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: rxvt-unicode-sixel
action: commit
revision:
path_from:
revision_from: 8b9ad747422dbee1a8191eb89e80a7985813b7af:
path_to:
revision_to:

git.thebackupbox.net

rxvt-unicode-sixel

git://git.thebackupbox.net/rxvt-unicode-sixel

commit 8b9ad747422dbee1a8191eb89e80a7985813b7af
Author: Marc Lehmann <schmorp@schmorp.de>
Date:   Thu Jun 7 07:53:12 2012 +0000

    preliminary recounting

diff --git a/src/rxvtimg.C b/src/rxvtimg.C

index f00b7e2ce2bc71e6063e2540c2cd470fa1e47bf0..

index ..661f9d46a851d49672bb191ce6e3b4de1a909708 100644

--- a/src/rxvtimg.C
+++ b/src/rxvtimg.C
@@ -5,15 +5,24 @@
 #if HAVE_IMG

 rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height)
-: s(screen), x(0), y(0), w(width), h(height), format(format), repeat(RepeatNormal), shared(false)
+: s(screen), x(0), y(0), w(width), h(height), format(format), repeat(RepeatNormal),
+  pm(0), refcnt(0)
 {
-  pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
 }

+rxvt_img::rxvt_img (const rxvt_img &img)
+: s(img.s), x(img.x), y(img.y), w(img.w), h(img.h), format(img.format), repeat(img.repeat), pm(img.pm), refcnt(img.refcnt)
+{
+  if (refcnt)
+    ++*refcnt;
+}
+
+#if 0
 rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap)
 : s(screen), x(0), y(0), w(width), h(height), format(format), repeat(RepeatNormal), shared(false), pm(pixmap)
 {
 }
+#endif

 rxvt_img *
 rxvt_img::new_from_root (rxvt_screen *s)
@@ -38,11 +47,10 @@ rxvt_img::new_from_root (rxvt_screen *s)
      s,
      XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
      root_pm_w,
-     root_pm_h,
-     root_pixmap
+     root_pm_h
   );

-  img->shared = true;
+  img->pm = root_pixmap;

   return img;
 }
@@ -62,7 +70,7 @@ rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
      gdk_pixbuf_get_width (pb),
      gdk_pixbuf_get_height (pb)
   );
-
+  img->alloc ();
   img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0);

   g_object_unref (pb);
@@ -70,24 +78,45 @@ rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
   return img;
 }

-rxvt_img::~rxvt_img ()
+void
+rxvt_img::destroy ()
 {
-  if (!shared)
+  if (!refcnt || --*refcnt)
+    return;
+
+  if (pm)
     XFreePixmap (s->display->dpy, pm);
+
+  delete refcnt;
+}
+
+rxvt_img::~rxvt_img ()
+{
+  destroy ();
+}
+
+void
+rxvt_img::alloc ()
+{
+  pm = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
+  refcnt = new int (1);
 }

 void
 rxvt_img::unshare ()
 {
-  if (!shared)
+  if (refcnt && *refcnt == 1)
     return;

-  rxvt_img *img = clone ();
+  Pixmap pm2 = XCreatePixmap (s->display->dpy, s->display->root, w, h, format->depth);
+  GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
+  XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0);
+  XFreeGC (s->display->dpy, gc);

-  ::swap (pm    , img->pm);
-  ::swap (shared, img->shared);
+  destroy ();

-  delete img;
+  pm = pm2;
+  refcnt = new int (1);
 }

 void
@@ -132,6 +161,7 @@ rxvt_img::blur (int rh, int rv)
   double *kernel = (double *)malloc (size * sizeof (double));
   XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
   rxvt_img *img = new rxvt_img (s, format, w, h);
+  img->alloc ();

   XRenderPictureAttributes pa;

@@ -342,19 +372,14 @@ rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int
 rxvt_img *
 rxvt_img::clone ()
 {
-  rxvt_img *img = new rxvt_img (s, format, w, h);
-
-  GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
-  XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
-  XFreeGC (s->display->dpy, gc);
-
-  return img;
+  return new rxvt_img (*this);
 }

 rxvt_img *
 rxvt_img::sub_rect (int x, int y, int width, int height)
 {
   rxvt_img *img = new rxvt_img (s, format, width, height);
+  img->alloc ();

   Display *dpy = s->display->dpy;
   XRenderPictureAttributes pa;
@@ -374,6 +399,7 @@ rxvt_img *
 rxvt_img::transform (int new_width, int new_height, double matrix[9])
 {
   rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
+  img->alloc ();

   Display *dpy = s->display->dpy;
   XRenderPictureAttributes pa;
@@ -427,7 +453,11 @@ rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi)
 rxvt_img *
 rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
 {
+  if (new_format == format)
+    return clone ();
+
   rxvt_img *img = new rxvt_img (s, new_format, w, h);
+  img->alloc ();

   Display *dpy = s->display->dpy;
   Picture src = XRenderCreatePicture (dpy,      pm,     format, 0, 0);
diff --git a/src/rxvtimg.h b/src/rxvtimg.h

index be473b49f915c76cd9b896c8df0d5830ae7c8fe7..

index ..ddec9d991cbf221a373c5e4cd301904847d10ac7 100644

--- a/src/rxvtimg.h
+++ b/src/rxvtimg.h
@@ -11,25 +11,33 @@

 #include <X11/extensions/Xrender.h>

-struct rxvt_img
+class rxvt_img
 {
+  void alloc ();
+  void destroy ();
+
+public:
   rxvt_screen *s;
   Pixmap pm;
+  int *refcnt; // shared refcnt
   int x, y, w, h, repeat;
   XRenderPictFormat *format;
-  bool shared; // true if we don't own it

   rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height);
-  rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap);
+  rxvt_img (const rxvt_img &img);
+
+  //rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap);
   static rxvt_img *new_from_root (rxvt_screen *s); // get root pixmap
   static rxvt_img *new_from_file (rxvt_screen *s, const char *filename); // from pixbuf

   ~rxvt_img ();

+  // TODO: steal should not do what it does, and this todo should be more specific
   Pixmap steal ()
   {
-    shared = true;
-    return pm;
+    Pixmap retval = pm;
+    pm = None;
+    return retval;
   }

   // inplace
@@ -44,7 +52,7 @@ struct rxvt_img
     this->repeat = repeat;
   }

-  void unshare (); // create a copy of the pixmap if !shared
+  void unshare (); // prepare for write
   void fill (const rxvt_color &c);
   void brightness (unsigned short r, unsigned short g, unsigned short b, unsigned short a);
   void contrast (unsigned short r, unsigned short g, unsigned short b, unsigned short a);
diff --git a/src/rxvtperl.xs b/src/rxvtperl.xs

index 0a64cc6e8f920928faadf5755deb96bb6acb1143..

index ..ea716aa14da58e12fc8d98af480a7bee49530535 100644

--- a/src/rxvtperl.xs
+++ b/src/rxvtperl.xs
@@ -2094,19 +2094,11 @@ rxvt_term::set_background (rxvt_img *img)

         if (img) // TODO: cannot be false
           {
-            XRenderPictFormat *f = XRenderFindVisualFormat (THIS->dpy, THIS->visual);
-            rxvt_img *img2 = 0;
-            rxvt_img *img3 = 0;
-
-            if (f != img->format)
-              img = img2 = img->convert_to (f, THIS->pix_colors [Color_bg]);
-
-            img->unshare ();
+            img = img->convert_to (XRenderFindVisualFormat (THIS->dpy, THIS->visual), THIS->pix_colors [Color_bg]);
             THIS->bg_pixmap = img->steal ();
             THIS->bg_flags |= rxvt_term::BG_NEEDS_REFRESH;
             THIS->bg_valid_since = ev::now (); // TODO: extra bloat
-
-            delete img2;
+            delete img;
           }

 #endif
@@ -2168,13 +2160,6 @@ rxvt_img::h ()
 	OUTPUT:
         RETVAL

-bool
-rxvt_img::shared ()
-	CODE:
-        RETVAL = THIS->shared;
-	OUTPUT:
-        RETVAL
-
 Pixmap
 rxvt_img::pm ()
 	CODE:

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 13:02:18 2024