summaryrefslogtreecommitdiff
path: root/plugins/keybindings/msd-keybindings-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/keybindings/msd-keybindings-manager.c')
-rw-r--r--plugins/keybindings/msd-keybindings-manager.c758
1 files changed, 0 insertions, 758 deletions
diff --git a/plugins/keybindings/msd-keybindings-manager.c b/plugins/keybindings/msd-keybindings-manager.c
deleted file mode 100644
index c1f876c..0000000
--- a/plugins/keybindings/msd-keybindings-manager.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 William Jon McCann <[email protected]>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <locale.h>
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-#include <X11/keysym.h>
-#include <mateconf/mateconf-client.h>
-
-#include "mate-settings-profile.h"
-#include "msd-keybindings-manager.h"
-
-#include "msd-keygrab.h"
-#include "eggaccelerators.h"
-
-#define MATECONF_BINDING_DIR "/desktop/mate/keybindings"
-#define ALLOWED_KEYS_KEY MATECONF_BINDING_DIR "/allowed_keys"
-
-#define MSD_KEYBINDINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MSD_TYPE_KEYBINDINGS_MANAGER, MsdKeybindingsManagerPrivate))
-
-typedef struct {
- char *binding_str;
- char *action;
- char *mateconf_key;
- Key key;
- Key previous_key;
-} Binding;
-
-struct MsdKeybindingsManagerPrivate
-{
- GSList *binding_list;
- GSList *allowed_keys;
- GSList *screens;
- guint notify;
-};
-
-static void msd_keybindings_manager_class_init (MsdKeybindingsManagerClass *klass);
-static void msd_keybindings_manager_init (MsdKeybindingsManager *keybindings_manager);
-static void msd_keybindings_manager_finalize (GObject *object);
-
-G_DEFINE_TYPE (MsdKeybindingsManager, msd_keybindings_manager, G_TYPE_OBJECT)
-
-static gpointer manager_object = NULL;
-
-static GSList *
-get_screens_list (void)
-{
- GdkDisplay *display = gdk_display_get_default();
- int n_screens;
- GSList *list = NULL;
- int i;
-
- n_screens = gdk_display_get_n_screens (display);
-
- if (n_screens == 1) {
- list = g_slist_append (list, gdk_screen_get_default ());
- } else {
- for (i = 0; i < n_screens; i++) {
- GdkScreen *screen;
-
- screen = gdk_display_get_screen (display, i);
- if (screen != NULL) {
- list = g_slist_prepend (list, screen);
- }
- }
- list = g_slist_reverse (list);
- }
-
- return list;
-}
-
-static char *
-entry_get_string (MateConfEntry *entry)
-{
- MateConfValue *value = mateconf_entry_get_value (entry);
-
- if (value == NULL || value->type != MATECONF_VALUE_STRING) {
- return NULL;
- }
-
- return g_strdup (mateconf_value_get_string (value));
-}
-
-static gboolean
-parse_binding (Binding *binding)
-{
- gboolean success;
-
- g_return_val_if_fail (binding != NULL, FALSE);
-
- binding->key.keysym = 0;
- binding->key.state = 0;
- g_free (binding->key.keycodes);
- binding->key.keycodes = NULL;
-
- if (binding->binding_str == NULL ||
- binding->binding_str[0] == '\0' ||
- strcmp (binding->binding_str, "Disabled") == 0) {
- return FALSE;
- }
-
- success = egg_accelerator_parse_virtual (binding->binding_str,
- &binding->key.keysym,
- &binding->key.keycodes,
- &binding->key.state);
-
- if (!success)
- g_warning (_("Key binding (%s) is invalid"), binding->mateconf_key);
-
- return success;
-}
-
-static gint
-compare_bindings (gconstpointer a,
- gconstpointer b)
-{
- Binding *key_a = (Binding *) a;
- char *key_b = (char *) b;
-
- return strcmp (key_b, key_a->mateconf_key);
-}
-
-static gboolean
-bindings_get_entry (MsdKeybindingsManager *manager,
- MateConfClient *client,
- const char *subdir)
-{
- Binding *new_binding;
- GSList *tmp_elem;
- GSList *list;
- GSList *li;
- char *mateconf_key;
- char *action = NULL;
- char *key = NULL;
-
- g_return_val_if_fail (subdir != NULL, FALSE);
-
- mateconf_key = g_path_get_basename (subdir);
-
- if (!mateconf_key) {
- return FALSE;
- }
-
- /* Get entries for this binding */
- list = mateconf_client_all_entries (client, subdir, NULL);
-
- for (li = list; li != NULL; li = li->next) {
- MateConfEntry *entry = li->data;
- char *key_name = g_path_get_basename (mateconf_entry_get_key (entry));
-
- if (key_name == NULL) {
- /* ignore entry */
- } else if (strcmp (key_name, "action") == 0) {
- action = entry_get_string (entry);
- } else if (strcmp (key_name, "binding") == 0) {
- key = entry_get_string (entry);
- }
-
- g_free (key_name);
- mateconf_entry_free (entry);
- }
-
- g_slist_free (list);
-
- if (!action || !key) {
- g_warning (_("Key binding (%s) is incomplete"), mateconf_key);
- g_free (mateconf_key);
- g_free (action);
- g_free (key);
- return FALSE;
- }
-
- tmp_elem = g_slist_find_custom (manager->priv->binding_list,
- mateconf_key,
- compare_bindings);
-
- if (!tmp_elem) {
- new_binding = g_new0 (Binding, 1);
- } else {
- new_binding = (Binding *) tmp_elem->data;
- g_free (new_binding->binding_str);
- g_free (new_binding->action);
- g_free (new_binding->mateconf_key);
-
- new_binding->previous_key.keysym = new_binding->key.keysym;
- new_binding->previous_key.state = new_binding->key.state;
- new_binding->previous_key.keycodes = new_binding->key.keycodes;
- new_binding->key.keycodes = NULL;
- }
-
- new_binding->binding_str = key;
- new_binding->action = action;
- new_binding->mateconf_key = mateconf_key;
-
- if (parse_binding (new_binding)) {
- if (!tmp_elem)
- manager->priv->binding_list = g_slist_prepend (manager->priv->binding_list, new_binding);
- } else {
- g_free (new_binding->binding_str);
- g_free (new_binding->action);
- g_free (new_binding->mateconf_key);
- g_free (new_binding->previous_key.keycodes);
- g_free (new_binding);
-
- if (tmp_elem)
- manager->priv->binding_list = g_slist_delete_link (manager->priv->binding_list, tmp_elem);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-same_keycode (const Key *key, const Key *other)
-{
- if (key->keycodes != NULL && other->keycodes != NULL) {
- guint *c;
-
- for (c = key->keycodes; *c; ++c) {
- if (key_uses_keycode (other, *c))
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static gboolean
-same_key (const Key *key, const Key *other)
-{
- if (key->state == other->state) {
- if (key->keycodes != NULL && other->keycodes != NULL) {
- guint *c1, *c2;
-
- for (c1 = key->keycodes, c2 = other->keycodes;
- *c1 || *c2; ++c1, ++c2) {
- if (*c1 != *c2)
- return FALSE;
- }
- } else if (key->keycodes != NULL || other->keycodes != NULL)
- return FALSE;
-
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-key_already_used (MsdKeybindingsManager *manager,
- Binding *binding)
-{
- GSList *li;
-
- for (li = manager->priv->binding_list; li != NULL; li = li->next) {
- Binding *tmp_binding = (Binding*) li->data;
-
- if (tmp_binding != binding &&
- same_keycode (&tmp_binding->key, &binding->key) &&
- tmp_binding->key.state == binding->key.state) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-binding_unregister_keys (MsdKeybindingsManager *manager)
-{
- GSList *li;
- gboolean need_flush = FALSE;
-
- gdk_error_trap_push ();
-
- for (li = manager->priv->binding_list; li != NULL; li = li->next) {
- Binding *binding = (Binding *) li->data;
-
- if (binding->key.keycodes) {
- need_flush = TRUE;
- grab_key_unsafe (&binding->key, FALSE, manager->priv->screens);
- }
- }
-
- if (need_flush)
- gdk_flush ();
- gdk_error_trap_pop ();
-}
-
-static void
-binding_register_keys (MsdKeybindingsManager *manager)
-{
- GSList *li;
- gboolean need_flush = FALSE;
-
- gdk_error_trap_push ();
-
- /* Now check for changes and grab new key if not already used */
- for (li = manager->priv->binding_list; li != NULL; li = li->next) {
- Binding *binding = (Binding *) li->data;
-
- if (manager->priv->allowed_keys != NULL &&
- !g_slist_find_custom (manager->priv->allowed_keys,
- binding->mateconf_key,
- (GCompareFunc) g_strcmp0)) {
- continue;
- }
-
- if (!same_key (&binding->previous_key, &binding->key)) {
- /* Ungrab key if it changed and not clashing with previously set binding */
- if (!key_already_used (manager, binding)) {
- gint i;
-
- need_flush = TRUE;
- if (binding->previous_key.keycodes) {
- grab_key_unsafe (&binding->previous_key, FALSE, manager->priv->screens);
- }
- grab_key_unsafe (&binding->key, TRUE, manager->priv->screens);
-
- binding->previous_key.keysym = binding->key.keysym;
- binding->previous_key.state = binding->key.state;
- g_free (binding->previous_key.keycodes);
- for (i = 0; binding->key.keycodes[i]; ++i);
- binding->previous_key.keycodes = g_new0 (guint, i);
- for (i = 0; binding->key.keycodes[i]; ++i)
- binding->previous_key.keycodes[i] = binding->key.keycodes[i];
- } else
- g_warning ("Key binding (%s) is already in use", binding->binding_str);
- }
- }
-
- if (need_flush)
- gdk_flush ();
- if (gdk_error_trap_pop ())
- g_warning ("Grab failed for some keys, another application may already have access the them.");
-}
-
-extern char **environ;
-
-static char *
-screen_exec_display_string (GdkScreen *screen)
-{
- GString *str;
- const char *old_display;
- char *p;
-
- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
- old_display = gdk_display_get_name (gdk_screen_get_display (screen));
-
- str = g_string_new ("DISPLAY=");
- g_string_append (str, old_display);
-
- p = strrchr (str->str, '.');
- if (p && p > strchr (str->str, ':')) {
- g_string_truncate (str, p - str->str);
- }
-
- g_string_append_printf (str, ".%d", gdk_screen_get_number (screen));
-
- return g_string_free (str, FALSE);
-}
-
-/**
- * get_exec_environment:
- *
- * Description: Modifies the current program environment to
- * ensure that $DISPLAY is set such that a launched application
- * inheriting this environment would appear on screen.
- *
- * Returns: a newly-allocated %NULL-terminated array of strings or
- * %NULL on error. Use g_strfreev() to free it.
- *
- * mainly ripped from egg_screen_exec_display_string in
- * mate-panel/egg-screen-exec.c
- **/
-static char **
-get_exec_environment (XEvent *xevent)
-{
- char **retval = NULL;
- int i;
- int display_index = -1;
- GdkScreen *screen = NULL;
- GdkWindow *window = gdk_xid_table_lookup (xevent->xkey.root);
-
- if (window) {
- screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
- }
-
- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
- for (i = 0; environ [i]; i++) {
- if (!strncmp (environ [i], "DISPLAY", 7)) {
- display_index = i;
- }
- }
-
- if (display_index == -1) {
- display_index = i++;
- }
-
- retval = g_new (char *, i + 1);
-
- for (i = 0; environ [i]; i++) {
- if (i == display_index) {
- retval [i] = screen_exec_display_string (screen);
- } else {
- retval [i] = g_strdup (environ [i]);
- }
- }
-
- retval [i] = NULL;
-
- return retval;
-}
-
-static GdkFilterReturn
-keybindings_filter (GdkXEvent *gdk_xevent,
- GdkEvent *event,
- MsdKeybindingsManager *manager)
-{
- XEvent *xevent = (XEvent *) gdk_xevent;
- GSList *li;
-
- if (xevent->type != KeyPress) {
- return GDK_FILTER_CONTINUE;
- }
-
- for (li = manager->priv->binding_list; li != NULL; li = li->next) {
- Binding *binding = (Binding *) li->data;
-
- if (match_key (&binding->key, xevent)) {
- GError *error = NULL;
- gboolean retval;
- gchar **argv = NULL;
- gchar **envp = NULL;
-
- g_return_val_if_fail (binding->action != NULL, GDK_FILTER_CONTINUE);
-
- if (!g_shell_parse_argv (binding->action,
- NULL, &argv,
- &error)) {
- return GDK_FILTER_CONTINUE;
- }
-
- envp = get_exec_environment (xevent);
-
- retval = g_spawn_async (NULL,
- argv,
- envp,
- G_SPAWN_SEARCH_PATH,
- NULL,
- NULL,
- NULL,
- &error);
- g_strfreev (argv);
- g_strfreev (envp);
-
- if (!retval) {
- GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CLOSE,
- _("Error while trying to run (%s)\n"\
- "which is linked to the key (%s)"),
- binding->action,
- binding->binding_str);
- g_signal_connect (dialog,
- "response",
- G_CALLBACK (gtk_widget_destroy),
- NULL);
- gtk_widget_show (dialog);
- }
- return GDK_FILTER_REMOVE;
- }
- }
- return GDK_FILTER_CONTINUE;
-}
-
-static void
-bindings_callback (MateConfClient *client,
- guint cnxn_id,
- MateConfEntry *entry,
- MsdKeybindingsManager *manager)
-{
- char** key_elems;
- char* binding_entry;
-
- if (strcmp (mateconf_entry_get_key (entry), ALLOWED_KEYS_KEY) == 0) {
- g_slist_foreach (manager->priv->allowed_keys, (GFunc)g_free, NULL);
- g_slist_free (manager->priv->allowed_keys);
- manager->priv->allowed_keys = mateconf_client_get_list (client,
- ALLOWED_KEYS_KEY,
- MATECONF_VALUE_STRING,
- NULL);
- }
- else {
- /* ensure we get binding dir not a sub component */
- key_elems = g_strsplit (mateconf_entry_get_key (entry), "/", 15);
- binding_entry = g_strdup_printf ("/%s/%s/%s/%s",
- key_elems[1],
- key_elems[2],
- key_elems[3],
- key_elems[4]);
- g_strfreev (key_elems);
-
- bindings_get_entry (manager, client, binding_entry);
- g_free (binding_entry);
- }
-
- binding_register_keys (manager);
-}
-
-static guint
-register_config_callback (MsdKeybindingsManager *manager,
- MateConfClient *client,
- const char *path,
- MateConfClientNotifyFunc func)
-{
- mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL);
- return mateconf_client_notify_add (client, path, func, manager, NULL, NULL);
-}
-
-gboolean
-msd_keybindings_manager_start (MsdKeybindingsManager *manager,
- GError **error)
-{
- MateConfClient *client;
- GSList *list;
- GSList *li;
- GdkDisplay *dpy;
- GdkScreen *screen;
- int screen_num;
- int i;
-
- g_debug ("Starting keybindings manager");
- mate_settings_profile_start (NULL);
-
- client = mateconf_client_get_default ();
-
- manager->priv->notify = register_config_callback (manager,
- client,
- MATECONF_BINDING_DIR,
- (MateConfClientNotifyFunc) bindings_callback);
-
- manager->priv->allowed_keys = mateconf_client_get_list (client,
- ALLOWED_KEYS_KEY,
- MATECONF_VALUE_STRING,
- NULL);
-
- dpy = gdk_display_get_default ();
- screen_num = gdk_display_get_n_screens (dpy);
-
- for (i = 0; i < screen_num; i++) {
- screen = gdk_display_get_screen (dpy, i);
- gdk_window_add_filter (gdk_screen_get_root_window (screen),
- (GdkFilterFunc) keybindings_filter,
- manager);
- }
-
- list = mateconf_client_all_dirs (client, MATECONF_BINDING_DIR, NULL);
- manager->priv->screens = get_screens_list ();
-
- for (li = list; li != NULL; li = li->next) {
- bindings_get_entry (manager, client, li->data);
- g_free (li->data);
- }
-
- g_slist_free (list);
- g_object_unref (client);
-
- binding_register_keys (manager);
-
- mate_settings_profile_end (NULL);
-
- return TRUE;
-}
-
-void
-msd_keybindings_manager_stop (MsdKeybindingsManager *manager)
-{
- MsdKeybindingsManagerPrivate *p = manager->priv;
- GSList *l;
-
- g_debug ("Stopping keybindings manager");
-
- if (p->notify != 0) {
- MateConfClient *client = mateconf_client_get_default ();
- mateconf_client_remove_dir (client, MATECONF_BINDING_DIR, NULL);
- mateconf_client_notify_remove (client, p->notify);
- g_object_unref (client);
- p->notify = 0;
- }
-
- for (l = p->screens; l; l = l->next) {
- GdkScreen *screen = l->data;
- gdk_window_remove_filter (gdk_screen_get_root_window (screen),
- (GdkFilterFunc) keybindings_filter,
- manager);
- }
-
- binding_unregister_keys (manager);
-
- g_slist_free (p->screens);
- p->screens = NULL;
-
- for (l = p->binding_list; l; l = l->next) {
- Binding *b = l->data;
- g_free (b->binding_str);
- g_free (b->action);
- g_free (b->mateconf_key);
- g_free (b->previous_key.keycodes);
- g_free (b->key.keycodes);
- g_free (b);
- }
- g_slist_free (p->binding_list);
- p->binding_list = NULL;
-}
-
-static void
-msd_keybindings_manager_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MsdKeybindingsManager *self;
-
- self = MSD_KEYBINDINGS_MANAGER (object);
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-msd_keybindings_manager_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MsdKeybindingsManager *self;
-
- self = MSD_KEYBINDINGS_MANAGER (object);
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GObject *
-msd_keybindings_manager_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
-{
- MsdKeybindingsManager *keybindings_manager;
- MsdKeybindingsManagerClass *klass;
-
- klass = MSD_KEYBINDINGS_MANAGER_CLASS (g_type_class_peek (MSD_TYPE_KEYBINDINGS_MANAGER));
-
- keybindings_manager = MSD_KEYBINDINGS_MANAGER (G_OBJECT_CLASS (msd_keybindings_manager_parent_class)->constructor (type,
- n_construct_properties,
- construct_properties));
-
- return G_OBJECT (keybindings_manager);
-}
-
-static void
-msd_keybindings_manager_dispose (GObject *object)
-{
- MsdKeybindingsManager *keybindings_manager;
-
- keybindings_manager = MSD_KEYBINDINGS_MANAGER (object);
-
- G_OBJECT_CLASS (msd_keybindings_manager_parent_class)->dispose (object);
-}
-
-static void
-msd_keybindings_manager_class_init (MsdKeybindingsManagerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = msd_keybindings_manager_get_property;
- object_class->set_property = msd_keybindings_manager_set_property;
- object_class->constructor = msd_keybindings_manager_constructor;
- object_class->dispose = msd_keybindings_manager_dispose;
- object_class->finalize = msd_keybindings_manager_finalize;
-
- g_type_class_add_private (klass, sizeof (MsdKeybindingsManagerPrivate));
-}
-
-static void
-msd_keybindings_manager_init (MsdKeybindingsManager *manager)
-{
- manager->priv = MSD_KEYBINDINGS_MANAGER_GET_PRIVATE (manager);
-
-}
-
-static void
-msd_keybindings_manager_finalize (GObject *object)
-{
- MsdKeybindingsManager *keybindings_manager;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (MSD_IS_KEYBINDINGS_MANAGER (object));
-
- keybindings_manager = MSD_KEYBINDINGS_MANAGER (object);
-
- g_return_if_fail (keybindings_manager->priv != NULL);
-
- G_OBJECT_CLASS (msd_keybindings_manager_parent_class)->finalize (object);
-}
-
-MsdKeybindingsManager *
-msd_keybindings_manager_new (void)
-{
- if (manager_object != NULL) {
- g_object_ref (manager_object);
- } else {
- manager_object = g_object_new (MSD_TYPE_KEYBINDINGS_MANAGER, NULL);
- g_object_add_weak_pointer (manager_object,
- (gpointer *) &manager_object);
- }
-
- return MSD_KEYBINDINGS_MANAGER (manager_object);
-}