summaryrefslogtreecommitdiff
path: root/beryl-plugins/src/neg.c
diff options
context:
space:
mode:
authorquinn <quinn@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-09-27 23:19:52 +0000
committerquinn <quinn@d7aaf104-2d23-0410-ae22-9d23157bf5a3>2006-09-27 23:19:52 +0000
commit4c9796dddab60529fff57638d3cb0d8ca830a3fe (patch)
tree1c54f385f71dc9897381c7b266ff1090137a74e1 /beryl-plugins/src/neg.c
parent6e36e85e06f7cf5edc75016bc2bb2612c0ee80c1 (diff)
downloadmarex-dev-4c9796dddab60529fff57638d3cb0d8ca830a3fe.tar.gz
marex-dev-4c9796dddab60529fff57638d3cb0d8ca830a3fe.tar.bz2
move in beryl-plugins
git-svn-id: file:///beryl/trunk@325 d7aaf104-2d23-0410-ae22-9d23157bf5a3
Diffstat (limited to 'beryl-plugins/src/neg.c')
-rw-r--r--beryl-plugins/src/neg.c732
1 files changed, 732 insertions, 0 deletions
diff --git a/beryl-plugins/src/neg.c b/beryl-plugins/src/neg.c
new file mode 100644
index 0000000..120d515
--- /dev/null
+++ b/beryl-plugins/src/neg.c
@@ -0,0 +1,732 @@
+/*
+ * Copyright (c) 2006 Darryll Truchan <moppsy@comcast.net>
+ *
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * I am sure that this is not the right way to do this.
+ * Any advice would be appreciated. I'm still a junior GL'er
+ *
+ * BUGS
+ * water doesn't draw on things negative
+ * neg also doesn't honor an apps initial, non-paintAttrib, opacity
+ *
+ * comments still need work.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <X11/Xatom.h>
+#include <X11/extensions/Xrender.h>
+
+#include <beryl.h>
+
+/* defaults */
+
+#define NEG_TOGGLE_KEY_DEFAULT "n"
+#define NEG_TOGGLE_MODIFIERS_DEFAULT CompSuperMask
+
+#define NEG_TOGGLE_ALL_KEY_DEFAULT "m"
+#define NEG_TOGGLE_ALL_MODIFIERS_DEFAULT CompSuperMask
+
+#define NEG_DISPLAY_OPTION_WINDOW_TOGGLE 0
+#define NEG_DISPLAY_OPTION_SCREEN_TOGGLE 1
+#define NEG_DISPLAY_OPTION_NUM 2
+
+static int displayPrivateIndex;
+
+typedef struct _NEGDisplay
+{
+ int screenPrivateIndex;
+ CompOption opt[NEG_DISPLAY_OPTION_NUM]; /* array of display options */
+} NEGDisplay;
+
+
+typedef struct _NEGSCreen
+{
+ int windowPrivateIndex;
+ DrawWindowTextureProc drawWindowTexture; /* function pointer */
+ DamageWindowRectProc damageWindowRect; /* function pointer */
+ PaintWindowProc paintWindow; /* function pointer */
+ Bool isNeg; /* negative screen flag */
+} NEGScreen;
+
+typedef struct _NEGWindow
+{
+ Bool isNeg; /* negative window flag */
+} NEGWindow;
+
+#define GET_NEG_DISPLAY(d) ((NEGDisplay *) (d)->privates[displayPrivateIndex].ptr)
+#define NEG_DISPLAY(d) NEGDisplay *nd = GET_NEG_DISPLAY (d)
+#define GET_NEG_SCREEN(s, nd) ((NEGScreen *) (s)->privates[(nd)->screenPrivateIndex].ptr)
+#define NEG_SCREEN(s) NEGScreen *ns = GET_NEG_SCREEN (s, GET_NEG_DISPLAY (s->display))
+#define GET_NEG_WINDOW(w, ns) ((NEGWindow *) (w)->privates[(ns)->windowPrivateIndex].ptr)
+#define NEG_WINDOW(w) NEGWindow *nw = GET_NEG_WINDOW (w, GET_NEG_SCREEN (w->screen, GET_NEG_DISPLAY (w->screen->display)))
+
+#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
+
+static void
+NEGToggle (CompWindow * w)
+{
+ NEG_WINDOW (w);
+
+ /* toggle window negative flag */
+ nw->isNeg = !nw->isNeg;
+
+ /* cause repainting */
+ addWindowDamage (w);
+}
+
+static void
+NEGToggleScreen (CompScreen * s)
+{
+ CompWindow *w;
+ NEG_SCREEN (s);
+
+ /* toggle screen negative flag */
+ ns->isNeg = !ns->isNeg;
+
+ /* toggle every window */
+ for (w = s->windows; w; w = w->next)
+ if (w)
+ NEGToggle (w);
+}
+
+static Bool
+negToggle (CompDisplay * d, CompAction * action, CompActionState state,
+ CompOption * option, int nOption)
+{
+ CompWindow *w;
+ Window xid;
+
+ xid = getIntOptionNamed (option, nOption, "window", 0);
+
+ w = findWindowAtDisplay (d, xid);
+
+ if (w)
+ NEGToggle (w);
+
+ return TRUE;
+}
+
+static Bool
+negToggleAll (CompDisplay * d, CompAction * action, CompActionState state,
+ CompOption * option, int nOption)
+{
+ CompScreen *s;
+ Window xid;
+
+ xid = getIntOptionNamed (option, nOption, "root", 0);
+
+ s = findScreenAtDisplay (d, xid);
+
+ if (s)
+ NEGToggleScreen (s);
+
+ return TRUE;
+}
+
+static void
+NEGDrawWindowTexture (CompWindow * w,
+ CompTexture * texture,
+ const WindowPaintAttrib * attrib, unsigned int mask)
+{
+ int filter;
+
+ NEG_SCREEN (w->screen);
+ NEG_WINDOW (w);
+
+ /* PAINT_WINDOW_DECORATION_MASK is set when the decorations are being painted
+ * I didn't want to paint them negative too
+ */
+ if (nw->isNeg && !(mask & PAINT_WINDOW_DECORATION_MASK))
+ {
+
+ /* this is for the most part taken from paint.c */
+
+ /* push the current matrix */
+ glPushMatrix ();
+
+ /* we need this to handle windows that are not regular, like during scale */
+ if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
+ {
+ glTranslatef (w->attrib.x, w->attrib.y, 0.0f);
+ glScalef (attrib->xScale, attrib->yScale, 0.0f);
+ glTranslatef (-w->attrib.x, -w->attrib.y, 0.0f);
+
+ filter = w->screen->filter[WINDOW_TRANS_FILTER];
+ }
+ else if (mask & PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK)
+ {
+ filter = w->screen->filter[SCREEN_TRANS_FILTER];
+ }
+ else
+ {
+ filter = w->screen->filter[NOTHING_TRANS_FILTER];
+ }
+
+ /* if we can addjust saturation, even if it's just on and off */
+ if (w->screen->canDoSaturated && attrib->saturation != COLOR)
+ {
+ GLfloat constant[4];
+
+ /* if the paint mask has this set we want to blend */
+ if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
+ glEnable (GL_BLEND);
+
+ /* enable the texture */
+ enableTexture (w->screen, texture, filter);
+
+ /* texture combiner */
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); /* negate */
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+ glColor4f (1.0f, 1.0f, 1.0f, 0.5f);
+
+ /* make another texture active */
+ w->screen->activeTexture (GL_TEXTURE1_ARB);
+
+ /* enable that texture */
+ enableTexture (w->screen, texture, filter);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ /* if we can do saturation that is in between min and max */
+ if (w->screen->canDoSlightlySaturated && attrib->saturation > 0)
+ {
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+ constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT;
+ constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT;
+ constant[2] = 0.5f + 0.5f * BLUE_SATURATION_WEIGHT;
+ constant[3] = 1.0;
+
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
+
+ /* mack another texture active */
+ w->screen->activeTexture (GL_TEXTURE2_ARB);
+
+ /* enable that texture */
+ enableTexture (w->screen, texture, filter);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); /* negate */
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+ /* color constant */
+ constant[3] = attrib->saturation / 65535.0f;
+
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
+
+ /* if we are not opaque or not fully bright */
+ if (attrib->opacity < OPAQUE || attrib->brightness != BRIGHT)
+ {
+ /* activate a new texture */
+ w->screen->activeTexture (GL_TEXTURE3_ARB);
+
+ /* enable that texture */
+ enableTexture (w->screen, texture, filter);
+
+ /* color constant */
+ constant[3] = attrib->opacity / 65535.0f;
+ constant[0] = constant[1] = constant[2] =
+ constant[3] * attrib->brightness / 65535.0f;
+
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
+ constant);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+ GL_COMBINE);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
+ GL_SRC_ALPHA);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
+ GL_SRC_ALPHA);
+
+ /* draw the window geometry */
+ (*w->screen->drawWindowGeometry) (w);
+
+ /* disable the current texture */
+ disableTexture (w->screen, texture);
+
+ /* set texture mode back to replace */
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+ GL_REPLACE);
+
+ /* re-activate last texture */
+ w->screen->activeTexture (GL_TEXTURE2_ARB);
+ }
+ else
+ {
+ /* fully opaque and bright */
+
+ /* draw the window geometry */
+ (*w->screen->drawWindowGeometry) (w);
+ }
+
+ /* disable the current texture */
+ disableTexture (w->screen, texture);
+
+ /* set the texture mode back to replace */
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ /* re-activate last texture */
+ w->screen->activeTexture (GL_TEXTURE1_ARB);
+ }
+ else
+ {
+ /* fully saturated or fully unsaturated */
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ /* color constant */
+ constant[3] = attrib->opacity / 65535.0f;
+ constant[0] = constant[1] = constant[2] =
+ constant[3] * attrib->brightness / 65535.0f;
+
+ constant[0] =
+ 0.5f + 0.5f * RED_SATURATION_WEIGHT * constant[0];
+ constant[1] =
+ 0.5f + 0.5f * GREEN_SATURATION_WEIGHT * constant[1];
+ constant[2] =
+ 0.5f + 0.5f * BLUE_SATURATION_WEIGHT * constant[2];
+
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
+
+ /* draw the window geometry */
+ (*w->screen->drawWindowGeometry) (w);
+ }
+
+ /* disable the current texture */
+ disableTexture (w->screen, texture);
+
+ /* set the texture mode back to replace */
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ /* re-activate last texture */
+ w->screen->activeTexture (GL_TEXTURE0_ARB);
+
+ /* disable that texture */
+ disableTexture (w->screen, texture);
+
+ /* set the default color */
+ glColor4usv (defaultColor);
+
+ /* set screens texture mode back to replace */
+ screenTexEnvMode (w->screen, GL_REPLACE);
+
+ /* if it's a translucent window, disable blending */
+ if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
+ glDisable (GL_BLEND);
+ }
+ else
+ {
+ /* no saturation adjustments */
+
+ /* enable the current texture */
+ enableTexture (w->screen, texture, filter);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); /* negate */
+
+
+ /* we are not opaque or fully bright */
+ if (attrib->opacity < OPAQUE || attrib->brightness != BRIGHT)
+ {
+ GLfloat constant[4];
+
+ /* enable blending */
+ glEnable (GL_BLEND);
+
+ /* color constant */
+ constant[3] = attrib->opacity / 65535.0f;
+ constant[0] = constant[3] * attrib->brightness / 65535.0f;
+ constant[1] = constant[3] * attrib->brightness / 65535.0f;
+ constant[2] = constant[3] * attrib->brightness / 65535.0f;
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); /* negate */
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
+ glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+ glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+
+ /* draw the window geometry */
+ (*w->screen->drawWindowGeometry) (w);
+
+ /* disable blending */
+ glDisable (GL_BLEND);
+
+ }
+ else
+ {
+ /* no adjustments to saturation, brightness or opacity */
+
+ /* draw the window geometry */
+ (*w->screen->drawWindowGeometry) (w);
+ }
+
+ /* disable the current texture */
+ disableTexture (w->screen, texture);
+
+ /* set the screens texture mode back to replace */
+ screenTexEnvMode (w->screen, GL_REPLACE);
+ }
+ /* pop previous matrix */
+ glPopMatrix ();
+ }
+ else
+ {
+ /* not negative */
+ UNWRAP (ns, w->screen, drawWindowTexture);
+ (*w->screen->drawWindowTexture) (w, texture, attrib, mask);
+ WRAP (ns, w->screen, drawWindowTexture, NEGDrawWindowTexture);
+ }
+}
+static Bool
+NEGDamageWindowRect (CompWindow * w, Bool initial, BoxPtr rect)
+{
+ int status;
+
+ NEG_SCREEN (w->screen);
+ NEG_WINDOW (w);
+
+ /* the window is initial when it is being mapped */
+ if (initial)
+ {
+ /* if the screen is negative, negate the new window */
+ if (ns->isNeg && !nw->isNeg)
+ NEGToggle (w);
+ }
+
+ UNWRAP (ns, w->screen, damageWindowRect);
+ status = (*w->screen->damageWindowRect) (w, initial, rect);
+ WRAP (ns, w->screen, damageWindowRect, NEGDamageWindowRect);
+
+ return status;
+}
+
+static Bool
+NEGPaintWindow (CompWindow * w, const WindowPaintAttrib * attrib,
+ Region region, unsigned int mask)
+{
+ int status;
+
+ NEG_SCREEN (w->screen);
+ NEG_WINDOW (w);
+
+ /* doing nothing */
+
+ UNWRAP (ns, w->screen, paintWindow);
+ status = (*w->screen->paintWindow) (w, attrib, region, mask);
+ WRAP (ns, w->screen, paintWindow, NEGPaintWindow);
+
+ return status;
+}
+static void
+NEGDisplayInitOptions (NEGDisplay * nd, Display * display)
+{
+ CompOption *o;
+
+ o = &nd->opt[NEG_DISPLAY_OPTION_WINDOW_TOGGLE];
+ o->name = "window_toggle";
+ o->shortDesc = N_("Toggle Negative");
+ o->longDesc = N_("Toggle Window Negative");
+ o->type = CompOptionTypeAction;
+ o->value.action.initiate = negToggle;
+ o->value.action.terminate = 0;
+ o->value.action.bell = FALSE;
+ o->value.action.edgeMask = 0;
+ o->value.action.type = CompBindingTypeKey;
+ o->value.action.state = CompActionStateInitKey;
+ o->value.action.state |= CompActionStateInitButton;
+ o->value.action.key.modifiers = NEG_TOGGLE_MODIFIERS_DEFAULT;
+ o->value.action.key.keycode =
+ XKeysymToKeycode (display, XStringToKeysym (NEG_TOGGLE_KEY_DEFAULT));
+
+ o = &nd->opt[NEG_DISPLAY_OPTION_SCREEN_TOGGLE];
+ o->name = "screen_toggle";
+ o->shortDesc = N_("Toggle Negative");
+ o->longDesc = N_("Toggle Screen Negative");
+ o->type = CompOptionTypeAction;
+ o->value.action.initiate = negToggleAll;
+ o->value.action.terminate = 0;
+ o->value.action.bell = FALSE;
+ o->value.action.edgeMask = 0;
+ o->value.action.type = CompBindingTypeKey;
+ o->value.action.state = CompActionStateInitKey;
+ o->value.action.state |= CompActionStateInitButton;
+ o->value.action.key.modifiers = NEG_TOGGLE_ALL_MODIFIERS_DEFAULT;
+ o->value.action.key.keycode =
+ XKeysymToKeycode (display,
+ XStringToKeysym (NEG_TOGGLE_ALL_KEY_DEFAULT));
+}
+
+static CompOption *
+NEGGetDisplayOptions (CompDisplay * display, int *count)
+{
+ if (display)
+ {
+ NEG_DISPLAY (display);
+
+ *count = NUM_OPTIONS (nd);
+ return nd->opt;
+ }
+ else
+ {
+ NEGDisplay * nd=malloc(sizeof(NEGDisplay));
+ Display * d = XOpenDisplay(getenv("DISPLAY"));
+ if(!d)exit(1);
+ NEGDisplayInitOptions(nd,d);
+ *count = NUM_OPTIONS(nd);
+ return nd->opt;
+ }
+}
+
+static Bool
+NEGSetDisplayOption (CompDisplay * display, char *name,
+ CompOptionValue * value)
+{
+ CompOption *o;
+ int index;
+
+ NEG_DISPLAY (display);
+
+ o = compFindOption (nd->opt, NUM_OPTIONS (nd), name, &index);
+ if (!o)
+ return FALSE;
+
+ switch (index)
+ {
+ case NEG_DISPLAY_OPTION_WINDOW_TOGGLE:
+ case NEG_DISPLAY_OPTION_SCREEN_TOGGLE:
+ if (setDisplayAction (display, o, value))
+ return TRUE;
+ break;
+
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+
+static Bool
+NEGInitDisplay (CompPlugin * p, CompDisplay * d)
+{
+ NEGDisplay *nd;
+
+ nd = malloc (sizeof (NEGDisplay));
+ if (!nd)
+ return FALSE;
+
+ nd->screenPrivateIndex = allocateScreenPrivateIndex (d);
+ if (nd->screenPrivateIndex < 0)
+ {
+ free (nd);
+ return FALSE;
+ }
+
+ /* initialize the display options */
+ NEGDisplayInitOptions (nd, d->display);
+
+ d->privates[displayPrivateIndex].ptr = nd;
+
+ return TRUE;
+}
+
+static void
+NEGFiniDisplay (CompPlugin * p, CompDisplay * d)
+{
+ NEG_DISPLAY (d);
+ freeScreenPrivateIndex (d, nd->screenPrivateIndex);
+ free (nd);
+}
+
+static Bool
+NEGInitScreen (CompPlugin * p, CompScreen * s)
+{
+ NEGScreen *ns;
+ NEG_DISPLAY (s->display);
+
+ ns = malloc (sizeof (NEGScreen));
+ if (!ns)
+ return FALSE;
+
+ ns->windowPrivateIndex = allocateWindowPrivateIndex (s);
+ if (ns->windowPrivateIndex < 0)
+ {
+ free (ns);
+ return FALSE;
+ }
+
+ /* initialize the screen variables
+ * you know what happens if you don't
+ */
+ ns->isNeg = FALSE;
+
+ /* add screen actions */
+ addScreenAction (s,
+ &nd->opt[NEG_DISPLAY_OPTION_WINDOW_TOGGLE].value.action);
+ addScreenAction (s,
+ &nd->opt[NEG_DISPLAY_OPTION_SCREEN_TOGGLE].value.action);
+
+ /* wrap overloaded functions */
+ WRAP (ns, s, drawWindowTexture, NEGDrawWindowTexture);
+ WRAP (ns, s, damageWindowRect, NEGDamageWindowRect);
+ WRAP (ns, s, paintWindow, NEGPaintWindow);
+
+ s->privates[nd->screenPrivateIndex].ptr = ns;
+
+ return TRUE;
+}
+
+
+static void
+NEGFiniScreen (CompPlugin * p, CompScreen * s)
+{
+ NEG_SCREEN (s);
+ freeWindowPrivateIndex (s, ns->windowPrivateIndex);
+ UNWRAP (ns, s, drawWindowTexture);
+ UNWRAP (ns, s, damageWindowRect);
+ UNWRAP (ns, s, paintWindow);
+ free (ns);
+}
+
+static Bool
+NEGInitWindow (CompPlugin * p, CompWindow * w)
+{
+ NEGWindow *nw;
+
+ NEG_SCREEN (w->screen);
+
+ nw = malloc (sizeof (NEGWindow));
+ if (!nw)
+ return FALSE;
+
+ nw->isNeg = FALSE;
+
+ w->privates[ns->windowPrivateIndex].ptr = nw;
+
+ return TRUE;
+}
+
+static void
+NEGFiniWindow (CompPlugin * p, CompWindow * w)
+{
+ NEG_WINDOW (w);
+ free (nw);
+}
+
+static Bool
+NEGInit (CompPlugin * p)
+{
+ displayPrivateIndex = allocateDisplayPrivateIndex ();
+ if (displayPrivateIndex < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+NEGFini (CompPlugin * p)
+{
+ if (displayPrivateIndex >= 0)
+ freeDisplayPrivateIndex (displayPrivateIndex);
+}
+
+CompPluginVTable NEGVTable = {
+ "neg",
+ N_("Negative"),
+ N_("Negative"),
+ NEGInit,
+ NEGFini,
+ NEGInitDisplay,
+ NEGFiniDisplay,
+ NEGInitScreen,
+ NEGFiniScreen,
+ NEGInitWindow,
+ NEGFiniWindow,
+ NEGGetDisplayOptions,
+ NEGSetDisplayOption,
+ 0, /* GetScreenOptions */
+ 0, /* SetScreenOption */
+ NULL,
+ 0,
+ BERYL_ABI_INFO
+};
+
+CompPluginVTable *
+getCompPluginInfo (void)
+{
+ return &NEGVTable;
+}