diff options
author | haxar <[email protected]> | 2012-02-21 20:14:01 -0800 |
---|---|---|
committer | haxar <[email protected]> | 2012-02-21 20:14:01 -0800 |
commit | e46b4adef5c6c6805b3ca6dbfbe99a4299252514 (patch) | |
tree | f95660c9462b74c2775355c29df79267fc30501b /plugins/mouse/gsd-mouse-manager.c | |
parent | ddaceb232c8b537a7d29a9708928d3a3671b98e5 (diff) | |
download | mate-settings-daemon-e46b4adef5c6c6805b3ca6dbfbe99a4299252514.tar.bz2 mate-settings-daemon-e46b4adef5c6c6805b3ca6dbfbe99a4299252514.tar.xz |
gsd to msd complete rename patch by NiceandGently; file rename commit
Diffstat (limited to 'plugins/mouse/gsd-mouse-manager.c')
-rw-r--r-- | plugins/mouse/gsd-mouse-manager.c | 1124 |
1 files changed, 0 insertions, 1124 deletions
diff --git a/plugins/mouse/gsd-mouse-manager.c b/plugins/mouse/gsd-mouse-manager.c deleted file mode 100644 index d7cb8e4..0000000 --- a/plugins/mouse/gsd-mouse-manager.c +++ /dev/null @@ -1,1124 +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 <math.h> - -#include <locale.h> - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <gdk/gdk.h> -#include <gdk/gdkx.h> -#include <gdk/gdkkeysyms.h> -#include <X11/keysym.h> -#include <X11/Xatom.h> - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -#include <X11/extensions/XInput.h> -#include <X11/extensions/XIproto.h> -#endif -#include <mateconf/mateconf.h> -#include <mateconf/mateconf-client.h> - -#include "mate-settings-profile.h" -#include "msd-mouse-manager.h" - -#define MSD_MOUSE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MSD_TYPE_MOUSE_MANAGER, MsdMouseManagerPrivate)) - -#define MATECONF_MOUSE_DIR "/desktop/mate/peripherals/mouse" -#define MATECONF_MOUSE_A11Y_DIR "/desktop/mate/accessibility/mouse" -#define MATECONF_TOUCHPAD_DIR "/desktop/mate/peripherals/touchpad" - -#define KEY_LEFT_HANDED MATECONF_MOUSE_DIR "/left_handed" -#define KEY_MOTION_ACCELERATION MATECONF_MOUSE_DIR "/motion_acceleration" -#define KEY_MOTION_THRESHOLD MATECONF_MOUSE_DIR "/motion_threshold" -#define KEY_LOCATE_POINTER MATECONF_MOUSE_DIR "/locate_pointer" -#define KEY_DWELL_ENABLE MATECONF_MOUSE_A11Y_DIR "/dwell_enable" -#define KEY_DELAY_ENABLE MATECONF_MOUSE_A11Y_DIR "/delay_enable" -#define KEY_TOUCHPAD_DISABLE_W_TYPING MATECONF_TOUCHPAD_DIR "/disable_while_typing" -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -#define KEY_TAP_TO_CLICK MATECONF_TOUCHPAD_DIR "/tap_to_click" -#define KEY_SCROLL_METHOD MATECONF_TOUCHPAD_DIR "/scroll_method" -#define KEY_PAD_HORIZ_SCROLL MATECONF_TOUCHPAD_DIR "/horiz_scroll_enabled" -#define KEY_TOUCHPAD_ENABLED MATECONF_TOUCHPAD_DIR "/touchpad_enabled" -#endif - -struct MsdMouseManagerPrivate -{ - guint notify; - guint notify_a11y; - guint notify_touchpad; - - gboolean mousetweaks_daemon_running; - gboolean syndaemon_spawned; - GPid syndaemon_pid; - gboolean locate_pointer_spawned; - GPid locate_pointer_pid; -}; - -static void msd_mouse_manager_class_init (MsdMouseManagerClass *klass); -static void msd_mouse_manager_init (MsdMouseManager *mouse_manager); -static void msd_mouse_manager_finalize (GObject *object); -static void set_mouse_settings (MsdMouseManager *manager); -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -static int set_tap_to_click (gboolean state, gboolean left_handed); -static XDevice* device_is_touchpad (XDeviceInfo deviceinfo); -#endif - -G_DEFINE_TYPE (MsdMouseManager, msd_mouse_manager, G_TYPE_OBJECT) - -static gpointer manager_object = NULL; - -static void -msd_mouse_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MsdMouseManager *self; - - self = MSD_MOUSE_MANAGER (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -msd_mouse_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MsdMouseManager *self; - - self = MSD_MOUSE_MANAGER (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -msd_mouse_manager_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - MsdMouseManager *mouse_manager; - MsdMouseManagerClass *klass; - - klass = MSD_MOUSE_MANAGER_CLASS (g_type_class_peek (MSD_TYPE_MOUSE_MANAGER)); - - mouse_manager = MSD_MOUSE_MANAGER (G_OBJECT_CLASS (msd_mouse_manager_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - return G_OBJECT (mouse_manager); -} - -static void -msd_mouse_manager_dispose (GObject *object) -{ - MsdMouseManager *mouse_manager; - - mouse_manager = MSD_MOUSE_MANAGER (object); - - G_OBJECT_CLASS (msd_mouse_manager_parent_class)->dispose (object); -} - -static void -msd_mouse_manager_class_init (MsdMouseManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = msd_mouse_manager_get_property; - object_class->set_property = msd_mouse_manager_set_property; - object_class->constructor = msd_mouse_manager_constructor; - object_class->dispose = msd_mouse_manager_dispose; - object_class->finalize = msd_mouse_manager_finalize; - - g_type_class_add_private (klass, sizeof (MsdMouseManagerPrivate)); -} - - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -static gboolean -supports_xinput_devices (void) -{ - gint op_code, event, error; - - return XQueryExtension (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - "XInputExtension", - &op_code, - &event, - &error); -} -#endif - -static void -configure_button_layout (guchar *buttons, - gint n_buttons, - gboolean left_handed) -{ - const gint left_button = 1; - gint right_button; - gint i; - - /* if the button is higher than 2 (3rd button) then it's - * probably one direction of a scroll wheel or something else - * uninteresting - */ - right_button = MIN (n_buttons, 3); - - /* If we change things we need to make sure we only swap buttons. - * If we end up with multiple physical buttons assigned to the same - * logical button the server will complain. This code assumes physical - * button 0 is the physical left mouse button, and that the physical - * button other than 0 currently assigned left_button or right_button - * is the physical right mouse button. - */ - - /* check if the current mapping satisfies the above assumptions */ - if (buttons[left_button - 1] != left_button && - buttons[left_button - 1] != right_button) - /* The current mapping is weird. Swapping buttons is probably not a - * good idea. - */ - return; - - /* check if we are left_handed and currently not swapped */ - if (left_handed && buttons[left_button - 1] == left_button) { - /* find the right button */ - for (i = 0; i < n_buttons; i++) { - if (buttons[i] == right_button) { - buttons[i] = left_button; - break; - } - } - /* swap the buttons */ - buttons[left_button - 1] = right_button; - } - /* check if we are not left_handed but are swapped */ - else if (!left_handed && buttons[left_button - 1] == right_button) { - /* find the right button */ - for (i = 0; i < n_buttons; i++) { - if (buttons[i] == left_button) { - buttons[i] = right_button; - break; - } - } - /* swap the buttons */ - buttons[left_button - 1] = left_button; - } -} - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -static gboolean -xinput_device_has_buttons (XDeviceInfo *device_info) -{ - int i; - XAnyClassInfo *class_info; - - class_info = device_info->inputclassinfo; - for (i = 0; i < device_info->num_classes; i++) { - if (class_info->class == ButtonClass) { - XButtonInfo *button_info; - - button_info = (XButtonInfo *) class_info; - if (button_info->num_buttons > 0) - return TRUE; - } - - class_info = (XAnyClassInfo *) (((guchar *) class_info) + - class_info->length); - } - return FALSE; -} - -static gboolean -touchpad_has_single_button (XDevice *device) -{ - Atom type, prop; - int format; - unsigned long nitems, bytes_after; - unsigned char *data; - gboolean is_single_button = FALSE; - int rc; - - prop = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Capabilities", False); - if (!prop) - return FALSE; - - gdk_error_trap_push (); - rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, prop, 0, 1, False, - XA_INTEGER, &type, &format, &nitems, - &bytes_after, &data); - if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 3) - is_single_button = (data[0] == 1 && data[1] == 0 && data[2] == 0); - - if (rc == Success) - XFree (data); - - gdk_error_trap_pop (); - - return is_single_button; -} - - -static void -set_xinput_devices_left_handed (gboolean left_handed) -{ - XDeviceInfo *device_info; - gint n_devices; - guchar *buttons; - gsize buttons_capacity = 16; - gint n_buttons; - gint i; - - device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &n_devices); - - if (n_devices > 0) - buttons = g_new (guchar, buttons_capacity); - else - buttons = NULL; - - for (i = 0; i < n_devices; i++) { - XDevice *device = NULL; - - if ((device_info[i].use == IsXPointer) || - (device_info[i].use == IsXKeyboard) || - (!xinput_device_has_buttons (&device_info[i]))) - continue; - - /* If the device is a touchpad, swap tap buttons - * around too, otherwise a tap would be a right-click */ - device = device_is_touchpad (device_info[i]); - if (device != NULL) { - MateConfClient *client = mateconf_client_get_default (); - gboolean tap = mateconf_client_get_bool (client, KEY_TAP_TO_CLICK, NULL); - gboolean single_button = touchpad_has_single_button (device); - - if (tap && !single_button) - set_tap_to_click (tap, left_handed); - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - g_object_unref (client); - - if (single_button) - continue; - } - - gdk_error_trap_push (); - - device = XOpenDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device_info[i].id); - - if ((gdk_error_trap_pop () != 0) || - (device == NULL)) - continue; - - n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - buttons, - buttons_capacity); - - while (n_buttons > buttons_capacity) { - buttons_capacity = n_buttons; - buttons = (guchar *) g_realloc (buttons, - buttons_capacity * sizeof (guchar)); - - n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - buttons, - buttons_capacity); - } - - configure_button_layout (buttons, n_buttons, left_handed); - - XSetDeviceButtonMapping (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, buttons, n_buttons); - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - } - g_free (buttons); - - if (device_info != NULL) - XFreeDeviceList (device_info); -} - -static GdkFilterReturn -devicepresence_filter (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) -{ - XEvent *xev = (XEvent *) xevent; - XEventClass class_presence; - int xi_presence; - - DevicePresence (gdk_x11_get_default_xdisplay (), xi_presence, class_presence); - - if (xev->type == xi_presence) - { - XDevicePresenceNotifyEvent *dpn = (XDevicePresenceNotifyEvent *) xev; - if (dpn->devchange == DeviceEnabled) - set_mouse_settings ((MsdMouseManager *) data); - } - return GDK_FILTER_CONTINUE; -} - -static void -set_devicepresence_handler (MsdMouseManager *manager) -{ - Display *display; - XEventClass class_presence; - int xi_presence; - - if (!supports_xinput_devices ()) - return; - - display = gdk_x11_get_default_xdisplay (); - - gdk_error_trap_push (); - DevicePresence (display, xi_presence, class_presence); - XSelectExtensionEvent (display, - RootWindow (display, DefaultScreen (display)), - &class_presence, 1); - - gdk_flush (); - if (!gdk_error_trap_pop ()) - gdk_window_add_filter (NULL, devicepresence_filter, manager); -} -#endif - -static void -set_left_handed (MsdMouseManager *manager, - gboolean left_handed) -{ - guchar *buttons ; - gsize buttons_capacity = 16; - gint n_buttons, i; - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - if (supports_xinput_devices ()) { - /* When XInput support is available, never set the - * button ordering on the core pointer as that would - * revert the changes we make on the devices themselves */ - set_xinput_devices_left_handed (left_handed); - return; - } -#endif - - buttons = g_new (guchar, buttons_capacity); - n_buttons = XGetPointerMapping (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - buttons, - (gint) buttons_capacity); - while (n_buttons > buttons_capacity) { - buttons_capacity = n_buttons; - buttons = (guchar *) g_realloc (buttons, - buttons_capacity * sizeof (guchar)); - - n_buttons = XGetPointerMapping (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - buttons, - (gint) buttons_capacity); - } - - configure_button_layout (buttons, n_buttons, left_handed); - - /* X refuses to change the mapping while buttons are engaged, - * so if this is the case we'll retry a few times - */ - for (i = 0; - i < 20 && XSetPointerMapping (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), buttons, n_buttons) == MappingBusy; - ++i) { - g_usleep (300); - } - - g_free (buttons); -} - -static void -set_motion_acceleration (MsdMouseManager *manager, - gfloat motion_acceleration) -{ - gint numerator, denominator; - - if (motion_acceleration >= 1.0) { - /* we want to get the acceleration, with a resolution of 0.5 - */ - if ((motion_acceleration - floor (motion_acceleration)) < 0.25) { - numerator = floor (motion_acceleration); - denominator = 1; - } else if ((motion_acceleration - floor (motion_acceleration)) < 0.5) { - numerator = ceil (2.0 * motion_acceleration); - denominator = 2; - } else if ((motion_acceleration - floor (motion_acceleration)) < 0.75) { - numerator = floor (2.0 *motion_acceleration); - denominator = 2; - } else { - numerator = ceil (motion_acceleration); - denominator = 1; - } - } else if (motion_acceleration < 1.0 && motion_acceleration > 0) { - /* This we do to 1/10ths */ - numerator = floor (motion_acceleration * 10) + 1; - denominator= 10; - } else { - numerator = -1; - denominator = -1; - } - - XChangePointerControl (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), True, False, - numerator, denominator, - 0); -} - -static void -set_motion_threshold (MsdMouseManager *manager, - int motion_threshold) -{ - XChangePointerControl (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False, True, - 0, 0, motion_threshold); -} - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -static XDevice* -device_is_touchpad (XDeviceInfo deviceinfo) -{ - XDevice *device; - Atom realtype, prop; - int realformat; - unsigned long nitems, bytes_after; - unsigned char *data; - - if (deviceinfo.type != XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XI_TOUCHPAD, False)) - return NULL; - - prop = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Off", False); - if (!prop) - return NULL; - - gdk_error_trap_push (); - device = XOpenDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), deviceinfo.id); - if (gdk_error_trap_pop () || (device == NULL)) - return NULL; - - gdk_error_trap_push (); - if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, prop, 0, 1, False, - XA_INTEGER, &realtype, &realformat, &nitems, - &bytes_after, &data) == Success) && (realtype != None)) { - gdk_error_trap_pop (); - XFree (data); - return device; - } - gdk_error_trap_pop (); - - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - return NULL; -} -#endif - -static int -set_disable_w_typing (MsdMouseManager *manager, gboolean state) -{ - - if (state) { - GError *error = NULL; - char *args[5]; - - if (manager->priv->syndaemon_spawned) - return 0; - - args[0] = "syndaemon"; - args[1] = "-i"; - args[2] = "0.5"; - args[3] = "-k"; - args[4] = NULL; - - if (!g_find_program_in_path (args[0])) - return 0; - - g_spawn_async (g_get_home_dir (), args, NULL, - G_SPAWN_SEARCH_PATH, NULL, NULL, - &manager->priv->syndaemon_pid, &error); - - manager->priv->syndaemon_spawned = (error == NULL); - - if (error) { - MateConfClient *client; - client = mateconf_client_get_default (); - mateconf_client_set_bool (client, KEY_TOUCHPAD_DISABLE_W_TYPING, FALSE, NULL); - g_object_unref (client); - g_error_free (error); - } - - } else if (manager->priv->syndaemon_spawned) - { - kill (manager->priv->syndaemon_pid, SIGHUP); - g_spawn_close_pid (manager->priv->syndaemon_pid); - manager->priv->syndaemon_spawned = FALSE; - } - - return 0; -} - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H -static int -set_tap_to_click (gboolean state, gboolean left_handed) -{ - int numdevices, i, format, rc; - unsigned long nitems, bytes_after; - XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &numdevices); - XDevice * device; - unsigned char* data; - Atom prop, type; - - if (devicelist == NULL) - return 0; - - prop = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Tap Action", False); - - if (!prop) - return 0; - - for (i = 0; i < numdevices; i++) { - if ((device = device_is_touchpad (devicelist[i]))) { - gdk_error_trap_push (); - rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, prop, 0, 2, - False, XA_INTEGER, &type, &format, &nitems, - &bytes_after, &data); - - if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 7) - { - /* Set RLM mapping for 1/2/3 fingers*/ - data[4] = (state) ? ((left_handed) ? 3 : 1) : 0; - data[5] = (state) ? ((left_handed) ? 1 : 3) : 0; - data[6] = (state) ? 2 : 0; - XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, prop, XA_INTEGER, 8, - PropModeReplace, data, nitems); - } - - if (rc == Success) - XFree (data); - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - if (gdk_error_trap_pop ()) { - g_warning ("Error in setting tap to click on \"%s\"", devicelist[i].name); - continue; - } - } - } - - XFreeDeviceList (devicelist); - return 0; -} - -static int -set_horiz_scroll (gboolean state) -{ - int numdevices, i, rc; - XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &numdevices); - XDevice *device; - Atom act_type, prop_edge, prop_twofinger; - int act_format; - unsigned long nitems, bytes_after; - unsigned char *data; - - if (devicelist == NULL) - return 0; - - prop_edge = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Edge Scrolling", False); - prop_twofinger = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Two-Finger Scrolling", False); - - if (!prop_edge || !prop_twofinger) - return 0; - - for (i = 0; i < numdevices; i++) { - if ((device = device_is_touchpad (devicelist[i]))) { - gdk_error_trap_push (); - rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_edge, 0, 1, False, - XA_INTEGER, &act_type, &act_format, &nitems, - &bytes_after, &data); - if (rc == Success && act_type == XA_INTEGER && - act_format == 8 && nitems >= 2) { - data[1] = (state && data[0]); - XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_edge, XA_INTEGER, 8, - PropModeReplace, data, nitems); - } - - XFree (data); - - rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_twofinger, 0, 1, False, - XA_INTEGER, &act_type, &act_format, &nitems, - &bytes_after, &data); - if (rc == Success && act_type == XA_INTEGER && - act_format == 8 && nitems >= 2) { - data[1] = (state && data[0]); - XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_twofinger, XA_INTEGER, 8, - PropModeReplace, data, nitems); - } - - XFree (data); - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - if (gdk_error_trap_pop ()) { - g_warning ("Error in setting horiz scroll on \"%s\"", devicelist[i].name); - continue; - } - } - } - - XFreeDeviceList (devicelist); - return 0; -} - - -/** - * Scroll methods are: 0 - disabled, 1 - edge scrolling, 2 - twofinger - * scrolling - */ -static int -set_edge_scroll (int method) -{ - int numdevices, i, rc; - XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &numdevices); - XDevice *device; - Atom act_type, prop_edge, prop_twofinger; - int act_format; - unsigned long nitems, bytes_after; - unsigned char *data; - - if (devicelist == NULL) - return 0; - - prop_edge = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Edge Scrolling", False); - prop_twofinger = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Synaptics Two-Finger Scrolling", False); - - if (!prop_edge || !prop_twofinger) - return 0; - - for (i = 0; i < numdevices; i++) { - if ((device = device_is_touchpad (devicelist[i]))) { - gdk_error_trap_push (); - rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_edge, 0, 1, False, - XA_INTEGER, &act_type, &act_format, &nitems, - &bytes_after, &data); - if (rc == Success && act_type == XA_INTEGER && - act_format == 8 && nitems >= 2) { - data[0] = (method == 1) ? 1 : 0; - XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_edge, XA_INTEGER, 8, - PropModeReplace, data, nitems); - } - - XFree (data); - - rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_twofinger, 0, 1, False, - XA_INTEGER, &act_type, &act_format, &nitems, - &bytes_after, &data); - if (rc == Success && act_type == XA_INTEGER && - act_format == 8 && nitems >= 2) { - data[0] = (method == 2) ? 1 : 0; - XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_twofinger, XA_INTEGER, 8, - PropModeReplace, data, nitems); - } - - XFree (data); - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - if (gdk_error_trap_pop ()) { - g_warning ("Error in setting edge scroll on \"%s\"", devicelist[i].name); - continue; - } - } - } - - XFreeDeviceList (devicelist); - return 0; -} - -static int -set_touchpad_enabled (gboolean state) -{ - int numdevices, i; - XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &numdevices); - XDevice *device; - Atom prop_enabled; - - if (devicelist == NULL) - return 0; - - prop_enabled = XInternAtom (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "Device Enabled", False); - - if (!prop_enabled) - return 0; - - for (i = 0; i < numdevices; i++) { - if ((device = device_is_touchpad (devicelist[i]))) { - unsigned char data = state; - gdk_error_trap_push (); - XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device, - prop_enabled, XA_INTEGER, 8, - PropModeReplace, &data, 1); - XCloseDevice (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), device); - gdk_flush (); - if (gdk_error_trap_pop ()) { - g_warning ("Error %s device \"%s\"", - (state) ? "enabling" : "disabling", - devicelist[i].name); - continue; - } - } - } - - XFreeDeviceList (devicelist); - return 0; -} -#endif - -static void -set_locate_pointer (MsdMouseManager *manager, - gboolean state) -{ - if (state) { - GError *error = NULL; - char *args[2]; - - if (manager->priv->locate_pointer_spawned) - return; - - args[0] = LIBEXECDIR "/msd-locate-pointer"; - args[1] = NULL; - - g_spawn_async (NULL, args, NULL, - 0, NULL, NULL, - &manager->priv->locate_pointer_pid, &error); - - manager->priv->locate_pointer_spawned = (error == NULL); - - if (error) { - MateConfClient *client; - client = mateconf_client_get_default (); - mateconf_client_set_bool (client, KEY_LOCATE_POINTER, FALSE, NULL); - g_object_unref (client); - g_error_free (error); - } - - } - else if (manager->priv->locate_pointer_spawned) { - kill (manager->priv->locate_pointer_pid, SIGHUP); - g_spawn_close_pid (manager->priv->locate_pointer_pid); - manager->priv->locate_pointer_spawned = FALSE; - } -} - -static void -set_mousetweaks_daemon (MsdMouseManager *manager, - gboolean dwell_enable, - gboolean delay_enable) -{ - GError *error = NULL; - gchar *comm; - gboolean run_daemon = dwell_enable || delay_enable; - - if (run_daemon || manager->priv->mousetweaks_daemon_running) - comm = g_strdup_printf ("mousetweaks %s", - run_daemon ? "" : "-s"); - else - return; - - if (run_daemon) - manager->priv->mousetweaks_daemon_running = TRUE; - - - if (! g_spawn_command_line_async (comm, &error)) { - if (error->code == G_SPAWN_ERROR_NOENT && - (dwell_enable || delay_enable)) { - GtkWidget *dialog; - MateConfClient *client; - - client = mateconf_client_get_default (); - if (dwell_enable) - mateconf_client_set_bool (client, - KEY_DWELL_ENABLE, - FALSE, NULL); - else if (delay_enable) - mateconf_client_set_bool (client, - KEY_DELAY_ENABLE, - FALSE, NULL); - g_object_unref (client); - - dialog = gtk_message_dialog_new (NULL, 0, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - _("Could not enable mouse accessibility features")); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("Mouse accessibility requires Mousetweaks " - "to be installed on your system.")); - gtk_window_set_title (GTK_WINDOW (dialog), - _("Mouse Preferences")); - gtk_window_set_icon_name (GTK_WINDOW (dialog), - "input-mouse"); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - } - g_error_free (error); - } - g_free (comm); -} - -static void -set_mouse_settings (MsdMouseManager *manager) -{ - MateConfClient *client = mateconf_client_get_default (); - gboolean left_handed = mateconf_client_get_bool (client, KEY_LEFT_HANDED, NULL); - - set_left_handed (manager, left_handed); - set_motion_acceleration (manager, mateconf_client_get_float (client, KEY_MOTION_ACCELERATION , NULL)); - set_motion_threshold (manager, mateconf_client_get_int (client, KEY_MOTION_THRESHOLD, NULL)); - - set_disable_w_typing (manager, mateconf_client_get_bool (client, KEY_TOUCHPAD_DISABLE_W_TYPING, NULL)); -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - set_tap_to_click (mateconf_client_get_bool (client, KEY_TAP_TO_CLICK, NULL), left_handed); - set_edge_scroll (mateconf_client_get_int (client, KEY_SCROLL_METHOD, NULL)); - set_horiz_scroll (mateconf_client_get_bool (client, KEY_PAD_HORIZ_SCROLL, NULL)); - set_touchpad_enabled (mateconf_client_get_bool (client, KEY_TOUCHPAD_ENABLED, NULL)); -#endif - - g_object_unref (client); -} - -static void -mouse_callback (MateConfClient *client, - guint cnxn_id, - MateConfEntry *entry, - MsdMouseManager *manager) -{ - if (! strcmp (entry->key, KEY_LEFT_HANDED)) { - if (entry->value->type == MATECONF_VALUE_BOOL) { - set_left_handed (manager, mateconf_value_get_bool (entry->value)); - } - } else if (! strcmp (entry->key, KEY_MOTION_ACCELERATION)) { - if (entry->value->type == MATECONF_VALUE_FLOAT) { - set_motion_acceleration (manager, mateconf_value_get_float (entry->value)); - } - } else if (! strcmp (entry->key, KEY_MOTION_THRESHOLD)) { - if (entry->value->type == MATECONF_VALUE_INT) { - set_motion_threshold (manager, mateconf_value_get_int (entry->value)); - } - } else if (! strcmp (entry->key, KEY_TOUCHPAD_DISABLE_W_TYPING)) { - if (entry->value->type == MATECONF_VALUE_BOOL) - set_disable_w_typing (manager, mateconf_value_get_bool (entry->value)); -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - } else if (! strcmp (entry->key, KEY_TAP_TO_CLICK)) { - if (entry->value->type == MATECONF_VALUE_BOOL) { - set_tap_to_click (mateconf_value_get_bool (entry->value), - mateconf_client_get_bool (client, KEY_LEFT_HANDED, NULL)); - } - } else if (! strcmp (entry->key, KEY_SCROLL_METHOD)) { - if (entry->value->type == MATECONF_VALUE_INT) { - set_edge_scroll (mateconf_value_get_int (entry->value)); - set_horiz_scroll (mateconf_client_get_bool (client, KEY_PAD_HORIZ_SCROLL, NULL)); - } - } else if (! strcmp (entry->key, KEY_PAD_HORIZ_SCROLL)) { - if (entry->value->type == MATECONF_VALUE_BOOL) - set_horiz_scroll (mateconf_value_get_bool (entry->value)); -#endif - } else if (! strcmp (entry->key, KEY_LOCATE_POINTER)) { - if (entry->value->type == MATECONF_VALUE_BOOL) { - set_locate_pointer (manager, mateconf_value_get_bool (entry->value)); - } -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - } else if (! strcmp (entry->key, KEY_TOUCHPAD_ENABLED)) { - if (entry->value->type == MATECONF_VALUE_BOOL) { - set_touchpad_enabled (mateconf_value_get_bool (entry->value)); - } -#endif - } else if (! strcmp (entry->key, KEY_DWELL_ENABLE)) { - if (entry->value->type == MATECONF_VALUE_BOOL) { - set_mousetweaks_daemon (manager, - mateconf_value_get_bool (entry->value), - mateconf_client_get_bool (client, KEY_DELAY_ENABLE, NULL)); - } - } else if (! strcmp (entry->key, KEY_DELAY_ENABLE)) { - if (entry->value->type == MATECONF_VALUE_BOOL) { - set_mousetweaks_daemon (manager, - mateconf_client_get_bool (client, KEY_DWELL_ENABLE, NULL), - mateconf_value_get_bool (entry->value)); - } - } -} - -static guint -register_config_callback (MsdMouseManager *manager, - MateConfClient *client, - const char *path, - MateConfClientNotifyFunc func) -{ - mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); - return mateconf_client_notify_add (client, path, func, manager, NULL, NULL); -} - -static void -msd_mouse_manager_init (MsdMouseManager *manager) -{ - manager->priv = MSD_MOUSE_MANAGER_GET_PRIVATE (manager); -} - -static gboolean -msd_mouse_manager_idle_cb (MsdMouseManager *manager) -{ - MateConfClient *client; - - mate_settings_profile_start (NULL); - - client = mateconf_client_get_default (); - - manager->priv->notify = - register_config_callback (manager, - client, - MATECONF_MOUSE_DIR, - (MateConfClientNotifyFunc) mouse_callback); - manager->priv->notify_a11y = - register_config_callback (manager, - client, - MATECONF_MOUSE_A11Y_DIR, - (MateConfClientNotifyFunc) mouse_callback); - manager->priv->notify_touchpad = - register_config_callback (manager, - client, - MATECONF_TOUCHPAD_DIR, - (MateConfClientNotifyFunc) mouse_callback); - manager->priv->syndaemon_spawned = FALSE; - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - set_devicepresence_handler (manager); -#endif - set_mouse_settings (manager); - set_locate_pointer (manager, mateconf_client_get_bool (client, KEY_LOCATE_POINTER, NULL)); - set_mousetweaks_daemon (manager, - mateconf_client_get_bool (client, KEY_DWELL_ENABLE, NULL), - mateconf_client_get_bool (client, KEY_DELAY_ENABLE, NULL)); - - set_disable_w_typing (manager, mateconf_client_get_bool (client, KEY_TOUCHPAD_DISABLE_W_TYPING, NULL)); -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - set_tap_to_click (mateconf_client_get_bool (client, KEY_TAP_TO_CLICK, NULL), - mateconf_client_get_bool (client, KEY_LEFT_HANDED, NULL)); - set_edge_scroll (mateconf_client_get_int (client, KEY_SCROLL_METHOD, NULL)); - set_horiz_scroll (mateconf_client_get_bool (client, KEY_PAD_HORIZ_SCROLL, NULL)); - set_touchpad_enabled (mateconf_client_get_bool (client, KEY_TOUCHPAD_ENABLED, NULL)); -#endif - - g_object_unref (client); - - mate_settings_profile_end (NULL); - - return FALSE; -} - -gboolean -msd_mouse_manager_start (MsdMouseManager *manager, - GError **error) -{ - mate_settings_profile_start (NULL); - - g_idle_add ((GSourceFunc) msd_mouse_manager_idle_cb, manager); - - mate_settings_profile_end (NULL); - - return TRUE; -} - -void -msd_mouse_manager_stop (MsdMouseManager *manager) -{ - MsdMouseManagerPrivate *p = manager->priv; - MateConfClient *client; - - g_debug ("Stopping mouse manager"); - - client = mateconf_client_get_default (); - - if (p->notify != 0) { - mateconf_client_remove_dir (client, MATECONF_MOUSE_DIR, NULL); - mateconf_client_notify_remove (client, p->notify); - p->notify = 0; - } - - if (p->notify_a11y != 0) { - mateconf_client_remove_dir (client, MATECONF_MOUSE_A11Y_DIR, NULL); - mateconf_client_notify_remove (client, p->notify_a11y); - p->notify_a11y = 0; - } - - if (p->notify_touchpad != 0) { - mateconf_client_remove_dir (client, MATECONF_TOUCHPAD_DIR, NULL); - mateconf_client_notify_remove (client, p->notify_touchpad); - p->notify_touchpad = 0; - } - - g_object_unref (client); - - set_locate_pointer (manager, FALSE); - -#ifdef HAVE_X11_EXTENSIONS_XINPUT_H - gdk_window_remove_filter (NULL, devicepresence_filter, manager); -#endif -} - -static void -msd_mouse_manager_finalize (GObject *object) -{ - MsdMouseManager *mouse_manager; - - g_return_if_fail (object != NULL); - g_return_if_fail (MSD_IS_MOUSE_MANAGER (object)); - - mouse_manager = MSD_MOUSE_MANAGER (object); - - g_return_if_fail (mouse_manager->priv != NULL); - - G_OBJECT_CLASS (msd_mouse_manager_parent_class)->finalize (object); -} - -MsdMouseManager * -msd_mouse_manager_new (void) -{ - if (manager_object != NULL) { - g_object_ref (manager_object); - } else { - manager_object = g_object_new (MSD_TYPE_MOUSE_MANAGER, NULL); - g_object_add_weak_pointer (manager_object, - (gpointer *) &manager_object); - } - - return MSD_MOUSE_MANAGER (manager_object); -} |