diff options
Diffstat (limited to 'plugins/gnomecompat.c')
-rw-r--r-- | plugins/gnomecompat.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/plugins/gnomecompat.c b/plugins/gnomecompat.c new file mode 100644 index 0000000..5f4b8c2 --- /dev/null +++ b/plugins/gnomecompat.c @@ -0,0 +1,344 @@ +/* + * Copyright © 2009 Danny Baumann + * + * 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 + * Danny Baumann not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Danny Baumann makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * DANNY BAUMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL DENNIS KASPRZYK 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: Danny Baumann <dannybaumann@web.de> + */ + +#include <compiz-core.h> + +static CompMetadata gnomeMetadata; + +static int displayPrivateIndex; + +#define GNOME_DISPLAY_OPTION_MAIN_MENU_KEY 0 +#define GNOME_DISPLAY_OPTION_RUN_DIALOG_KEY 1 +#define GNOME_DISPLAY_OPTION_SCREENSHOT_CMD 2 +#define GNOME_DISPLAY_OPTION_RUN_SCREENSHOT_KEY 3 +#define GNOME_DISPLAY_OPTION_WINDOW_SCREENSHOT_CMD 4 +#define GNOME_DISPLAY_OPTION_RUN_WINDOW_SCREENSHOT_KEY 5 +#define GNOME_DISPLAY_OPTION_TERMINAL_CMD 6 +#define GNOME_DISPLAY_OPTION_RUN_TERMINAL_KEY 7 +#define GNOME_DISPLAY_OPTION_NUM 8 + +typedef struct _GnomeDisplay { + CompOption opt[GNOME_DISPLAY_OPTION_NUM]; + + Atom panelActionAtom; + Atom panelMainMenuAtom; + Atom panelRunDialogAtom; +} GnomeDisplay; + +#define GET_GNOME_DISPLAY(d) \ + ((GnomeDisplay *) (d)->base.privates[displayPrivateIndex].ptr) +#define GNOME_DISPLAY(d) \ + GnomeDisplay *gd = GET_GNOME_DISPLAY (d) + +#define NUM_OPTIONS(d) (sizeof ((d)->opt) / sizeof (CompOption)) + +static Bool +runDispatch (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) + { + GNOME_DISPLAY (d); + + runCommand (s, gd->opt[action->priv.val].value.s); + } + + return TRUE; +} + +static void +panelAction (CompDisplay *d, + CompOption *option, + int nOption, + Atom actionAtom) +{ + Window xid; + CompScreen *s; + XEvent event; + Time time; + + GNOME_DISPLAY (d); + + xid = getIntOptionNamed (option, nOption, "root", 0); + s = findScreenAtDisplay (d, xid); + + if (!s) + return; + + time = getIntOptionNamed (option, nOption, "time", CurrentTime); + + /* we need to ungrab the keyboard here, otherwise the panel main + menu won't popup as it wants to grab the keyboard itself */ + XUngrabKeyboard (d->display, time); + + event.type = ClientMessage; + event.xclient.window = s->root; + event.xclient.message_type = gd->panelActionAtom; + event.xclient.format = 32; + event.xclient.data.l[0] = actionAtom; + event.xclient.data.l[1] = time; + event.xclient.data.l[2] = 0; + event.xclient.data.l[3] = 0; + event.xclient.data.l[4] = 0; + + XSendEvent (d->display, s->root, FALSE, StructureNotifyMask, &event); +} + +static Bool +showMainMenu (CompDisplay *d, + CompAction *action, + CompActionState state, + CompOption *option, + int nOption) +{ + GNOME_DISPLAY (d); + + panelAction (d, option, nOption, gd->panelMainMenuAtom); + + return TRUE; +} + +static Bool +showRunDialog (CompDisplay *d, + CompAction *action, + CompActionState state, + CompOption *option, + int nOption) +{ + GNOME_DISPLAY (d); + + panelAction (d, option, nOption, gd->panelRunDialogAtom); + + return TRUE; +} +static const CompMetadataOptionInfo gnomeDisplayOptionInfo[] = { + { "main_menu_key", "key", 0, showMainMenu, 0 }, + { "run_key", "key", 0, showRunDialog, 0 }, + { "command_screenshot", "string", 0, 0, 0 }, + { "run_command_screenshot_key", "key", 0, runDispatch, 0 }, + { "command_window_screenshot", "string", 0, 0, 0 }, + { "run_command_window_screenshot_key", "key", 0, runDispatch, 0 }, + { "command_terminal", "string", 0, 0, 0 }, + { "run_command_terminal_key", "key", 0, runDispatch, 0 } +}; + +static CompBool +gnomeInitDisplay (CompPlugin *p, + CompDisplay *d) +{ + GnomeDisplay *gd; + int opt, index; + + if (!checkPluginABI ("core", CORE_ABIVERSION)) + return FALSE; + + gd = malloc (sizeof (GnomeDisplay)); + if (!gd) + return FALSE; + + if (!compInitDisplayOptionsFromMetadata (d, + &gnomeMetadata, + gnomeDisplayOptionInfo, + gd->opt, + GNOME_DISPLAY_OPTION_NUM)) + { + free (gd); + return FALSE; + } + + opt = GNOME_DISPLAY_OPTION_RUN_SCREENSHOT_KEY; + gd->opt[opt].value.action.priv.val = GNOME_DISPLAY_OPTION_SCREENSHOT_CMD; + + opt = GNOME_DISPLAY_OPTION_RUN_WINDOW_SCREENSHOT_KEY; + index = GNOME_DISPLAY_OPTION_WINDOW_SCREENSHOT_CMD; + gd->opt[opt].value.action.priv.val = index; + + opt = GNOME_DISPLAY_OPTION_RUN_TERMINAL_KEY; + gd->opt[opt].value.action.priv.val = GNOME_DISPLAY_OPTION_TERMINAL_CMD; + + gd->panelActionAtom = + XInternAtom (d->display, "_GNOME_PANEL_ACTION", FALSE); + gd->panelMainMenuAtom = + XInternAtom (d->display, "_GNOME_PANEL_ACTION_MAIN_MENU", FALSE); + gd->panelRunDialogAtom = + XInternAtom (d->display, "_GNOME_PANEL_ACTION_RUN_DIALOG", FALSE); + + d->base.privates[displayPrivateIndex].ptr = gd; + + return TRUE; +} + +static void +gnomeFiniDisplay (CompPlugin *p, + CompDisplay *d) +{ + GNOME_DISPLAY (d); + + compFiniDisplayOptions (d, gd->opt, GNOME_DISPLAY_OPTION_NUM); + + free (gd); +} + +static CompOption * +gnomeGetDisplayOptions (CompPlugin *p, + CompDisplay *d, + int *count) +{ + GNOME_DISPLAY (d); + + *count = NUM_OPTIONS (gd); + return gd->opt; +} + +static CompBool +gnomeSetDisplayOption (CompPlugin *p, + CompDisplay *d, + const char *name, + CompOptionValue *value) +{ + CompOption *o; + + GNOME_DISPLAY (d); + + o = compFindOption (gd->opt, NUM_OPTIONS (gd), name, NULL); + if (!o) + return FALSE; + + return compSetDisplayOption (d, o, value); +} + +static CompBool +gnomeInitObject (CompPlugin *p, + CompObject *o) +{ + static InitPluginObjectProc dispTab[] = { + (InitPluginObjectProc) 0, /* InitCore */ + (InitPluginObjectProc) gnomeInitDisplay + }; + + RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o)); +} + +static void +gnomeFiniObject (CompPlugin *p, + CompObject *o) +{ + static FiniPluginObjectProc dispTab[] = { + (FiniPluginObjectProc) 0, /* FiniCore */ + (FiniPluginObjectProc) gnomeFiniDisplay + }; + + DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o)); +} + +static CompOption * +gnomeGetObjectOptions (CompPlugin *p, + CompObject *o, + int *count) +{ + static GetPluginObjectOptionsProc dispTab[] = { + (GetPluginObjectOptionsProc) 0, /* GetCoreOptions */ + (GetPluginObjectOptionsProc) gnomeGetDisplayOptions + }; + + *count = 0; + RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), + (void *) count, (p, o, count)); +} + +static CompBool +gnomeSetObjectOption (CompPlugin *p, + CompObject *o, + const char *name, + CompOptionValue *value) +{ + static SetPluginObjectOptionProc dispTab[] = { + (SetPluginObjectOptionProc) 0, /* SetCoreOption */ + (SetPluginObjectOptionProc) gnomeSetDisplayOption, + }; + + RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), FALSE, + (p, o, name, value)); +} + +static Bool +gnomeInit (CompPlugin *p) +{ + if (!compInitPluginMetadataFromInfo (&gnomeMetadata, + p->vTable->name, + gnomeDisplayOptionInfo, + GNOME_DISPLAY_OPTION_NUM, 0, 0)) + return FALSE; + + displayPrivateIndex = allocateDisplayPrivateIndex (); + if (displayPrivateIndex < 0) + { + compFiniMetadata (&gnomeMetadata); + return FALSE; + } + + compAddMetadataFromFile (&gnomeMetadata, p->vTable->name); + + return TRUE; +} + +static void +gnomeFini (CompPlugin *p) +{ + freeDisplayPrivateIndex (displayPrivateIndex); + compFiniMetadata (&gnomeMetadata); +} + +static CompMetadata * +gnomeGetMetadata (CompPlugin *p) +{ + return &gnomeMetadata; +} + +static CompPluginVTable gnomeVTable = { + "gnomecompat", + gnomeGetMetadata, + gnomeInit, + gnomeFini, + gnomeInitObject, + gnomeFiniObject, + gnomeGetObjectOptions, + gnomeSetObjectOption +}; + +CompPluginVTable * +getCompPluginInfo20070830 (void) +{ + return &gnomeVTable; +} |