diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2009-09-18 01:35:00 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2009-09-24 12:14:41 -0700 |
commit | 9252dcd454ffe5d1aa740d066169834961cb383c (patch) | |
tree | 69c0981d3719b2b1ff8ffdfcc1644688ab016406 | |
parent | afeb0353ceabc5e2cbb21a48159a3334e8024765 (diff) |
Secure label area.
-rw-r--r-- | metadata/Makefile.am | 1 | ||||
-rw-r--r-- | metadata/flask.xml.in | 15 | ||||
-rw-r--r-- | plugins/Makefile.am | 6 | ||||
-rw-r--r-- | plugins/flask.c | 407 |
4 files changed, 429 insertions, 0 deletions
diff --git a/metadata/Makefile.am b/metadata/Makefile.am index af5c9ce..db82d35 100644 --- a/metadata/Makefile.am +++ b/metadata/Makefile.am @@ -9,6 +9,7 @@ xml_in_files = \ dbus.xml.in \ decoration.xml.in \ fade.xml.in \ + flask.xml.in \ fs.xml.in \ gconf.xml.in \ glib.xml.in \ diff --git a/metadata/flask.xml.in b/metadata/flask.xml.in new file mode 100644 index 0000000..4a202d4 --- /dev/null +++ b/metadata/flask.xml.in @@ -0,0 +1,15 @@ +<compiz> + <plugin name="flask"> + <_short>Flaskification</_short> + <_long>Flaskification</_long> + <category>Effects</category> + <feature>securelabel</feature> + <deps> + <relation type="after"> + <plugin>decoration</plugin> + </relation> + </deps> + <display> + </display> + </plugin> +</compiz> diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 0bb4d51..6e6271a 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,6 +1,11 @@ libfade_la_LDFLAGS = -module -avoid-version -no-undefined libfade_la_SOURCES = fade.c +libflask_la_DEPENDENCIES = $(top_builddir)/libdecoration/libdecoration.la +libflask_la_LDFLAGS = -module -avoid-version -no-undefined +libflask_la_LIBADD = $(top_builddir)/libdecoration/libdecoration.la +libflask_la_SOURCES = flask.c + libcube_la_LDFLAGS = -module -avoid-version -no-undefined libcube_la_SOURCES = cube.c @@ -160,6 +165,7 @@ module_LTLIBRARIES = \ libdecoration.la \ libwobbly.la \ libfade.la \ + libflask.la \ libminimize.la \ libcube.la \ librotate.la \ diff --git a/plugins/flask.c b/plugins/flask.c new file mode 100644 index 0000000..00043cc --- /dev/null +++ b/plugins/flask.c @@ -0,0 +1,407 @@ +/* + * Copyright © 2006 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman <davidr@novell.com> + */ + +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#include <compiz.h> +#include <compiz-core.h> + +#include <X11/Xatom.h> + +static int displayPrivateIndex; + +static CompMetadata flaskMetadata; + +typedef struct _FlaskTexture { + Pixmap pixmap; + Damage damage; + CompTexture texture; +} FlaskTexture; + +typedef struct _FlaskDisplay { + HandleEventProc handleEvent; + + int screenPrivateIndex; + Atom securityAtom; +} FlaskDisplay; + +typedef struct _FlaskScreen { + PaintOutputProc paintOutput; + + Window rootWindow; + Pixmap pixmap; + FlaskTexture *texture; + int width; + int height; + int errorStatus; +} FlaskScreen; + +#define GET_FLASK_DISPLAY(d) \ + ((FlaskDisplay *) (d)->base.privates[displayPrivateIndex].ptr) + +#define FLASK_DISPLAY(d) \ + FlaskDisplay *ad = GET_FLASK_DISPLAY (d) + +#define GET_FLASK_SCREEN(s, ad) \ + ((FlaskScreen *) (s)->base.privates[(ad)->screenPrivateIndex].ptr) + +#define FLASK_SCREEN(s) \ + FlaskScreen *as = GET_FLASK_SCREEN (s, GET_FLASK_DISPLAY (s->display)) + + +static FlaskTexture * +flaskGetTexture (CompScreen *screen) +{ + FlaskTexture *texture; + unsigned int width, height, depth, ui; + Window root; + int i; + + FLASK_SCREEN (screen); + + texture = malloc (sizeof (FlaskTexture)); + if (!texture) + return NULL; + + initTexture (screen, &texture->texture); + + if (!XGetGeometry (screen->display->display, as->pixmap, &root, + &i, &i, &width, &height, &ui, &depth)) + { + finiTexture (screen, &texture->texture); + free (texture); + return NULL; + } + + if (!bindPixmapToTexture (screen, &texture->texture, as->pixmap, + as->width, as->height, depth)) + { + finiTexture (screen, &texture->texture); + free (texture); + return NULL; + } + + texture->damage = XDamageCreate (screen->display->display, as->pixmap, + XDamageReportRawRectangles); + + texture->pixmap = as->pixmap; + + return texture; +} + +static void +flaskReleaseTexture (CompScreen *screen, + FlaskTexture *texture) +{ + if (texture) { + finiTexture (screen, &texture->texture); + free (texture); + } +} + +static Bool +flaskPaintOutput (CompScreen *s, + const ScreenPaintAttrib *sAttrib, + const CompTransform *transform, + Region region, + CompOutput *output, + unsigned int mask) +{ + Bool status; + float width, height, x1, x2, y1, y2; + + FLASK_SCREEN (s); + + UNWRAP (as, s, paintOutput); + status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask); + WRAP (as, s, paintOutput, flaskPaintOutput); + + if (status && as->texture && region->numRects) + { + glPushMatrix (); + + enableTexture (s, &as->texture->texture, COMP_TEXTURE_FILTER_FAST); + + height = (float)as->height / (float)as->width * 3.5f; + height *= (float)s->width / (float)s->height; + + x1 = -1.75f; + y1 = -2.0f; + x2 = 1.75f; + y2 = height - 2.0f; + + glBegin(GL_QUADS); + glTexCoord2i(0, as->height); + glVertex3f(x1, y1, -4.0f); + + glTexCoord2i(as->width, as->height); + glVertex3f(x2, y1, -4.0f); + + glTexCoord2i(as->width, 0); + glVertex3f(x2, y2, -4.0f); + + glTexCoord2i(0, 0); + glVertex3f(x1, y2, -4.0f); + + glEnd(); + + disableTexture (s, &as->texture->texture); + + glFlush(); + + glPopMatrix (); + } + + return status; +} + +static void +flaskUpdateSecurityPixmap (CompScreen *s) +{ + Atom actual; + int result, format; + unsigned long n, nleft; + unsigned char *data; + long *prop; + + FLASK_SCREEN (s); + FLASK_DISPLAY (s->display); + + flaskReleaseTexture(s, as->texture); + as->texture = NULL; + + result = XGetWindowProperty (s->display->display, as->rootWindow, + ad->securityAtom, 0L, 3L, FALSE, + XA_INTEGER, &actual, &format, + &n, &nleft, &data); + + if (result == Success && data) { + if (n >= 3) { + prop = (long *) data; + as->pixmap = prop[0]; + as->width = 1000; //prop[1]; + as->height = 40; //prop[2]; + as->texture = flaskGetTexture(s); + } + + XFree (data); + } +} + +static void +flaskHandleEvent (CompDisplay *d, + XEvent *event) +{ + CompScreen *s; + FlaskScreen *as; + + FLASK_DISPLAY (d); + + UNWRAP (ad, d, handleEvent); + (*d->handleEvent) (d, event); + WRAP (ad, d, handleEvent, flaskHandleEvent); + + if (event->type == PropertyNotify && + event->xproperty.atom == ad->securityAtom) + { + for (s = d->screens; s; s = s->next) + { + as = GET_FLASK_SCREEN (s, ad); + if (event->xproperty.window == as->rootWindow) { + flaskUpdateSecurityPixmap (s); + damageScreen (s); + break; + } + } + } + else if (event->type == d->damageEvent + XDamageNotify) + { + XDamageNotifyEvent *de = (XDamageNotifyEvent *) event; + + for (s = d->screens; s; s = s->next) + { + as = GET_FLASK_SCREEN (s, ad); + if (as->texture && as->texture->pixmap == de->drawable) + { + as->texture->texture.oldMipmaps = TRUE; + damageScreen (s); + break; + } + } + } +} + +static Bool +flaskInitDisplay (CompPlugin *p, + CompDisplay *d) +{ + FlaskDisplay *ad; + + ad = malloc (sizeof (FlaskDisplay)); + if (!ad) + return FALSE; + + ad->screenPrivateIndex = allocateScreenPrivateIndex (d); + if (ad->screenPrivateIndex < 0) + { + free (ad); + return FALSE; + } + + ad->securityAtom = XInternAtom (d->display, "_COMPIZ_SECURITY_PIXMAP", 0); + + WRAP (ad, d, handleEvent, flaskHandleEvent); + + d->base.privates[displayPrivateIndex].ptr = ad; + + return TRUE; +} + +static void +flaskFiniDisplay (CompPlugin *p, + CompDisplay *d) +{ + FLASK_DISPLAY (d); + + freeScreenPrivateIndex (d, ad->screenPrivateIndex); + + free (ad); +} + +static Bool +flaskInitScreen (CompPlugin *p, + CompScreen *s) +{ + FlaskScreen *as; + + FLASK_DISPLAY (s->display); + + as = malloc (sizeof (FlaskScreen)); + if (!as) + return FALSE; + + as->rootWindow = RootWindow(s->display->display, s->screenNum); + as->texture = NULL; + + WRAP (as, s, paintOutput, flaskPaintOutput); + + s->base.privates[ad->screenPrivateIndex].ptr = as; + + flaskUpdateSecurityPixmap (s); + + return TRUE; +} + +static void +flaskFiniScreen (CompPlugin *p, + CompScreen *s) +{ + FLASK_SCREEN (s); + + UNWRAP (as, s, paintOutput); + + flaskReleaseTexture (s, as->texture); + free (as); +} + +static Bool +flaskInit (CompPlugin *p) +{ + if (!compInitPluginMetadataFromInfo (&flaskMetadata, + p->vTable->name, + NULL, + 0, + 0, 0)) + return FALSE; + + displayPrivateIndex = allocateDisplayPrivateIndex (); + if (displayPrivateIndex < 0) + { + compFiniMetadata (&flaskMetadata); + return FALSE; + } + + compAddMetadataFromFile (&flaskMetadata, p->vTable->name); + + return TRUE; +} + +static void +flaskFini (CompPlugin *p) +{ + if (displayPrivateIndex >= 0) + freeDisplayPrivateIndex (displayPrivateIndex); + + compFiniMetadata (&flaskMetadata); +} + +static CompMetadata * +flaskGetMetadata (CompPlugin *plugin) +{ + return &flaskMetadata; +} + +static CompBool +flaskInitObject (CompPlugin *p, + CompObject *o) +{ + static InitPluginObjectProc dispTab[] = { + 0, + (InitPluginObjectProc) flaskInitDisplay, + (InitPluginObjectProc) flaskInitScreen, + }; + + RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o)); +} + +static void +flaskFiniObject (CompPlugin *p, + CompObject *o) +{ + static FiniPluginObjectProc dispTab[] = { + 0, + (FiniPluginObjectProc) flaskFiniDisplay, + (FiniPluginObjectProc) flaskFiniScreen, + }; + + DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o)); +} + +static CompPluginVTable flaskVTable = { + "flask", + flaskGetMetadata, + flaskInit, + flaskFini, + flaskInitObject, + flaskFiniObject, +}; + +CompPluginVTable * +getCompPluginInfo20070830 (void) +{ + return &flaskVTable; +} |