Hello community,
here is the log from the commit of package xorg-x11-driver-input for openSUSE:Factory
checked in at Wed Apr 21 18:09:20 CEST 2010.
--------
--- xorg-x11-driver-input/xorg-x11-driver-input.changes 2010-04-16 11:54:53.000000000 +0200
+++ xorg-x11-driver-input/xorg-x11-driver-input.changes 2010-04-21 16:45:05.000000000 +0200
@@ -1,0 +2,6 @@
+Wed Apr 21 16:36:42 CEST 2010 - tiwai@suse.de
+
+- xf86-input-synaptics-add-clickpad-support,
+ xf86-input-synaptics-add-led-support: Add Clickpad support
+
+-------------------------------------------------------------------
calling whatdependson for head-i586
New:
----
xf86-input-synaptics-add-clickpad-support
xf86-input-synaptics-add-led-support
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xorg-x11-driver-input.spec ++++++
--- /var/tmp/diff_new_pack.O0Hv0t/_old 2010-04-21 18:09:02.000000000 +0200
+++ /var/tmp/diff_new_pack.O0Hv0t/_new 2010-04-21 18:09:02.000000000 +0200
@@ -23,7 +23,7 @@
BuildRequires: Mesa-devel pkgconfig udev xorg-x11-proto-devel xorg-x11-server-sdk
Url: http://xorg.freedesktop.org/
Version: 7.5
-Release: 4
+Release: 5
License: MIT License (or similar)
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Group: System/X11/Servers/XF86_4
@@ -62,6 +62,8 @@
Patch40: xf86-input-hyperpen.diff
Patch41: xf86-input-mutouch.diff
Patch43: xf86-input-synaptics-retry-serial-open.diff
+Patch44: xf86-input-synaptics-add-clickpad-support
+Patch45: xf86-input-synaptics-add-led-support
%description
This package contains X.Org input drivers.
@@ -78,6 +80,8 @@
%patch23 -p0
%patch24 -p0
%patch43 -p1
+%patch44 -p1
+%patch45 -p1
popd
pushd xf86-input-elographics-*
%patch38 -p1
++++++ xf86-input-synaptics-add-clickpad-support ++++++
From 0b3698b3a34c8e250512df6c0ba434da2d8ae0d5 Mon Sep 17 00:00:00 2001
From: Takashi Iwai
Date: Tue, 13 Apr 2010 17:25:23 +0200
Subject: [PATCH] Add Clickpad support
This patch adds the support for Synaptics Clickpad devices.
It requires the change in Linux kernel synaptics input driver, found in
https://patchwork.kernel.org/patch/92435/
When the kernel driver sets only the left-button bit evbit, Clickpad
mode is activated. In this mode, the bottom touch area is used as
button emulations. Clicking at the bottom-left, bottom-center and
bottom-right zone corresponds to a left, center and right click.
Signed-off-by: Takashi Iwai
---
src/eventcomm.c | 6 ++++++
src/synaptics.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/synapticsstr.h | 2 ++
3 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/src/eventcomm.c b/src/eventcomm.c
index d00d810..10d183d 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -252,6 +252,12 @@ event_query_axis_ranges(LocalDevicePtr local)
if ((priv->has_triple = (TEST_BIT(BTN_TOOL_TRIPLETAP, keybits) != 0)))
strcat(buf, " triple");
xf86Msg(X_INFO, "%s: buttons:%s\n", local->name, buf);
+
+ /* clickpad device reports only the single left button mask */
+ if (priv->has_left && !priv->has_right && !priv->has_middle) {
+ priv->is_clickpad = TRUE;
+ xf86Msg(X_INFO, "%s: is Clickpad device\n", local->name);
+ }
}
}
diff --git a/src/synaptics.c b/src/synaptics.c
index 091dbe1..0c63f8b 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -457,6 +457,14 @@ static void set_default_parameters(LocalDevicePtr local)
vertResolution = priv->resy;
}
+ /* Clickpad mode -- bottom area is used as buttons */
+ if (priv->is_clickpad) {
+ int button_bottom;
+ button_bottom = priv->maxy - (abs(priv->maxy - priv->miny) * 20) / 100;
+ if (button_bottom < b && b >= t)
+ b = button_bottom;
+ }
+
/* set the parameters */
pars->left_edge = xf86SetIntOption(opts, "LeftEdge", l);
pars->right_edge = xf86SetIntOption(opts, "RightEdge", r);
@@ -2052,6 +2060,44 @@ HandleClickWithFingers(SynapticsParameters *para, struct SynapticsHwState *hw)
}
}
+/* clickpad event handling */
+static void
+HandleClickpad(LocalDevicePtr local, struct SynapticsHwState *hw)
+{
+ SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+
+ if (priv->prev_hw.left || priv->prev_hw.middle || priv->prev_hw.right) {
+ /* dragging */
+ if (hw->left) {
+ hw->left = priv->prev_hw.left;
+ hw->right = priv->prev_hw.right;
+ hw->middle = priv->prev_hw.middle;
+ }
+ } else {
+ int width = priv->maxx - priv->minx;
+ int left_button_x, right_button_x;
+
+ /* left and right clickpad button ranges;
+ * the gap between them is interpreted as a middle-button click
+ */
+ left_button_x = width * 2/ 5 + priv->minx;
+ right_button_x = width * 3 / 5 + priv->minx;
+
+ /* clickpad reports only one button, and we need
+ * to fake left/right buttons depending on the touch position
+ */
+ if (hw->left) { /* clicked? */
+ hw->left = 0;
+ if (hw->x < left_button_x)
+ hw->left = 1;
+ else if (hw->x > right_button_x)
+ hw->right = 1;
+ else
+ hw->middle = 1;
+ }
+ }
+ priv->prev_hw = *hw;
+}
/*
* React on changes in the hardware state. This function is called every time
@@ -2102,6 +2148,10 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
if (para->touchpad_off == 1)
return delay;
+ /* Clickpad handling for button area */
+ if (priv->is_clickpad)
+ HandleClickpad(local, hw);
+
/* Treat the first two multi buttons as up/down for now. */
hw->up |= hw->multi[0];
hw->down |= hw->multi[1];
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index bd19c79..05e43d3 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -232,6 +232,8 @@ typedef struct _SynapticsPrivateRec
Bool has_double; /* double click detected for this device */
Bool has_triple; /* triple click detected for this device */
Bool has_pressure; /* device reports pressure */
+ Bool is_clickpad; /* is Clickpad device (one-button) */
+ struct SynapticsHwState prev_hw; /* previous h/w state (for clickpad) */
enum TouchpadModel model; /* The detected model */
} SynapticsPrivate;
--
1.7.0.4
++++++ xf86-input-synaptics-add-led-support ++++++
From ee7ad89ecbe365a6a9705b34a4c4b697cbff333e Mon Sep 17 00:00:00 2001
From: Takashi Iwai
Date: Wed, 21 Apr 2010 13:33:41 +0200
Subject: [PATCH 2/2] Support LED and tap-on-LED feature
This patch adds the control of the embedded LED on the top-left corner
of new Synaptics devices. For LED control, it requires the patch to
Linux synaptics input driver,
https://patchwork.kernel.org/patch/93858/
When a sysfs file /sys/class/leds/psmouse::synaptics exists, the driver
assumes it supports the embeded LED control. This corresponds to the
touchpad-off state. When touchpad is disabled, LED is turned on.
For linking between the touchpad state and the LED state, a new callback
UpdateHardware is introduced. Only eventcomm.c supports this (naturally).
A new feature for the LED-equipped device is that user can double-tap
on the LED to toggle the touchpad state on the fly. This is also linked
with the touchpad-off state.
There is a new parameter for controlling the LED double-tap behavior, too.
It specifies the double-tap time. Passing zero disables the double-tap
feature.
Signed-off-by: Takashi Iwai
---
include/synaptics-properties.h | 3 +
man/synaptics.man | 13 ++++++
src/eventcomm.c | 29 ++++++++++++++
src/properties.c | 26 +++++++++++++
src/synaptics.c | 80 +++++++++++++++++++++++++++++++++++++++++
src/synapticsstr.h | 6 +++
src/synproto.h | 1
tools/synclient.c | 1
8 files changed, 158 insertions(+), 1 deletion(-)
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -155,4 +155,7 @@
/* 32 bit, 4 values, left, right, top, bottom */
#define SYNAPTICS_PROP_AREA "Synaptics Area"
+/* 32 bit */
+#define SYNAPTICS_PROP_LED_DOUBLE_TAP "Synaptics LED Double Tap"
+
#endif /* _SYNAPTICS_PROPERTIES_H_ */
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -509,6 +509,19 @@
The option is disabled by default and can be enabled by setting the
AreaBottomEdge option to any integer value other than zero. Property: "Synaptics Area"
.
+.TP
+.BI "Option \*qLEDDoubleTap\*q \*q" integer \*q
+.
+The double-tap time for toggling the touchpad-control on the top-left
+corner LED.
+.
+Some devices have an LED on the top-left corner to indicate the
+touchpad state. User can double-tap on the LED to toggle the touchpad
+state. This option controls the double-tap time in milli-seconds.
+When it's zero, the LED-tapping feature is disabled. The default
+value is 400.
+Property: "Synaptics LED Double Tap"
+.
.LP
A tap event happens when the finger is touched and released in a time
interval shorter than MaxTapTime, and the touch and release
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -51,6 +51,8 @@
#define LONG(x) ((x) / LONG_BITS)
#define TEST_BIT(bit, array) (array[LONG(bit)] & (1 << OFF(bit)))
+#define SYNAPTICS_LED_SYS_FILE "/sys/class/leds/psmouse::synaptics/brightness"
+
/*****************************************************************************
* Function Definitions
****************************************************************************/
@@ -166,6 +168,29 @@
}
}
+static void
+event_query_led(LocalDevicePtr local)
+{
+ SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
+
+ priv->has_led = !access(SYNAPTICS_LED_SYS_FILE, W_OK);
+}
+
+static void EventUpdateHardware(LocalDevicePtr local)
+{
+ SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
+
+ if (priv->has_led) {
+ char *val = priv->synpara.touchpad_off ? "255" : "0";
+ int fd = open(SYNAPTICS_LED_SYS_FILE, O_WRONLY);
+ if (fd < 0)
+ return;
+ if (write(fd, val, strlen(val)) < 0)
+ return;
+ close(fd);
+ }
+}
+
/* Query device for axis ranges */
static void
event_query_axis_ranges(LocalDevicePtr local)
@@ -430,6 +455,7 @@
if (event_query_is_touchpad(local->fd, (need_grab) ? *need_grab : TRUE))
event_query_axis_ranges(local);
event_query_info(local);
+ event_query_led(local);
}
static Bool
@@ -499,5 +525,6 @@
EventQueryHardware,
EventReadHwState,
EventAutoDevProbe,
- EventReadDevDimensions
+ EventReadDevDimensions,
+ EventUpdateHardware,
};
--- a/src/properties.c
+++ b/src/properties.c
@@ -84,6 +84,7 @@
Atom prop_capabilities = 0;
Atom prop_resolution = 0;
Atom prop_area = 0;
+Atom prop_led_double_tap = 0;
static Atom
InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values)
@@ -274,6 +275,9 @@
values[2] = para->area_top_edge;
values[3] = para->area_bottom_edge;
prop_area = InitAtom(local->dev, SYNAPTICS_PROP_AREA, 32, 4, values);
+
+ prop_led_double_tap = InitAtom(local->dev, SYNAPTICS_PROP_LED_DOUBLE_TAP, 32, 1, ¶->led_double_tap);
+
}
int
@@ -490,6 +494,11 @@
return BadValue;
para->touchpad_off = off;
+ if (!checkonly) {
+ if (priv->proto_ops && priv->proto_ops->UpdateHardware)
+ priv->proto_ops->UpdateHardware(local);
+ }
+
} else if (property == prop_guestmouse)
{
if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
@@ -642,10 +651,27 @@
para->area_right_edge = area[1];
para->area_top_edge = area[2];
para->area_bottom_edge = area[3];
+ } else if (property == prop_led_double_tap)
+ {
+ if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER)
+ return BadMatch;
+
+ para->led_double_tap = *(INT32*)prop->data;
}
return Success;
}
+void SynapticsToggleOffProperty(DeviceIntPtr dev, Bool off)
+{
+ uint8_t val;
+
+ if (!prop_off)
+ return;
+ val = off;
+ XIChangeDeviceProperty(dev, prop_off, XA_INTEGER, 8,
+ PropModeReplace, 1, &val, FALSE);
+}
+
#endif
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -138,6 +138,7 @@
void InitDeviceProperties(LocalDevicePtr local);
int SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
BOOL checkonly);
+void SynapticsToggleOffProperty(DeviceIntPtr dev, Bool off);
#endif
InputDriverRec SYNAPTICS = {
@@ -549,6 +550,7 @@
pars->tap_and_drag_gesture = xf86SetBoolOption(opts, "TapAndDragGesture", TRUE);
pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", horizResolution);
pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", vertResolution);
+ pars->led_double_tap = xf86SetIntOption(opts, "LEDDoubleTap", 400);
/* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
if (pars->top_edge > pars->bottom_edge) {
@@ -805,6 +807,10 @@
xf86AddEnabledDevice(local);
+ /* update LED */
+ if (priv->proto_ops && priv->proto_ops->UpdateHardware)
+ priv->proto_ops->UpdateHardware(local);
+
return Success;
}
@@ -2120,6 +2126,72 @@
}
}
+#define LED_TOGGLE_X_AREA 0.10
+#define LED_TOGGLE_Y_AREA 0.08
+
+static int
+in_led_toggle_area(LocalDevicePtr local, struct SynapticsHwState *hw)
+{
+ SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+ int click_led_x, click_led_y;
+
+ click_led_x = (priv->maxx - priv->minx) * LED_TOGGLE_X_AREA + priv->minx;
+ click_led_y = (priv->maxy - priv->miny) * LED_TOGGLE_Y_AREA + priv->miny;
+ return (hw->x < click_led_x && hw->y < click_led_y);
+}
+
+/* clicpad button toggle point:
+ * some devices have a LED at the upper-left corner, and double-tapping it
+ * toggles the touchpad enable/disable
+ */
+static int
+HandleToggleLED(LocalDevicePtr local, struct SynapticsHwState *hw, int finger)
+{
+ SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+ SynapticsParameters *para = &priv->synpara;
+ int diff;
+
+ if (finger) {
+ if (!in_led_toggle_area(local, hw)) {
+ /* outside the toggle area */
+ priv->led_touch_state = FALSE;
+ priv->led_tapped = FALSE;
+ return finger;
+ }
+ if (!priv->led_touch_state) {
+ /* touch start */
+ priv->led_touch_millis = hw->millis;
+ priv->led_touch_state = TRUE;
+ }
+ return 0; /* already processed; ignore this finger event */
+ }
+
+ if (!priv->led_touch_state)
+ return finger; /* nothing happened */
+
+ /* touch-released */
+ priv->led_touch_state = FALSE;
+ diff = TIME_DIFF(priv->led_touch_millis + para->tap_time, hw->millis);
+ if (diff < 0) /* non-tap? */
+ return finger;
+ if (priv->led_tapped) {
+ /* double-tapped? */
+ diff = TIME_DIFF(priv->led_tap_millis + para->led_double_tap, hw->millis);
+ if (diff >= 0) {
+ para->touchpad_off = !para->touchpad_off;
+ if (priv->proto_ops && priv->proto_ops->UpdateHardware)
+ priv->proto_ops->UpdateHardware(local); /* update LED */
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
+ SynapticsToggleOffProperty(local->dev, para->touchpad_off);
+#endif
+ priv->led_tapped = FALSE;
+ }
+ } else
+ priv->led_tapped = TRUE;
+ priv->led_tap_millis = hw->millis;
+ return 0; /* already processed; ignore this finger event */
+}
+
/* clickpad event handling */
static void
HandleClickpad(LocalDevicePtr local, struct SynapticsHwState *hw)
@@ -2267,6 +2339,14 @@
finger = SynapticsDetectFinger(priv, hw);
+ if (priv->has_led && para->led_double_tap) {
+ finger = HandleToggleLED(local, hw, finger);
+ if (para->touchpad_off == 1) {
+ priv->finger_state = finger;
+ return delay;
+ }
+ }
+
/* tap and drag detection */
timeleft = HandleTapProcessing(priv, hw, edge, finger, inside_active_area);
if (timeleft > 0)
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -149,6 +149,7 @@
unsigned int resolution_horiz; /* horizontal resolution of touchpad in units/mm */
unsigned int resolution_vert; /* vertical resolution of touchpad in units/mm */
int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
+ int led_double_tap; /* double-tap period in ms for touchpad LED control */
} SynapticsParameters;
@@ -223,6 +224,11 @@
Bool has_pressure; /* device reports pressure */
Bool is_clickpad; /* is Clickpad device (one-button) */
struct SynapticsHwState prev_hw; /* previous h/w state (for clickpad) */
+ Bool has_led; /* has LED indicator */
+ Bool led_touch_state;
+ Bool led_tapped;
+ int led_touch_millis;
+ int led_tap_millis;
enum TouchpadModel model; /* The detected model */
} SynapticsPrivate;
--- a/src/synproto.h
+++ b/src/synproto.h
@@ -97,6 +97,7 @@
struct CommData *comm, struct SynapticsHwState *hwRet);
Bool (*AutoDevProbe)(LocalDevicePtr local);
void (*ReadDevDimensions)(LocalDevicePtr local);
+ void (*UpdateHardware)(LocalDevicePtr local);
};
extern struct SynapticsProtocolOperations psaux_proto_operations;
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -143,6 +143,7 @@
{"AreaRightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 1},
{"AreaTopEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 2},
{"AreaBottomEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 3},
+ {"LEDDoubleTap", PT_INT, 0, 1000, SYNAPTICS_PROP_LED_DOUBLE_TAP, 32, 0},
{ NULL, 0, 0, 0, 0 }
};
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org