2014-10-29 10:37:29 -04:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 Red Hat
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* Author: Carlos Garnacho <carlosg@gnome.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "meta-backend-x11.h"
|
|
|
|
#include "meta-input-settings-x11.h"
|
|
|
|
|
2015-05-08 11:36:55 -04:00
|
|
|
#include <string.h>
|
2014-10-29 10:37:29 -04:00
|
|
|
#include <gdk/gdkx.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
#include <X11/extensions/XInput2.h>
|
2015-06-11 21:10:28 -04:00
|
|
|
#include <X11/Xlib-xcb.h>
|
2014-10-29 10:37:29 -04:00
|
|
|
#include <X11/XKBlib.h>
|
2015-06-11 21:10:28 -04:00
|
|
|
#include <xcb/xinput.h>
|
2014-10-29 10:37:29 -04:00
|
|
|
|
|
|
|
#include <meta/errors.h>
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (MetaInputSettingsX11, meta_input_settings_x11, META_TYPE_INPUT_SETTINGS)
|
|
|
|
|
2015-05-08 11:31:48 -04:00
|
|
|
static void *
|
|
|
|
get_property (ClutterInputDevice *device,
|
|
|
|
const gchar *property,
|
|
|
|
Atom type,
|
|
|
|
int format,
|
|
|
|
gulong nitems)
|
|
|
|
{
|
|
|
|
MetaBackend *backend = meta_get_backend ();
|
|
|
|
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
|
gulong nitems_ret, bytes_after_ret;
|
|
|
|
int rc, device_id, format_ret;
|
|
|
|
Atom property_atom, type_ret;
|
|
|
|
guchar *data_ret = NULL;
|
|
|
|
|
|
|
|
property_atom = XInternAtom (xdisplay, property, False);
|
|
|
|
device_id = clutter_input_device_get_device_id (device);
|
|
|
|
|
|
|
|
rc = XIGetProperty (xdisplay, device_id, property_atom,
|
|
|
|
0, 10, False, type, &type_ret, &format_ret,
|
|
|
|
&nitems_ret, &bytes_after_ret, &data_ret);
|
|
|
|
if (rc == Success && type_ret == type && format_ret == format && nitems_ret >= nitems)
|
|
|
|
{
|
|
|
|
if (nitems_ret > nitems)
|
|
|
|
g_warning ("Property '%s' for device '%s' returned %lu items, expected %lu",
|
|
|
|
property, clutter_input_device_get_device_name (device), nitems_ret, nitems);
|
|
|
|
return data_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_XFree (data_ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-10-29 10:37:29 -04:00
|
|
|
static void
|
|
|
|
change_property (ClutterInputDevice *device,
|
|
|
|
const gchar *property,
|
|
|
|
Atom type,
|
|
|
|
int format,
|
|
|
|
void *data,
|
|
|
|
gulong nitems)
|
|
|
|
{
|
|
|
|
MetaBackend *backend = meta_get_backend ();
|
|
|
|
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
2015-06-11 21:10:28 -04:00
|
|
|
xcb_connection_t *xcb_conn = XGetXCBConnection (xdisplay);
|
2015-05-08 11:31:48 -04:00
|
|
|
int device_id;
|
|
|
|
Atom property_atom;
|
2014-10-29 10:37:29 -04:00
|
|
|
guchar *data_ret;
|
|
|
|
|
|
|
|
property_atom = XInternAtom (xdisplay, property, False);
|
|
|
|
device_id = clutter_input_device_get_device_id (device);
|
|
|
|
|
2015-05-08 11:31:48 -04:00
|
|
|
data_ret = get_property (device, property, type, format, nitems);
|
|
|
|
if (!data_ret)
|
|
|
|
return;
|
2014-10-29 10:37:29 -04:00
|
|
|
|
2015-06-11 21:10:28 -04:00
|
|
|
xcb_input_xi_change_property (xcb_conn, device_id, XCB_PROP_MODE_REPLACE,
|
|
|
|
format, property_atom, type,
|
|
|
|
nitems, data);
|
2014-10-29 10:37:29 -04:00
|
|
|
meta_XFree (data_ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
GDesktopDeviceSendEvents mode)
|
|
|
|
{
|
|
|
|
guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
|
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
|
|
|
|
values[0] = 1;
|
|
|
|
break;
|
|
|
|
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
|
|
|
values[1] = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
change_property (device, "libinput Send Events Mode Enabled",
|
|
|
|
XA_INTEGER, 8, &values, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_matrix (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
gfloat matrix[6])
|
|
|
|
{
|
|
|
|
MetaBackend *backend = meta_get_backend ();
|
|
|
|
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
|
gfloat full_matrix[9] = { matrix[0], matrix[1], matrix[2],
|
|
|
|
matrix[3], matrix[4], matrix[5],
|
|
|
|
0, 0, 1 };
|
|
|
|
|
|
|
|
change_property (device, "Coordinate Transformation Matrix",
|
|
|
|
XInternAtom (xdisplay, "FLOAT", False),
|
|
|
|
32, &full_matrix, 9);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_speed (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
gdouble speed)
|
|
|
|
{
|
|
|
|
MetaBackend *backend = meta_get_backend ();
|
|
|
|
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
|
gfloat value = speed;
|
|
|
|
|
|
|
|
change_property (device, "libinput Accel Speed",
|
|
|
|
XInternAtom (xdisplay, "FLOAT", False),
|
|
|
|
32, &value, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
gboolean enabled)
|
|
|
|
{
|
|
|
|
guchar value = (enabled) ? 1 : 0;
|
|
|
|
|
|
|
|
change_property (device, "libinput Left Handed Enabled",
|
|
|
|
XA_INTEGER, 8, &value, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
gboolean enabled)
|
|
|
|
{
|
|
|
|
guchar value = (enabled) ? 1 : 0;
|
|
|
|
|
|
|
|
change_property (device, "libinput Tapping Enabled",
|
|
|
|
XA_INTEGER, 8, &value, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
gboolean inverted)
|
|
|
|
{
|
|
|
|
guchar value = (inverted) ? 1 : 0;
|
|
|
|
|
|
|
|
change_property (device, "libinput Natural Scrolling Enabled",
|
|
|
|
XA_INTEGER, 8, &value, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_scroll_method (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
GDesktopTouchpadScrollMethod mode)
|
|
|
|
{
|
|
|
|
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
|
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
|
|
|
|
break;
|
|
|
|
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
|
|
|
|
values[1] = 1;
|
|
|
|
break;
|
|
|
|
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
|
|
|
values[0] = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
|
|
|
|
|
|
|
change_property (device, "libinput Scroll Method Enabled",
|
|
|
|
XA_INTEGER, 8, &values, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
guint button)
|
|
|
|
{
|
2015-04-15 11:55:38 -04:00
|
|
|
change_property (device, "libinput Button Scrolling Button",
|
2014-10-29 10:37:29 -04:00
|
|
|
XA_INTEGER, 32, &button, 1);
|
|
|
|
}
|
|
|
|
|
2015-03-16 10:28:42 -04:00
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_click_method (MetaInputSettings *settings,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
GDesktopTouchpadClickMethod mode)
|
|
|
|
{
|
|
|
|
guchar values[2] = { 0 }; /* buttonareas, clickfinger */
|
2015-05-08 11:36:55 -04:00
|
|
|
guchar *defaults;
|
2015-03-16 10:28:42 -04:00
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
{
|
2015-05-08 11:36:55 -04:00
|
|
|
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
|
|
|
|
defaults = get_property (device, "libinput Click Method Enabled Default",
|
|
|
|
XA_INTEGER, 8, 2);
|
|
|
|
if (!defaults)
|
|
|
|
break;
|
|
|
|
memcpy (values, defaults, 2);
|
|
|
|
meta_XFree (defaults);
|
|
|
|
break;
|
2015-03-16 10:28:42 -04:00
|
|
|
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
|
|
|
|
break;
|
|
|
|
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
|
|
|
|
values[0] = 1;
|
|
|
|
break;
|
|
|
|
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS:
|
|
|
|
values[1] = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
change_property (device, "libinput Click Method Enabled",
|
|
|
|
XA_INTEGER, 8, &values, 2);
|
|
|
|
}
|
|
|
|
|
2014-10-29 10:37:29 -04:00
|
|
|
static void
|
|
|
|
meta_input_settings_x11_set_keyboard_repeat (MetaInputSettings *settings,
|
|
|
|
gboolean enabled,
|
|
|
|
guint delay,
|
|
|
|
guint interval)
|
|
|
|
{
|
|
|
|
MetaBackend *backend = meta_get_backend ();
|
|
|
|
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
|
|
|
|
|
if (enabled)
|
|
|
|
{
|
|
|
|
XAutoRepeatOn (xdisplay);
|
|
|
|
XkbSetAutoRepeatRate (xdisplay, XkbUseCoreKbd, delay, interval);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XAutoRepeatOff (xdisplay);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
|
|
|
{
|
|
|
|
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
|
|
|
|
|
|
|
input_settings_class->set_send_events = meta_input_settings_x11_set_send_events;
|
|
|
|
input_settings_class->set_matrix = meta_input_settings_x11_set_matrix;
|
|
|
|
input_settings_class->set_speed = meta_input_settings_x11_set_speed;
|
|
|
|
input_settings_class->set_left_handed = meta_input_settings_x11_set_left_handed;
|
|
|
|
input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled;
|
|
|
|
input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll;
|
|
|
|
input_settings_class->set_scroll_method = meta_input_settings_x11_set_scroll_method;
|
|
|
|
input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button;
|
2015-03-16 10:28:42 -04:00
|
|
|
input_settings_class->set_click_method = meta_input_settings_x11_set_click_method;
|
2014-10-29 10:37:29 -04:00
|
|
|
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_input_settings_x11_init (MetaInputSettingsX11 *settings)
|
|
|
|
{
|
|
|
|
}
|