summaryrefslogtreecommitdiff
path: root/plugins/mouse/gsd-mouse-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mouse/gsd-mouse-manager.c')
-rw-r--r--plugins/mouse/gsd-mouse-manager.c1124
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);
-}