/* * 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 */ #include 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; }