/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. (c) Diogo Ferreira Authors: Diogo Ferreira */ #include #include #include #include static CompMetadata magickMetadata; static int displayPrivateIndex; /* plugin structures */ typedef struct _MagickDisplay { FileToImageProc fileToImage; ImageToFileProc imageToFile; } MagickDisplay; #define GET_MAGICK_DISPLAY(d) \ ((MagickDisplay *) (d)->privates[displayPrivateIndex].ptr) #define MAGICK_DISPLAY(d) \ MagickDisplay *md = GET_MAGICK_DISPLAY (d) /* image methods */ static Bool magickFileToImage ( CompDisplay *d, const char *path, const char *name, int *width, int *height, int *stride, void **data ) { Bool status = FALSE; char *file; int len; MAGICK_DISPLAY(d); if (name && strstr(name,".")) { len = (path ? strlen(path) : 0) + strlen(name) + 1; file = malloc(len); if (file) { MagickWand *wand; MagickBooleanType result; if (path) sprintf(file, "%s/%s", path, name); else sprintf(file, "%s", name); wand = NewMagickWand (); result = MagickReadImage (wand, file); if (result != MagickFalse) { *width = MagickGetImageWidth (wand); *height = MagickGetImageHeight(wand); *data = malloc (*width * *height * 4); if (*data) { MagickGetImagePixels(wand, 0,0, *width, *height, "BGRA", CharPixel, *data); *stride = *width * 4; free (file); wand = DestroyMagickWand (wand); return TRUE; } } free (file); wand = DestroyMagickWand (wand); } } UNWRAP (md, d, fileToImage); status = (*d->fileToImage) (d, path, name, width, height, stride, data); WRAP (md, d, fileToImage, magickFileToImage); return status; } static Bool magickImageToFile ( CompDisplay *d, const char *path, const char *name, const char *format, int width, int height, int stride, void *data ) { Bool status = FALSE; char *file; int len; MAGICK_DISPLAY(d); len = (path ? strlen (path) : 0) + strlen(name) + 1; file = malloc (len); if (file) { MagickWand *wand; MagickBooleanType result; if (path) sprintf(file, "%s/%s",path,name); else sprintf(file, "%s",name); wand = NewMagickWand (); result = MagickNewImage (wand, width, height, NewPixelWand ()); if (result != MagickFalse) { MagickSetImagePixels(wand, 0,0, width, height, "RGBA", CharPixel, data); /*FIXME: compiz passes the pixels in a different order than imagemagick is expecting, so flipping solves the problem*/ MagickFlipImage (wand); result = MagickWriteImage (wand, file); if (result != MagickFalse) { free (file); wand = DestroyMagickWand (wand); return TRUE; } } free (file); wand = DestroyMagickWand (wand); } UNWRAP (md, d, imageToFile); status = (*d->imageToFile) (d, path, name, format, width, height, stride, data); WRAP (md, d, imageToFile, magickImageToFile); return status; } /* compiz glue */ static Bool magickInitDisplay (CompPlugin *p, CompDisplay *d) { MagickDisplay *md = malloc (sizeof(MagickDisplay)); if (!md) return FALSE; WRAP(md, d, fileToImage, magickFileToImage); WRAP(md, d, imageToFile, magickImageToFile); d->privates[displayPrivateIndex].ptr = md; return TRUE; } static void magickFiniDisplay (CompPlugin *p, CompDisplay *d) { MAGICK_DISPLAY (d); UNWRAP (md, d, fileToImage); UNWRAP (md, d, imageToFile); free (md); } static Bool magickInit (CompPlugin *p) { if (!compInitPluginMetadataFromInfo (&magickMetadata, p->vTable->name, 0, 0, 0, 0)) return FALSE; displayPrivateIndex = allocateDisplayPrivateIndex (); if (displayPrivateIndex < 0) { compFiniMetadata (&magickMetadata); return FALSE; } compAddMetadataFromFile (&magickMetadata, p->vTable->name); MagickWandGenesis (); return TRUE; } static void magickFini (CompPlugin *p) { MagickWandTerminus (); freeDisplayPrivateIndex (displayPrivateIndex); compFiniMetadata (&magickMetadata); } static int magickGetVersion (CompPlugin *p, int version) { return ABIVERSION; } static CompMetadata *magickGetMetadata (CompPlugin *plugin) { return &magickMetadata; } CompPluginVTable magickVTable = { "magick", magickGetVersion, magickGetMetadata, magickInit, magickFini, magickInitDisplay, magickFiniDisplay, 0, /* InitScreen */ 0, /* FiniScreen */ 0, /* InitWindow */ 0, /* FiniWindow */ 0, /* GetDisplayOptions */ 0, /* SetDisplayOption */ 0, /* GetScreenOptions */ 0, /* SetScreenOption */ 0, /* Deps */ 0, /* nDeps */ 0, /* Features */ 0 /* nFeatures */ }; CompPluginVTable *getCompPluginInfo () { return &magickVTable; }