[GRASS-SVN] r34929 - grass/trunk/lib/cairodriver

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Dec 18 16:49:58 EST 2008


Author: glynn
Date: 2008-12-18 16:49:58 -0500 (Thu, 18 Dec 2008)
New Revision: 34929

Added:
   grass/trunk/lib/cairodriver/read_xid.c
   grass/trunk/lib/cairodriver/write_xid.c
Modified:
   grass/trunk/lib/cairodriver/Graph.c
   grass/trunk/lib/cairodriver/Makefile
   grass/trunk/lib/cairodriver/cairodriver.h
   grass/trunk/lib/cairodriver/read.c
   grass/trunk/lib/cairodriver/write.c
Log:
Fix, improve handling of X Pixmap surfaces


Modified: grass/trunk/lib/cairodriver/Graph.c
===================================================================
--- grass/trunk/lib/cairodriver/Graph.c	2008-12-18 17:32:51 UTC (rev 34928)
+++ grass/trunk/lib/cairodriver/Graph.c	2008-12-18 21:49:58 UTC (rev 34929)
@@ -49,60 +49,52 @@
 static void init_xlib(void)
 {
 #if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
-    Display *dpy;
-    Drawable win;
     unsigned long xid;
     XVisualInfo templ;
     XVisualInfo *vinfo;
+    int scrn;
     int count;
-    Window root;
-    unsigned int depth;
-    int si;
-    unsigned int ui;
-    Visual *visual;
     char *p;
 
-    p = getenv("GRASS_CAIRO_DRAWABLE");
-    if (!p || sscanf(p, "%li", &xid) != 1)
-	G_fatal_error(_("Invalid Drawable XID: %s"), p);
-    win = xid;
-
-    dpy = XOpenDisplay(NULL);
-    if (!dpy)
+    ca.dpy = XOpenDisplay(NULL);
+    if (!ca.dpy)
 	G_fatal_error(_("Unable to open display"));
 
+    p = getenv("GRASS_CAIRO_SCREEN");
+    if (!p || sscanf(p, "%i", &scrn) != 1)
+	scrn = DefaultScreen(ca.dpy);
+
     p = getenv("GRASS_CAIRO_VISUAL");
     if (!p || sscanf(p, "%li", &xid) != 1)
-	G_fatal_error(_("invalid Visual XID: %s"), p);
+	xid = DefaultVisual(ca.dpy, scrn)->visualid;
+
     templ.visualid = xid;
+    templ.screen = scrn;
 
-    vinfo = XGetVisualInfo(dpy, VisualIDMask, &templ, &count);
+    vinfo = XGetVisualInfo(ca.dpy, VisualIDMask, &templ, &count);
     if (!vinfo || !count)
 	G_fatal_error(_("Unable to obtain visual"));
-    visual = vinfo[0].visual;
+    ca.visual = vinfo[0].visual;
 
-    if (!XGetGeometry
-	(dpy, win, &root, &si, &si, &width, &height, &ui, &depth))
-	G_fatal_error(_("Unable to query drawable"));
+    if (!ca.win)
+	ca.win = XCreatePixmap(
+	    ca.dpy, RootWindow(ca.dpy, scrn),
+	    ca.width, ca.height, vinfo[0].depth);
+#endif
+}
 
-    surface = cairo_xlib_surface_create(dpy, win, visual, width, height);
-
-    if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
-	G_fatal_error(_("Failed to initialize Xlib surface"));
-
-    cairo = cairo_create(surface);
-
-    ca.file_name = "<X11>";
-    file_type = FTYPE_X11;
-
-    screen_right = screen_left + ca.width;
-    screen_bottom = screen_top + ca.height;
+static void fini_xlib(void)
+{
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    XSetCloseDownMode(ca.dpy, RetainPermanent);
+    XCloseDisplay(ca.dpy);
 #endif
 }
 
 static void init_file(void)
 {
     int is_vector = 0;
+    int is_xlib = 0;
     int do_read = 0;
     int do_map = 0;
     char *p;
@@ -120,8 +112,7 @@
     ca.file_name = p;
 
     /* get file type (from extension) */
-    if (ca.file_type == FTYPE_X11) ;	/* skip */
-    else if (ends_with(ca.file_name, ".ppm"))
+    if (ends_with(ca.file_name, ".ppm"))
 	ca.file_type = FTYPE_PPM;
     else if (ends_with(ca.file_name, ".bmp"))
 	ca.file_type = FTYPE_BMP;
@@ -141,6 +132,10 @@
     else if (ends_with(ca.file_name, ".svg"))
 	ca.file_type = FTYPE_SVG;
 #endif
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    else if (ends_with(ca.file_name, ".xid"))
+	ca.file_type = FTYPE_X11;
+#endif
     else
 	G_fatal_error(_("Unknown file extension: %s"), p);
     G_debug(1, "File type: %s (%d)", ca.file_name, ca.file_type);
@@ -151,6 +146,9 @@
     case FTYPE_SVG:
 	is_vector = 1;
 	break;
+    case FTYPE_X11:
+	is_xlib = 1;
+	break;
     }
 
     p = getenv("GRASS_PNG_MAPPED");
@@ -175,6 +173,15 @@
     if (do_read && do_map)
 	map_file();
 
+    if (is_xlib) {
+	if (do_read)
+	    cairo_read_image();
+	else
+	    ca.win = 0;
+	init_xlib();
+	ca.mapped = 1;
+    }
+
     if (!ca.mapped && !is_vector)
 	ca.grid = G_malloc(ca.height * ca.stride);
 
@@ -244,11 +251,7 @@
     if (p && G_strcasecmp(p, "subpixel") == 0)
 	antialias = CAIRO_ANTIALIAS_SUBPIXEL;
 
-    p = getenv("GRASS_CAIRO_DRAWABLE");
-    if (p)
-	init_xlib();
-    else
-	init_file();
+    init_file();
 
     cairo_set_antialias(cairo, antialias);
 
@@ -262,6 +265,13 @@
 {
     G_debug(1, "Cairo_Graph_close");
 
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    if (ca.file_type == FTYPE_X11) {
+	XFlush(cairo_xlib_surface_get_display(surface));
+	ca.mapped = 0;
+    }
+#endif
+
     cairo_write_image();
 
     if (cairo) {
@@ -272,6 +282,11 @@
 	cairo_surface_destroy(surface);
 	surface = NULL;
     }
+
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    if (ca.file_type == FTYPE_X11)
+	fini_xlib();
+#endif
 }
 
 static void init_cairo(void)
@@ -308,6 +323,13 @@
 		ca.file_name, (double) ca.width, (double) ca.height);
 	break;
 #endif
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    case FTYPE_X11:
+	surface =
+	    (cairo_surface_t *) cairo_xlib_surface_create(
+		ca.dpy, ca.win, ca.visual, ca.width, ca.height);
+	break;
+#endif
     default:
 	G_fatal_error(_("Unknown Cairo surface type"));
 	break;
@@ -356,3 +378,4 @@
     ca.mapped = 1;
 #endif
 }
+

Modified: grass/trunk/lib/cairodriver/Makefile
===================================================================
--- grass/trunk/lib/cairodriver/Makefile	2008-12-18 17:32:51 UTC (rev 34928)
+++ grass/trunk/lib/cairodriver/Makefile	2008-12-18 21:49:58 UTC (rev 34929)
@@ -9,6 +9,10 @@
 
 include $(MODULE_TOPDIR)/include/Make/Lib.make
 
+ifneq ($(USE_X11),)
+EXTRA_CFLAGS += -DUSE_X11=1
+endif
+
 ifneq ($(USE_CAIRO),)
 default: lib
 endif

Modified: grass/trunk/lib/cairodriver/cairodriver.h
===================================================================
--- grass/trunk/lib/cairodriver/cairodriver.h	2008-12-18 17:32:51 UTC (rev 34928)
+++ grass/trunk/lib/cairodriver/cairodriver.h	2008-12-18 21:49:58 UTC (rev 34929)
@@ -21,6 +21,13 @@
 
 #include <cairo.h>
 
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <cairo-xlib.h>
+#endif
+
 #include <grass/config.h>
 #include <grass/gis.h>
 
@@ -56,6 +63,11 @@
     double bgcolor_r, bgcolor_g, bgcolor_b, bgcolor_a;
     int modified;
     int mapped;
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    Display *dpy;
+    Drawable win;
+    Visual *visual;
+#endif
 };
 
 extern struct cairo_state ca;
@@ -93,10 +105,12 @@
 extern void cairo_read_image(void);
 extern void cairo_read_ppm(void);
 extern void cairo_read_bmp(void);
+extern void cairo_read_xid(void);
 
 /* write.c */
 extern void cairo_write_image(void);
 extern void cairo_write_ppm(void);
 extern void cairo_write_bmp(void);
+extern void cairo_write_xid(void);
 
 #endif /* __CAIRODRIVER_H__ */

Modified: grass/trunk/lib/cairodriver/read.c
===================================================================
--- grass/trunk/lib/cairodriver/read.c	2008-12-18 17:32:51 UTC (rev 34928)
+++ grass/trunk/lib/cairodriver/read.c	2008-12-18 21:49:58 UTC (rev 34929)
@@ -47,6 +47,12 @@
 	cairo_surface_destroy(img_surf);
     }
 #endif
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    if (ca.file_type == FTYPE_X11) {
+	G_debug(1, "Reading XID from %s", ca.file_name);
+	cairo_read_xid();
+    }
+#endif
     /* vector format files are written directly to file */
 
     ca.modified = 0;

Added: grass/trunk/lib/cairodriver/read_xid.c
===================================================================
--- grass/trunk/lib/cairodriver/read_xid.c	                        (rev 0)
+++ grass/trunk/lib/cairodriver/read_xid.c	2008-12-18 21:49:58 UTC (rev 34929)
@@ -0,0 +1,27 @@
+#include <grass/glocale.h>
+
+#include "cairodriver.h"
+
+void cairo_read_xid(void)
+{
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    FILE *fp;
+    char buf[64];
+    unsigned long xid;
+
+    fp = fopen(ca.file_name, "r");
+    if (!fp)
+	G_fatal_error(_("Unable to open input file <%s>"), ca.file_name);
+
+    if (!fgets(buf, sizeof(buf), fp))
+	G_fatal_error(_("Unable to read input file <%s>"), ca.file_name);
+
+    if (sscanf(buf, "%lu", &xid) != 1)
+	G_fatal_error(_("Unable to parse input file <%s>"), ca.file_name);
+
+    fclose(fp);
+
+    ca.win = (Drawable) xid;
+#endif
+}
+

Modified: grass/trunk/lib/cairodriver/write.c
===================================================================
--- grass/trunk/lib/cairodriver/write.c	2008-12-18 17:32:51 UTC (rev 34928)
+++ grass/trunk/lib/cairodriver/write.c	2008-12-18 21:49:58 UTC (rev 34929)
@@ -14,7 +14,7 @@
 
 #include "cairodriver.h"
 
-#if CAIRO_HAS_XLIB_SURFACE
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
 #include <X11/Xlib.h>
 #include <cairo-xlib.h>
 #endif
@@ -46,9 +46,10 @@
 	cairo_surface_write_to_png(surface, ca.file_name);
     }
 #endif
-#if CAIRO_HAS_XLIB_SURFACE
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
     else if (ca.file_type == FTYPE_X11) {
-	XFlush(cairo_xlib_surface_get_display(surface));
+	G_debug(1, "Writing XID to %s", ca.file_name);
+	cairo_write_xid();
     }
 #endif
     /* vector format files are written directly to file */

Added: grass/trunk/lib/cairodriver/write_xid.c
===================================================================
--- grass/trunk/lib/cairodriver/write_xid.c	                        (rev 0)
+++ grass/trunk/lib/cairodriver/write_xid.c	2008-12-18 21:49:58 UTC (rev 34929)
@@ -0,0 +1,24 @@
+
+#include <grass/glocale.h>
+
+#include "cairodriver.h"
+
+void cairo_write_xid(void)
+{
+#if defined(USE_X11) && CAIRO_HAS_XLIB_SURFACE
+    FILE *fp;
+    char buf[64];
+
+    fp = fopen(ca.file_name, "w");
+    if (!fp)
+	G_fatal_error(_("Unable to open output file <%s>"), ca.file_name);
+
+    sprintf(buf, "0x%08lx\n", (unsigned long) ca.win);
+
+    if (fputs(buf, fp) < 0)
+	G_fatal_error(_("Unable to write output file <%s>"), ca.file_name);
+
+    fclose(fp);
+#endif
+}
+



More information about the grass-commit mailing list