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