Hi,

since the text plugin interface is among the weirdest ones that we have
(a structure pointer passed via a character pointer variable, a pixmap
passed back as void *, usage of the image rendering interface), I
decided to give cleaning it up a go. Attached is what I have so far, a
text plugin rewrite and an example implementation of the new interface
for the ring plugin.

I would like to know about opinions, improvement suggestions etc. about
this new interface. Ideas I have (and like to hear opinions about) are

- Pass a CompTextData * instead of the Bool as result of the rendering
functions, which then could be used to check if rendering was successful
later on (would save some memory in my example implementation, but
would cause another heap allocation though, not sure if we want to avoid
that)

- Implement more stuff currently implemented via copy'n'paste in the
various text plugins users. Among those are e.g. automatic binding of
the pixmap to the texture, a cleanup function, a drawing function which
puts the texture on screen. I'm not sure doing stuff like automatic
binding would limit the use cases of the text plugin (e.g. group doesn't
need it because it does some additional cairo magic). We could make the
binding optional via a flag, though (and enable it by default).

Any thoughts?

Thanks,

Danny
>From 8c26e53234f28af723bb9f62daadc6fdd1ff645b Mon Sep 17 00:00:00 2001
From: Danny Baumann <dannybaum...@web.de>
Date: Sun, 4 Jan 2009 17:47:08 +0100
Subject: [PATCH] De-cruftify text plugin interface.
 - Use function pointer set as interface instead of providing a fake
 image renderer.
 - De-BCOP text plugin, BCOP wasn't needed anyway.
 - Some cleanups.

---
 compiz-text.h |   62 ++++---
 text.c        |  652 ++++++++++++++++++++++++++++++++-------------------------
 text.xml.in   |    3 +-
 3 files changed, 407 insertions(+), 310 deletions(-)

diff --git a/compiz-text.h b/compiz-text.h
index 74cc9b8..f8daa23 100644
--- a/compiz-text.h
+++ b/compiz-text.h
@@ -21,38 +21,48 @@
 #ifndef _COMPIZ_TEXT_H
 #define _COMPIZ_TEXT_H
 
-#define TEXT_ABIVERSION 20080421
+#define TEXT_ABIVERSION 20090103
 
-#define TEXT_ID "TextToPixmap"
-
-#define TEXT_STYLE_NORMAL		(1 << 0)
-#define TEXT_STYLE_BOLD			(1 << 1)
-#define TEXT_STYLE_ITALIC		(1 << 2)
-#define TEXT_STYLE_BACKGROUND		(1 << 3)
-
-typedef enum {
-    TextRenderNormal = 0,
-    TextRenderWindowTitle,
-    TextRenderWindowTitleWithViewport
-} TextRenderMode;
+#define CompTextStyleBold           (1 << 0)
+#define CompTextStyleItalic         (1 << 1)
+#define CompTextStyleEllipsized     (1 << 2)
+#define CompTextStyleWithBackground (1 << 3)
 
 typedef struct _CompTextAttrib {
-    TextRenderMode renderMode;
-
-    void *data;
-
-    CompScreen *screen;
-    int        maxWidth;
-    int        maxHeight;
-
     char           *family;
     int            size;
     unsigned short color[4];
-    unsigned int   style;
-    Bool           ellipsize;
-    int            backgroundHMargin;
-    int            backgroundVMargin;
-    unsigned short backgroundColor[4];
+
+    unsigned int   flags;
+
+    int            maxWidth;
+    int            maxHeight;
+
+    int            bgHMargin;
+    int            bgVMargin;
+    unsigned short bgColor[4];
 } CompTextAttrib;
 
+typedef struct _CompTextData {
+    Pixmap       pixmap;
+    unsigned int width;
+    unsigned int height;
+} CompTextData;
+
+typedef Bool (*RenderTextProc) (CompScreen           *s,
+				const char           *text,
+				const CompTextAttrib *attrib,
+				CompTextData         *data);
+
+typedef Bool (*RenderWindowTitleProc) (CompScreen           *s,
+				       Window               window,
+				       Bool                 withViewportNumber,
+				       const CompTextAttrib *attrib,
+				       CompTextData         *data);
+
+typedef struct _TextFunc {
+    RenderTextProc        renderText;
+    RenderWindowTitleProc renderWindowTitle;
+} TextFunc;
+
 #endif
diff --git a/text.c b/text.c
index 49f2893..adbe70d 100644
--- a/text.c
+++ b/text.c
@@ -39,17 +39,22 @@
 
 #include <compiz-core.h>
 #include "compiz-text.h"
-#include "text_options.h"
 
 #define PI 3.14159265359f
 
+static CompMetadata textMetadata;
+
 static int displayPrivateIndex;
+static int functionsPrivateIndex;
 
-typedef struct _TextDisplay
-{
-    FileToImageProc fileToImage;
+#define TEXT_DISPLAY_OPTION_ABI    0
+#define TEXT_DISPLAY_OPTION_INDEX  1
+#define TEXT_DISPLAY_OPTION_NUM    2
 
+typedef struct _TextDisplay {
     Atom visibleNameAtom;
+
+    CompOption opt[TEXT_DISPLAY_OPTION_NUM];
 } TextDisplay;
 
 #define GET_TEXT_DISPLAY(d)				    \
@@ -58,46 +63,55 @@ typedef struct _TextDisplay
 #define TEXT_DISPLAY(d)			 \
     TextDisplay *td = GET_TEXT_DISPLAY (d)
 
-static char*
+#define NUM_OPTIONS(d) (sizeof ((d)->opt) / sizeof (CompOption))
+
+typedef struct _TextSurfaceData {
+    int                  width;
+    int                  height;
+
+    cairo_t              *cr;
+    cairo_surface_t      *surface;
+    PangoLayout          *layout;
+    Pixmap               pixmap;
+    XRenderPictFormat    *format;
+    PangoFontDescription *font;
+    Screen               *screen;
+} TextSurfaceData;
+
+static char *
 textGetUtf8Property (CompDisplay *d,
 		     Window      id,
 		     Atom        atom)
 {
     Atom          type;
-    int           format;
-    unsigned long nitems;
-    unsigned long bytesAfter;
-    char          *val;
-    int           result;
-    char          *retval;
+    int           result, format;
+    unsigned long nItems, bytesAfter;
+    char          *val, *retval = NULL;
 
     result = XGetWindowProperty (d->display, id, atom, 0L, 65536, False,
-				 d->utf8StringAtom, &type, &format, &nitems,
-				 &bytesAfter, (unsigned char **)&val);
+				 d->utf8StringAtom, &type, &format, &nItems,
+				 &bytesAfter, (unsigned char **) &val);
 
     if (result != Success)
 	return NULL;
 
-    if (type != d->utf8StringAtom || format != 8 || nitems == 0)
-    {
-	if (val)
-	    XFree (val);
-	return NULL;
-    }
-
-    retval = malloc (sizeof (char) * (nitems + 1));
-    if (retval)
+    if (type == d->utf8StringAtom && format == 8 && val && nItems > 0)
     {
-	strncpy (retval, val, nitems);
-	retval[nitems] = 0;
+	retval = malloc (sizeof (char) * (nItems + 1));
+	if (retval)
+	{
+	    strncpy (retval, val, nItems);
+	    retval[nItems] = 0;
+	}
     }
 
-    XFree (val);
+    if (val)
+	XFree (val);
 
     return retval;
 }
 
-static char*
+static char *
 textGetTextProperty (CompDisplay *d,
 		     Window      id,
 		     Atom        atom)
@@ -124,7 +138,7 @@ textGetTextProperty (CompDisplay *d,
     return retval;
 }
 
-static char*
+static char *
 textGetWindowName (CompDisplay *d,
 		   Window      id)
 {
@@ -135,7 +149,7 @@ textGetWindowName (CompDisplay *d,
     name = textGetUtf8Property (d, id, td->visibleNameAtom);
 
     if (!name)
-	name = textGetUtf8Property(d, id, d->wmNameAtom);
+	name = textGetUtf8Property (d, id, d->wmNameAtom);
 
     if (!name)
 	name = textGetTextProperty (d, id, XA_WM_NAME);
@@ -147,8 +161,12 @@ textGetWindowName (CompDisplay *d,
  * Draw a rounded rectangle path
  */
 static void
-textDrawTextBackground (cairo_t *cr, int x, int y, int width, int height,
-			int radius)
+textDrawTextBackground (cairo_t *cr,
+			int     x,
+			int     y,
+			int     width,
+			int     height,
+			int     radius)
 {
     int x0, y0, x1, y1;
 
@@ -168,287 +186,304 @@ textDrawTextBackground (cairo_t *cr, int x, int y, int width, int height,
     cairo_close_path (cr);
 }
 
+static Bool
+textInitCairo (CompScreen      *s,
+	       TextSurfaceData *data,
+	       int             width,
+	       int             height)
+{
+    Display *dpy = s->display->display;
+
+    data->pixmap = None;
+    if (width > 0 && height > 0)
+	data->pixmap = XCreatePixmap (dpy, s->root, width, height, 32);
+
+    data->width  = width;
+    data->height = height;
+
+    if (!data->pixmap)
+    {
+	compLogMessage ("text", CompLogLevelError,
+			"Couldn't create %d x %d pixmap.", width, height);
+	return FALSE;
+    }
+
+    data->surface = cairo_xlib_surface_create_with_xrender_format (dpy,
+								   data->pixmap,
+  								   data->screen,
+								   data->format,
+								   width,
+								   height);
+    if (cairo_surface_status (data->surface) != CAIRO_STATUS_SUCCESS)
+    {
+	compLogMessage ("text", CompLogLevelError, "Couldn't create surface.");
+	return FALSE;
+    }
+
+    data->cr = cairo_create (data->surface);
+    if (cairo_status (data->cr) != CAIRO_STATUS_SUCCESS)
+    {
+	compLogMessage ("text", CompLogLevelError,
+			"Couldn't create cairo context.");
+	return FALSE;
+    }
+
+    return TRUE;
+}
 
 static Bool
-textFileToImage (CompDisplay *d,
-      		 const char  *path,
-		 const char  *name,
-		 int         *width,
-		 int         *height,
-		 int         *stride,
-		 void        **data)
+textInitSurface (CompScreen      *s,
+		 TextSurfaceData *data)
 {
-    Bool status = FALSE;
+    Display *dpy = s->display->display;
 
-    TEXT_DISPLAY (d);
+    data->screen = ScreenOfDisplay (dpy, s->screenNum);
+    if (!data->screen)
+    {
+	compLogMessage ("text", CompLogLevelError,
+			"Couldn't get screen for %d.", s->screenNum);
+	return FALSE;
+    }
 
-    if (path && name && strcmp(path, TEXT_ID) == 0)
+    data->format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
+    if (!data->format)
     {
-	cairo_t              *cr;
-	cairo_surface_t      *surface;
-	PangoLayout          *layout;
-	Pixmap               pixmap;
-	XRenderPictFormat    *format;
-	PangoFontDescription *font;
-	CompTextAttrib       *textAttrib;
-	Display              *dpy = d->display;
-	Screen               *screen;
-	int                  w, h;
-	int		    layoutWidth;
-	char                 *text = NULL;
-	
-	textAttrib = (CompTextAttrib*) name; /* get it through the name */
-	screen = ScreenOfDisplay (dpy, textAttrib->screen->screenNum);
+	compLogMessage ("text", CompLogLevelError, "Couldn't get format.");
+	return FALSE;
+    }
 
-	if (!screen)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't get screen for %d.",
-			    textAttrib->screen->screenNum);
-	    return FALSE;
-	}
+    if (!textInitCairo (s, data, 1, 1))
+	return FALSE;
 
-	format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
-	if (!format)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't get format.");
-	    return FALSE;
-	}
+    /* init pango */
+    data->layout = pango_cairo_create_layout (data->cr);
+    if (!data->layout)
+    {
+	compLogMessage ("text", CompLogLevelError,
+			"Couldn't create pango layout.");
+	return FALSE;
+    }
 
-	pixmap = XCreatePixmap (dpy, textAttrib->screen->root, 1, 1, 32);
-	if (!pixmap)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create pixmap.");
-	    return FALSE;
-	}
+    data->font = pango_font_description_new ();
+    if (!data->font)
+    {
+	compLogMessage ("text", CompLogLevelError,
+			"Couldn't create font description.");
+	return FALSE;
+    }
 
-	surface = cairo_xlib_surface_create_with_xrender_format (dpy,
-								 pixmap,
-								 screen,
-								 format, 1, 1);
+    return TRUE;
+}
 
-	if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create surface.");
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+static Bool
+textUpdateSurface (CompScreen      *s,
+		   TextSurfaceData *data,
+		   int             width,
+		   int             height)
+{
+    Display *dpy = s->display->display;
 
-	cr = cairo_create (surface);
-	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create cairo context.");
-	    cairo_surface_destroy (surface);
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+    cairo_surface_destroy (data->surface);
+    cairo_destroy (data->cr);
+    XFreePixmap (dpy, data->pixmap);
 
-	/* init pango */
-	layout = pango_cairo_create_layout (cr);
-	if (!layout)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create pango layout.");
-	    cairo_destroy (cr);
-	    cairo_surface_destroy (surface);
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+    return textInitCairo (s, data, width, height);
+}
 
-	font = pango_font_description_new ();
-	if (!font)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create font description.");
-	    g_object_unref (layout);
-	    cairo_destroy (cr);
-	    cairo_surface_destroy (surface);
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+static Bool
+textDrawText (CompScreen           *s,
+	      const char           *text,
+	      TextSurfaceData      *data,
+	      const CompTextAttrib *attrib)
+{
+    int width, height, layoutWidth;
 
-	pango_font_description_set_family (font, textAttrib->family);
-	pango_font_description_set_absolute_size (font,
-						  textAttrib->size *
-						  PANGO_SCALE);
+    pango_font_description_set_family (data->font, attrib->family);
+    pango_font_description_set_absolute_size (data->font,
+					      attrib->size * PANGO_SCALE);
+    pango_font_description_set_style (data->font, PANGO_STYLE_NORMAL);
 
-	pango_font_description_set_style (font, PANGO_STYLE_NORMAL);
+    if (attrib->flags & CompTextStyleBold)
+	pango_font_description_set_weight (data->font, PANGO_WEIGHT_BOLD);
 
-	if (textAttrib->style & TEXT_STYLE_BOLD)
-	    pango_font_description_set_weight (font, PANGO_WEIGHT_BOLD);
+    if (attrib->flags & CompTextStyleItalic)
+	pango_font_description_set_style (data->font, PANGO_STYLE_ITALIC);
 
-	if (textAttrib->style & TEXT_STYLE_ITALIC)
-    	    pango_font_description_set_style (font, PANGO_STYLE_ITALIC);
+    pango_layout_set_font_description (data->layout, data->font);
 
-	pango_layout_set_font_description (layout, font);
+    if (attrib->flags & CompTextStyleEllipsized)
+	pango_layout_set_ellipsize (data->layout, PANGO_ELLIPSIZE_END);
 
-	if (textAttrib->ellipsize)
-    	    pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
+    pango_layout_set_auto_dir (data->layout, FALSE);
+    pango_layout_set_text (data->layout, text, -1);
 
-	switch (textAttrib->renderMode) {
-	case TextRenderNormal:
-	    text = strdup ((char*) textAttrib->data);
-	    break;
-	case TextRenderWindowTitle:
-	    {
-		Window xid = (Window) textAttrib->data;
-		text = textGetWindowName (d, xid);
-	    }
-	    break;
-	case TextRenderWindowTitleWithViewport:
-	    {
-		Window xid = (Window) textAttrib->data;
-		char *title = textGetWindowName (d, xid);
-
-		if (title)
-		{
-		    CompWindow *w;
-
-		    w = findWindowAtDisplay (d, xid);
-		    if (w)
-		    {
-			int vx, vy, viewport;
-
-			defaultViewportForWindow (w, &vx, &vy);
-			viewport = vy * w->screen->hsize + vx + 1;
-			asprintf (&text, "%s -[%d]-", title, viewport);
-			free (title);
-		    }
-		    else
-			text = title;
-		}
-	    }
-	    break;
-	default:
-	    break;
-	}
+    pango_layout_get_pixel_size (data->layout, &width, &height);
 
-	if (text)
-	{
-	    pango_layout_set_auto_dir (layout, FALSE);
-	    pango_layout_set_text (layout, text, -1);
-	    free (text);
-	}
-	else
-	{
-	    pango_font_description_free (font);
-	    g_object_unref (layout);
-	    cairo_destroy (cr);
-	    cairo_surface_destroy (surface);
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+    if (attrib->flags & CompTextStyleWithBackground)
+    {
+	width  += 2 * attrib->bgHMargin;
+	height += 2 * attrib->bgVMargin;
+    }
 
-	pango_layout_get_pixel_size (layout, &w, &h);
+    width  = MIN (attrib->maxWidth, width);
+    height = MIN (attrib->maxHeight, height);
 
-	if (textAttrib->style & TEXT_STYLE_BACKGROUND)
-	{
-	    w += 2 * textAttrib->backgroundHMargin;
-	    h += 2 * textAttrib->backgroundVMargin;
-	}
+    /* update the size of the pango layout */
+    layoutWidth = attrib->maxWidth;
+    if (attrib->flags & CompTextStyleWithBackground)
+	layoutWidth -= 2 * attrib->bgHMargin;
 
-	w = MIN (textAttrib->maxWidth, w);
-	h = MIN (textAttrib->maxHeight, h);
+    pango_layout_set_width (data->layout, layoutWidth * PANGO_SCALE);
 
-	/* update the size of the pango layout */
-	layoutWidth = textAttrib->maxWidth;
-	if (textAttrib->style & TEXT_STYLE_BACKGROUND)
-	    layoutWidth -= 2 * textAttrib->backgroundHMargin;
-	pango_layout_set_width (layout, layoutWidth * PANGO_SCALE);
+    if (!textUpdateSurface (s, data, width, height))
+	return FALSE;
 
-	cairo_surface_destroy (surface);
-	cairo_destroy (cr);
-	XFreePixmap (dpy, pixmap);
-	pixmap = None;
+    pango_cairo_update_layout (data->cr, data->layout);
 
-	if (w > 0 && h > 0)
-	    pixmap = XCreatePixmap (dpy, textAttrib->screen->root, w, h, 32);
+    cairo_save (data->cr);
+    cairo_set_operator (data->cr, CAIRO_OPERATOR_CLEAR);
+    cairo_paint (data->cr);
+    cairo_restore (data->cr);
 
-	if (!pixmap)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create %d x %d pixmap.", w, h);
-	    pango_font_description_free (font);
-	    g_object_unref (layout);
-	    return FALSE;
-	}
+    cairo_set_operator (data->cr, CAIRO_OPERATOR_OVER);
 
-	surface = cairo_xlib_surface_create_with_xrender_format (dpy, pixmap,
-								 screen, format,
-								 w, h);
-	if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create surface.");
-	    pango_font_description_free (font);
-	    g_object_unref (layout);
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+    if (attrib->flags & CompTextStyleWithBackground)
+    {
+	textDrawTextBackground (data->cr, 0, 0, width, height,
+				MIN (attrib->bgHMargin, attrib->bgVMargin));
+	cairo_set_source_rgba (data->cr,
+			       attrib->bgColor[0] / 65535.0,
+			       attrib->bgColor[1] / 65535.0,
+			       attrib->bgColor[2] / 65535.0,
+			       attrib->bgColor[3] / 65535.0);
+	cairo_fill (data->cr);
+	cairo_move_to (data->cr, attrib->bgHMargin, attrib->bgVMargin);
+    }
 
-	cr = cairo_create (surface);
-	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	{
-	    compLogMessage ("text", CompLogLevelError,
-			    "Couldn't create cairo context.");
-	    cairo_surface_destroy (surface);
-	    pango_font_description_free (font);
-	    g_object_unref (layout);
-	    XFreePixmap (dpy, pixmap);
-	    return FALSE;
-	}
+    cairo_set_source_rgba (data->cr,
+			   attrib->color[0] / 65535.0,
+			   attrib->color[1] / 65535.0,
+			   attrib->color[2] / 65535.0,
+			   attrib->color[3] / 65535.0);
 
-	pango_cairo_update_layout (cr, layout);
+    pango_cairo_show_layout (data->cr, data->layout);
 
-	cairo_save (cr);
-	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-	cairo_paint (cr);
-	cairo_restore (cr);
+    return TRUE;
+}
+
+static void
+textCleanupSurface (TextSurfaceData *data)
+{
+    if (data->layout)
+	g_object_unref (data->layout);
+    if (data->surface)
+	cairo_surface_destroy (data->surface);
+    if (data->cr)
+	cairo_destroy (data->cr);
+    if (data->font)
+	pango_font_description_free (data->font);
+}
 
-	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+static Bool
+textRenderText (CompScreen           *s,
+		const char           *text,
+		const CompTextAttrib *attrib,
+		CompTextData         *data)
+{
+    TextSurfaceData surface;
+    Bool            retval = FALSE;
 
-	if (textAttrib->style & TEXT_STYLE_BACKGROUND)
+    if (!text)
+	return FALSE;
+
+    memset (&surface, 0, sizeof (TextSurfaceData));
+
+    if (textInitSurface (s, &surface) &&
+	textDrawText (s, text, &surface, attrib))
+    {
+	data->pixmap = surface.pixmap;
+	data->width  = surface.width;
+	data->height = surface.height;
+
+	retval = TRUE;
+    }
+
+    if (!retval && surface.pixmap)
+	XFreePixmap (s->display->display, surface.pixmap);
+
+    textCleanupSurface (&surface);
+
+    return retval;
+}
+
+static Bool
+textRenderWindowTitle (CompScreen           *s,
+		       Window               window,
+		       Bool                 withViewportNumber,
+		       const CompTextAttrib *attrib,
+		       CompTextData         *data)
+{
+    char *text;
+    Bool retval;
+
+    if (withViewportNumber)
+    {
+	char *title;
+	
+	title = textGetWindowName (s->display, window);
+	if (title)
 	{
-	    textDrawTextBackground (cr, 0, 0, w, h,
-				    MIN (textAttrib->backgroundHMargin,
-					 textAttrib->backgroundVMargin));
-	    cairo_set_source_rgba (cr,
-				   textAttrib->backgroundColor[0] / 65535.0,
-				   textAttrib->backgroundColor[1] / 65535.0,
-				   textAttrib->backgroundColor[2] / 65535.0,
-				   textAttrib->backgroundColor[3] / 65535.0);
-	    cairo_fill (cr);
-	    cairo_move_to (cr, textAttrib->backgroundHMargin,
-			   textAttrib->backgroundVMargin);
+	    CompWindow *w;
+
+	    w = findWindowAtDisplay (s->display, window);
+	    if (w)
+	    {
+		int vx, vy, viewport;
+
+		defaultViewportForWindow (w, &vx, &vy);
+		viewport = vy * w->screen->hsize + vx + 1;
+		asprintf (&text, "%s -[%d]-", title, viewport);
+		free (title);
+	    }
+	    else
+	    {
+		text = title;
+	    }
 	}
-	cairo_set_source_rgba (cr,
-			       textAttrib->color[0] / 65535.0,
-     			       textAttrib->color[1] / 65535.0,
-			       textAttrib->color[2] / 65535.0,
-			       textAttrib->color[3] / 65535.0);
-	pango_cairo_show_layout (cr, layout);
-
-	g_object_unref (layout);
-	cairo_surface_destroy (surface);
-	cairo_destroy (cr);
-	pango_font_description_free (font);
-
-	*width  = w;
-	*height = h;
-	*data   = (void *)pixmap;
-
-	return TRUE;
+    }
+    else
+    {
+	text = textGetWindowName (s->display, window);
     }
 
-    UNWRAP (td, d, fileToImage);
-    status = (*d->fileToImage) (d, path, name, width, height, stride, data);
-    WRAP (td, d, fileToImage, textFileToImage);
+    if (!text)
+	return FALSE;
+
+    retval = textRenderText (s, text, attrib, data);
+    free (text);
 
-    return status;
+    return retval;
+}
+
+static TextFunc textFunctions =
+{
+    .renderText        = textRenderText,
+    .renderWindowTitle = textRenderWindowTitle
+};
+static const CompMetadataOptionInfo textDisplayOptionInfo[] = {
+    { "abi", "int", 0, 0, 0 },
+    { "index", "int", 0, 0, 0 }
+};
+
+static CompOption *
+textGetDisplayOptions (CompPlugin  *plugin,
+		       CompDisplay *display,
+		       int         *count)
+{
+    TEXT_DISPLAY (display);
+
+    *count = NUM_OPTIONS (td);
+    return td->opt;
 }
 
 static Bool
@@ -456,7 +491,6 @@ textInitDisplay (CompPlugin  *p,
 		 CompDisplay *d)
 {
     TextDisplay *td;
-    CompOption  *o;
 
     if (!checkPluginABI ("core", CORE_ABIVERSION))
 	return FALSE;
@@ -465,15 +499,24 @@ textInitDisplay (CompPlugin  *p,
     if (!td)
 	return FALSE;
 
+    if (!compInitDisplayOptionsFromMetadata (d,
+					     &textMetadata,
+					     textDisplayOptionInfo,
+					     td->opt,
+					     TEXT_DISPLAY_OPTION_NUM))
+    {
+	free (td);
+	return FALSE;
+    }
+
     td->visibleNameAtom = XInternAtom (d->display,
 				       "_NET_WM_VISIBLE_NAME", 0);
 
-    WRAP (td, d, fileToImage, textFileToImage);
-
-    d->base.privates[displayPrivateIndex].ptr = td;
+    td->opt[TEXT_DISPLAY_OPTION_ABI].value.i   = TEXT_ABIVERSION;
+    td->opt[TEXT_DISPLAY_OPTION_INDEX].value.i = functionsPrivateIndex;
 
-    o = textGetAbiOption (d);
-    o->value.i = TEXT_ABIVERSION;
+    d->base.privates[displayPrivateIndex].ptr   = td;
+    d->base.privates[functionsPrivateIndex].ptr = &textFunctions;
 
     return TRUE;
 }
@@ -484,7 +527,7 @@ textFiniDisplay (CompPlugin  *p,
 {
     TEXT_DISPLAY (d);
 
-    UNWRAP (td, d, fileToImage);
+    compFiniDisplayOptions (d, td->opt, TEXT_DISPLAY_OPTION_NUM);
 
     free (td);
 }
@@ -513,12 +556,47 @@ textFiniObject (CompPlugin *p,
     DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
 }
 
+static CompOption *
+textGetObjectOptions (CompPlugin *plugin,
+		      CompObject *object,
+		      int        *count)
+{
+    static GetPluginObjectOptionsProc dispTab[] = {
+	(GetPluginObjectOptionsProc) 0, /* GetCoreOptions */
+	(GetPluginObjectOptionsProc) textGetDisplayOptions
+    };
+
+    RETURN_DISPATCH (object, dispTab, ARRAY_SIZE (dispTab),
+		     (void *) (*count = 0), (plugin, object, count));
+}
+
+
 static Bool
 textInit (CompPlugin *p)
 {
+    if (!compInitPluginMetadataFromInfo (&textMetadata,
+					 p->vTable->name,
+					 textDisplayOptionInfo,
+					 TEXT_DISPLAY_OPTION_NUM,
+					 NULL, 0))
+	return FALSE;
+
     displayPrivateIndex = allocateDisplayPrivateIndex ();
     if (displayPrivateIndex < 0)
+    {
+	compFiniMetadata (&textMetadata);
 	return FALSE;
+    }
+
+    functionsPrivateIndex = allocateDisplayPrivateIndex ();
+    if (functionsPrivateIndex < 0)
+    {
+	freeDisplayPrivateIndex (displayPrivateIndex);
+	compFiniMetadata (&textMetadata);
+	return FALSE;
+    }
+    
+    compAddMetadataFromFile (&textMetadata, p->vTable->name);
 
     return TRUE;
 }
@@ -526,22 +604,30 @@ textInit (CompPlugin *p)
 static void
 textFini (CompPlugin *p)
 {
-    freeDisplayPrivateIndex(displayPrivateIndex);
+    freeDisplayPrivateIndex (displayPrivateIndex);
+    freeDisplayPrivateIndex (functionsPrivateIndex);
+    compFiniMetadata (&textMetadata);
+}
+
+static CompMetadata *
+textGetMetadata (CompPlugin *p)
+{
+    return &textMetadata;
 }
 
 CompPluginVTable textVTable = {
     "text",
-    0,
+    textGetMetadata,
     textInit,
     textFini,
     textInitObject,
     textFiniObject,
-    0,
+    textGetObjectOptions,
     0
 };
 
-CompPluginVTable*
-getCompPluginInfo (void)
+CompPluginVTable *
+getCompPluginInfo20070830 (void)
 {
     return &textVTable;
 }
diff --git a/text.xml.in b/text.xml.in
index 4810486..b47b234 100644
--- a/text.xml.in
+++ b/text.xml.in
@@ -1,11 +1,12 @@
 <?xml version="1.0"?>
 <compiz>
-	<plugin name="text" useBcop="true">
+	<plugin name="text">
 		<_short>Text</_short>
 		<_long>Render text to texture</_long>
 		<category>Image Loading</category>
 		<display>
 			<option name="abi" type="int" read_only="true"/>
+			<option name="index" type="int" read_only="true"/>
 		</display>
 	</plugin>
 </compiz>
-- 
1.6.0.6

>From ed5636858a87d09392abc4518e5bea1d8056fc88 Mon Sep 17 00:00:00 2001
From: Danny Baumann <dannybaum...@web.de>
Date: Sun, 4 Jan 2009 17:49:47 +0100
Subject: [PATCH] Adapt for new text plugin interface.

---
 ring.c |  105 ++++++++++++++++++++++++++++++----------------------------------
 1 files changed, 49 insertions(+), 56 deletions(-)

diff --git a/ring.c b/ring.c
index 189ed88..c69c828 100644
--- a/ring.c
+++ b/ring.c
@@ -65,7 +65,7 @@ typedef struct _RingDrawSlot {
 typedef struct _RingDisplay {
     int		    screenPrivateIndex;
     HandleEventProc handleEvent;
-    Bool            textAvailable;
+    TextFunc        *textFunc;
 } RingDisplay;
 
 typedef struct _RingScreen {
@@ -100,10 +100,8 @@ typedef struct _RingScreen {
     Window selectedWindow;
 
     /* text display support */
-    CompTexture textTexture;
-    Pixmap      textPixmap;
-    int         textWidth;
-    int         textHeight;
+    CompTexture  textTexture;
+    CompTextData textData;
 
     CompMatch match;
     CompMatch *currentMatch;
@@ -205,21 +203,19 @@ ringFreeWindowTitle (CompScreen *s)
 {
     RING_SCREEN(s);
 
-    if (!rs->textPixmap)
+    if (!rs->textData.pixmap)
 	return;
 
     releasePixmapFromTexture (s, &rs->textTexture);
     initTexture (s, &rs->textTexture);
-    XFreePixmap (s->display->display, rs->textPixmap);
-    rs->textPixmap = None;
+    XFreePixmap (s->display->display, rs->textData.pixmap);
+    rs->textData.pixmap = None;
 }
 
 static void 
 ringRenderWindowTitle (CompScreen *s)
 {
-    CompTextAttrib tA;
-    int            stride;
-    void           *data;
+    CompTextAttrib attrib;
     int            ox1, ox2, oy1, oy2;
 
     RING_SCREEN (s);
@@ -227,7 +223,7 @@ ringRenderWindowTitle (CompScreen *s)
 
     ringFreeWindowTitle (s);
 
-    if (!rd->textAvailable)
+    if (!rd->textFunc)
 	return;
 
     if (!rs->selectedWindow)
@@ -239,48 +235,37 @@ ringRenderWindowTitle (CompScreen *s)
     getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);
 
     /* 75% of the output device as maximum width */
-    tA.maxWidth = (ox2 - ox1) * 3 / 4;
-    tA.maxHeight = 100;
-    tA.screen = s;
-    tA.size = ringGetTitleFontSize (s);
-    tA.color[0] = ringGetTitleFontColorRed (s);
-    tA.color[1] = ringGetTitleFontColorGreen (s);
-    tA.color[2] = ringGetTitleFontColorBlue (s);
-    tA.color[3] = ringGetTitleFontColorAlpha (s);
-    tA.style = (ringGetTitleFontBold (s)) ?
-	       TEXT_STYLE_BOLD : TEXT_STYLE_NORMAL;
-    tA.style |= TEXT_STYLE_BACKGROUND;
-    tA.family = "Sans";
-    tA.ellipsize = TRUE;
-    tA.backgroundHMargin = 15;
-    tA.backgroundVMargin = 15;
-    tA.backgroundColor[0] = ringGetTitleBackColorRed (s);
-    tA.backgroundColor[1] = ringGetTitleBackColorGreen (s);
-    tA.backgroundColor[2] = ringGetTitleBackColorBlue (s);
-    tA.backgroundColor[3] = ringGetTitleBackColorAlpha (s);
-
-    if (rs->type == RingTypeAll)
-	tA.renderMode = TextRenderWindowTitleWithViewport;
-    else
-	tA.renderMode = TextRenderWindowTitle;
-
-    tA.data = (void*)rs->selectedWindow;
+    attrib.maxWidth = (ox2 - ox1) * 3 / 4;
+    attrib.maxHeight = 100;
+
+    attrib.size = ringGetTitleFontSize (s);
+    attrib.color[0] = ringGetTitleFontColorRed (s);
+    attrib.color[1] = ringGetTitleFontColorGreen (s);
+    attrib.color[2] = ringGetTitleFontColorBlue (s);
+    attrib.color[3] = ringGetTitleFontColorAlpha (s);
+    attrib.flags = CompTextStyleWithBackground | CompTextStyleEllipsized;
+    if (ringGetTitleFontBold (s))
+	attrib.flags |= CompTextStyleBold;
+    attrib.family = "Sans";
+    attrib.bgHMargin = 15;
+    attrib.bgVMargin = 15;
+    attrib.bgColor[0] = ringGetTitleBackColorRed (s);
+    attrib.bgColor[1] = ringGetTitleBackColorGreen (s);
+    attrib.bgColor[2] = ringGetTitleBackColorBlue (s);
+    attrib.bgColor[3] = ringGetTitleBackColorAlpha (s);
 
     initTexture (s, &rs->textTexture);
 
-    if ((*s->display->fileToImage) (s->display, TEXT_ID, (char *)&tA,
-			 	    &rs->textWidth, &rs->textHeight,
-				    &stride, &data))
+    if (rd->textFunc->renderWindowTitle (s, rs->selectedWindow,
+					 rs->type == RingTypeAll,
+					 &attrib, &rs->textData))
     {
-	rs->textPixmap = (Pixmap)data;
-	bindPixmapToTexture (s, &rs->textTexture, rs->textPixmap,
-			     rs->textWidth, rs->textHeight, 32);
+	bindPixmapToTexture (s, &rs->textTexture, rs->textData.pixmap,
+			     rs->textData.width, rs->textData.height, 32);
     }
     else 
     {
-	rs->textPixmap = None;
-	rs->textWidth  = 0;
-	rs->textHeight = 0;
+	memset (&rs->textData, 0, sizeof (rs->textData));
     }
 }
 
@@ -295,12 +280,12 @@ ringDrawWindowTitle (CompScreen *s)
 
     RING_SCREEN (s);
 
-    width = rs->textWidth;
-    height = rs->textHeight;
+    width = rs->textData.width;
+    height = rs->textData.height;
 
     getCurrentOutputExtents (s, &ox1, &oy1, &ox2, &oy2);
 
-    x = ox1 + ((ox2 - ox1) / 2) - (rs->textWidth / 2);
+    x = ox1 + ((ox2 - ox1) / 2) - (rs->textData.width / 2);
 
     /* assign y (for the lower corner!) according to the setting */
     switch (ringGetTitleTextPlacement (s))
@@ -995,7 +980,7 @@ ringPaintOutput (CompScreen		  *s,
 
 	rs->paintingSwitcher = FALSE;
 
-	if (rs->textPixmap && (rs->state != RingStateIn))
+	if (rs->textData.pixmap && (rs->state != RingStateIn))
 	    ringDrawWindowTitle (s);
 	
 	glPopMatrix ();
@@ -1383,7 +1368,8 @@ ringWindowSelectAt (CompScreen *s,
 
 	ringTerminate (s->display, NULL, 0, &o, 1);
     }
-    else if (!terminate && (selected != rs->selectedWindow || !rs->textPixmap))
+    else if (!terminate &&
+	     (selected != rs->selectedWindow || !rs->textData.pixmap))
     {
 	if (!selected)
 	{
@@ -1593,6 +1579,7 @@ ringInitDisplay (CompPlugin  *p,
 		 CompDisplay *d)
 {
     RingDisplay *rd;
+    int         index;
 
     if (!checkPluginABI ("core", CORE_ABIVERSION))
 	return FALSE;
@@ -1608,10 +1595,17 @@ ringInitDisplay (CompPlugin  *p,
 	return FALSE;
     }
 
-    rd->textAvailable = checkPluginABI ("text", TEXT_ABIVERSION);
-    if (!rd->textAvailable)
+    if (checkPluginABI ("text", TEXT_ABIVERSION) &&
+	getPluginDisplayIndex (d, "text", &index))
+    {
+	rd->textFunc = d->base.privates[index].ptr;
+    }
+    else
+    {
 	compLogMessage ("ring", CompLogLevelWarn,
 			"No compatible text plugin found.");
+	rd->textFunc = NULL;
+    }
 
     ringSetNextKeyInitiate (d, ringNext);
     ringSetNextKeyTerminate (d, ringTerminate);
@@ -1696,8 +1690,7 @@ ringInitScreen (CompPlugin *p,
     rs->rotAdjust = 0;
     rs->rVelocity = 0;
 
-    rs->textPixmap = None;
-
+    memset (&rs->textData, 0, sizeof (rs->textData));
     matchInit (&rs->match);
 
     WRAP (rs, s, preparePaintScreen, ringPreparePaintScreen);
-- 
1.6.0.6

_______________________________________________
Dev mailing list
Dev@lists.compiz-fusion.org
http://lists.compiz-fusion.org/mailman/listinfo/dev

Reply via email to