[PATCH] weston-launch: only drop privileges when uid/gid != euid/egid

2013-08-05 Thread Peter Hutterer
initgroups requires CAP_SETGID and may fail. If we're not actually
changing anything anyway we can just skip this and (most likely) fail later
when we don't have the required permissions to open something.
---
Should arguably be part of the previous patch but since it changes behaviour
from before 636156d, here it is separately.

running weston-launch as user (w/o suid bit set) now passes this bit (and
fails later, but still :)

 src/weston-launch.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/weston-launch.c b/src/weston-launch.c
index 5b03094..06194a9 100644
--- a/src/weston-launch.c
+++ b/src/weston-launch.c
@@ -554,7 +554,8 @@ launch_compositor(struct weston_launch *wl, int argc, char 
*argv[])
if (wl->new_user)
setup_session(wl);
 
-   drop_privileges(wl);
+   if (getuid() != geteuid() || getgid() != getegid())
+   drop_privileges(wl);
 
if (wl->tty != STDIN_FILENO)
setenv_fd("WESTON_TTY_FD", wl->tty);
-- 
1.8.2.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] weston-launch: always drop privileges before execve

2013-08-05 Thread Peter Hutterer
The current code works if pw->pw_shell is bash because:
 "If the shell is started with the effective user (group) id not equal to
 the real user (group) id, and the -p option is not supplied, these actions
 are taken and the effective user id is set to the real user id."

Thus, for bash, weston's EUID == UID.

For zsh, the -p option "is enabled automatically on startup if the effective
user (group) ID is  not equal to the real user (group) ID."
Thus, weston's EUID = 0, and if pw_shell is zsh, /run/user/$UID/wayland-0 is
created with euid root and not writeable by the user, causing all clients to
fail.

Fix this by always dropping privileges to the user.

Regression introduced in 636156d.
---
 src/weston-launch.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/weston-launch.c b/src/weston-launch.c
index a111812..5b03094 100644
--- a/src/weston-launch.c
+++ b/src/weston-launch.c
@@ -513,13 +513,6 @@ setup_session(struct weston_launch *wl)
error(1, errno, "TIOCSCTTY failed - tty is in use");
}
 
-   if (setgid(wl->pw->pw_gid) < 0 ||
-#ifdef HAVE_INITGROUPS
-   initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
-#endif
-   setuid(wl->pw->pw_uid) < 0)
-   error(1, errno, "dropping privileges failed");
-
term = getenv("TERM");
clearenv();
setenv("TERM", term, 1);
@@ -539,6 +532,17 @@ setup_session(struct weston_launch *wl)
 }
 
 static void
+drop_privileges(struct weston_launch *wl)
+{
+   if (setgid(wl->pw->pw_gid) < 0 ||
+#ifdef HAVE_INITGROUPS
+   initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
+#endif
+   setuid(wl->pw->pw_uid) < 0)
+   error(1, errno, "dropping privileges failed");
+}
+
+static void
 launch_compositor(struct weston_launch *wl, int argc, char *argv[])
 {
char *child_argv[MAX_ARGV_SIZE];
@@ -550,6 +554,8 @@ launch_compositor(struct weston_launch *wl, int argc, char 
*argv[])
if (wl->new_user)
setup_session(wl);
 
+   drop_privileges(wl);
+
if (wl->tty != STDIN_FILENO)
setenv_fd("WESTON_TTY_FD", wl->tty);
 
-- 
1.8.2.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] Drop extraneous duplicate header includes

2013-08-05 Thread Bryce Harrington
From: Bryce Harrington 

Signed-off-by: Bryce Harrington 
---
 clients/flower.c   |1 -
 clients/smoke.c|1 -
 src/compositor-drm.c   |1 -
 src/compositor-fbdev.c |2 --
 4 files changed, 5 deletions(-)

diff --git a/clients/flower.c b/clients/flower.c
index 87a1a00..b31d513 100644
--- a/clients/flower.c
+++ b/clients/flower.c
@@ -26,7 +26,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/clients/smoke.c b/clients/smoke.c
index 5d7333d..0177424 100644
--- a/clients/smoke.c
+++ b/clients/smoke.c
@@ -26,7 +26,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index c7d6c04..a47fe36 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -25,7 +25,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
index 10ba7db..73ce37b 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -39,8 +39,6 @@
 
 #include 
 
-#include "config.h"
-
 #include "compositor.h"
 #include "launcher-util.h"
 #include "pixman-renderer.h"
-- 
1.7.9.5

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH 3/4 v2] xwayland: Draw decoration on window manager side

2013-08-05 Thread Louis-Francis Ratté-Boulianne
Draw everything in a cairo image surface before copying it to the XCB
surface. That removes the flickering visible on rpi whenever the
decoration were redrawn.
---
 src/xwayland/window-manager.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 15cb2ed..594c64f 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -97,6 +97,7 @@ struct weston_wm_window {
xcb_window_t id;
xcb_window_t frame_id;
cairo_surface_t *cairo_surface;
+   cairo_surface_t *cairo_xcb_surface;
struct weston_surface *surface;
struct shell_surface *shsurf;
struct wl_listener surface_destroy_listener;
@@ -900,12 +901,16 @@ weston_wm_handle_map_request(struct weston_wm *wm, 
xcb_generic_event_t *event)
xcb_map_window(wm->conn, map_request->window);
xcb_map_window(wm->conn, window->frame_id);
 
-   window->cairo_surface =
+   window->cairo_xcb_surface =
cairo_xcb_surface_create_with_xrender_format(wm->conn,
 wm->screen,
 window->frame_id,
 &wm->format_rgba,
 width, height);
+   window->cairo_surface =
+   cairo_surface_create_similar_image(window->cairo_xcb_surface,
+  CAIRO_FORMAT_ARGB32,
+  width, height);
 
hash_table_insert(wm->window_hash, window->frame_id, window);
 
@@ -967,6 +972,8 @@ weston_wm_handle_unmap_notify(struct weston_wm *wm, 
xcb_generic_event_t *event)
wl_event_source_remove(window->repaint_source);
if (window->cairo_surface)
cairo_surface_destroy(window->cairo_surface);
+   if (window->cairo_xcb_surface)
+   cairo_surface_destroy(window->cairo_xcb_surface);
 
if (window->frame_id) {
xcb_reparent_window(wm->conn, window->id, wm->wm_window, 0, 0);
@@ -1009,7 +1016,16 @@ weston_wm_window_draw_decoration(void *data)
weston_wm_window_get_frame_size(window, &width, &height);
weston_wm_window_get_child_position(window, &x, &y);
 
-   cairo_xcb_surface_set_size(window->cairo_surface, width, height);
+   if (cairo_image_surface_get_width(window->cairo_surface) != width ||
+   cairo_image_surface_get_height(window->cairo_surface) != height) {
+   cairo_surface_destroy(window->cairo_surface);
+   window->cairo_surface =
+   
cairo_surface_create_similar_image(window->cairo_xcb_surface,
+  CAIRO_FORMAT_ARGB32,
+  width, height);
+   cairo_xcb_surface_set_size(window->cairo_xcb_surface, width, 
height);
+   }
+
cr = cairo_create(window->cairo_surface);
 
if (window->fullscreen) {
@@ -1036,6 +1052,12 @@ weston_wm_window_draw_decoration(void *data)
 
cairo_destroy(cr);
 
+   cr = cairo_create(window->cairo_xcb_surface);
+   cairo_set_source_surface(cr, window->cairo_surface, 0, 0);
+   cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);  
+   cairo_paint(cr);
+   cairo_destroy(cr);
+
if (window->surface) {
pixman_region32_fini(&window->surface->pending.opaque);
if(window->has_alpha) {
-- 
1.8.1.4

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH 3/4] xwayland: Draw decoration on window manager side

2013-08-05 Thread Louis-Francis Ratté-Boulianne
 
On Wednesday, July 31, 2013 10:41 EDT, Uli Schlachter  wrote: 
 
> Hi,
> 
> On 30.07.2013 18:13, Louis-Francis Ratté-Boulianne wrote:
> > Draw everything in a cairo image surface before copying it to the XCB
> > surface. That removes the flickering visible on rpi whenever the
> > decoration were redrawn.
> > ---
> >  src/xwayland/window-manager.c | 22 --
> >  1 file changed, 20 insertions(+), 2 deletions(-)
> > 
> > diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
> > index b3c9251..57a5d99 100644
> > --- a/src/xwayland/window-manager.c
> > +++ b/src/xwayland/window-manager.c
> > @@ -97,6 +97,7 @@ struct weston_wm_window {
> > xcb_window_t id;
> > xcb_window_t frame_id;
> > cairo_surface_t *cairo_surface;
> > +   cairo_surface_t *cairo_xcb_surface;
> > struct weston_surface *surface;
> > struct shell_surface *shsurf;
> > struct wl_listener surface_destroy_listener;
> > @@ -900,12 +901,14 @@ weston_wm_handle_map_request(struct weston_wm *wm, 
> > xcb_generic_event_t *event)
> > xcb_map_window(wm->conn, map_request->window);
> > xcb_map_window(wm->conn, window->frame_id);
> >  
> > -   window->cairo_surface =
> > +   window->cairo_xcb_surface =
> > cairo_xcb_surface_create_with_xrender_format(wm->conn,
> >  wm->screen,
> >  window->frame_id,
> >  &wm->format_rgba,
> >  width, height);
> > +   window->cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
> > +   width, height);
> [...]
> 
> Why do you use an image surface for this? I would suggest to use
> cairo_surface_create_similar() instead. This might then give you an XCB 
> surface
> drawing to a temporary pixmap (but it could also be an image surface or
> something completely different).

I tried this way, but it still flickers between a black surface and the drawn 
decoration when the decorations are updated or the window is resized. It's 
still better than having each element showing up one after the other, but still 
really ugly.

Also, I was wondering..if the similar surface that has been created is a XCB 
one, is the rendering on the server side? The objective of my patch was to move 
the drawing on client side (wm) so we know when it's done and we can push it to 
the screen.

> If there is some reason for forcing image surfaces and if depending on cairo
> 1.12 is no problem, I would suggest to use 
> cairo_surface_create_similar_image()
> at least. This would make it possible for cairo to use shared memory instead 
> of
> sending all the pixels over the X11 socket.

That's seem to be the only solution that avoids any flickering while drawing 
the decoration on slow hardware (Raspberry Pi in my case). Unfortunately, there 
is a bug in Cairo < 1.12.6. So if you feel confident that we can update the 
dependency, that's the patch you should push. If not, the old patch still seems 
to be the only working solution for me.

Related cairo commit: "xcb: Clear the result of create_similar_image"
 
> And a third idea would be to use cairo_push_group(); /
> cairo_pop_group_to_source(); cairo_paint();. This would need to be done around
> the drawing code. I don't know this code and I am too lazy to look it up, but 
> if
> this works and could be done easily, this would avoid the memory usage for
> keeping the double-buffering surface around always.

That solution would have been really great to avoid the memory usage, but a 
similar problem occurs (flickering). I guess it's because the decorations are 
still rendered on server side.

Thanks for the review. If you want to see the patches I came up with to test 
the other solutions, let me know.

--
Louis-Francis

> Cheers,
> Uli
> -- 
> - He made himself, me nothing, you nothing out of the dust
> - Er machte sich mir nichts, dir nichts aus dem Staub
 
 
 
 

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] clients: Fix typo in simple-touch and simple-shm.

2013-08-05 Thread Stefan Schmidt
listenter -> listener. Better fix it now before it spreads further.

Signed-off-by: Stefan Schmidt 
---
 clients/simple-shm.c   |4 ++--
 clients/simple-touch.c |4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/clients/simple-shm.c b/clients/simple-shm.c
index f187b10..98102eb 100644
--- a/clients/simple-shm.c
+++ b/clients/simple-shm.c
@@ -294,7 +294,7 @@ shm_format(void *data, struct wl_shm *wl_shm, uint32_t 
format)
d->formats |= (1 << format);
 }
 
-struct wl_shm_listener shm_listenter = {
+struct wl_shm_listener shm_listener = {
shm_format
 };
 
@@ -314,7 +314,7 @@ registry_handle_global(void *data, struct wl_registry 
*registry,
} else if (strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry,
  id, &wl_shm_interface, 1);
-   wl_shm_add_listener(d->shm, &shm_listenter, d);
+   wl_shm_add_listener(d->shm, &shm_listener, d);
}
 }
 
diff --git a/clients/simple-touch.c b/clients/simple-touch.c
index 534c77c..9e4c60a 100644
--- a/clients/simple-touch.c
+++ b/clients/simple-touch.c
@@ -95,7 +95,7 @@ shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
touch->has_argb = 1;
 }
 
-struct wl_shm_listener shm_listenter = {
+struct wl_shm_listener shm_listener = {
shm_format
 };
 
@@ -257,7 +257,7 @@ handle_global(void *data, struct wl_registry *registry,
} else if (strcmp(interface, "wl_shm") == 0) {
touch->shm = wl_registry_bind(registry, name,
  &wl_shm_interface, 1);
-   wl_shm_add_listener(touch->shm, &shm_listenter, touch);
+   wl_shm_add_listener(touch->shm, &shm_listener, touch);
} else if (strcmp(interface, "wl_seat") == 0) {
touch->seat = wl_registry_bind(registry, name,
   &wl_seat_interface, 1);
-- 
1.7.9.5

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 8/8] evdev-touchpad: Autodetect known Sony-style touchpads

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

---
 src/evdev-touchpad.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 53de1e7..e36c2aa 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -193,7 +193,31 @@ configure_interaction_model(struct touchpad_dispatch 
*touchpad)
case TOUCHPAD_MODEL_APPLETOUCH:
touchpad->interaction_model = INTERACTION_MODEL_APPLE;
break;
+   case TOUCHPAD_MODEL_SYNAPTICS:
+   case TOUCHPAD_MODEL_ELANTECH:
+   case TOUCHPAD_MODEL_ALPS:
+   /*
+* FIXME: fallback to INTERACTION_MODEL_SIMPLE if out
+* requirements such as multitouch support or pressure
+* readings are not met.
+*/
+   touchpad->interaction_model = INTERACTION_MODEL_SONY;
+   break;
default:
+   /* Note: Chromebook Pixel also gets here because of the 
following:
+* I: Bus=0018 Vendor= Product= Version=
+* N: Name="Atmel maXTouch Touchpad"
+* P: Phys=i2c-1-004b/input0
+* S: 
Sysfs=/devices/pci:00/:00:02.0/i2c-1/1-004b/input/input9
+* U: Uniq=
+* H: Handlers=mouse1 event9
+* B: PROP=5
+* B: EV=b
+* B: KEY=e520 1 0 0 0 0
+* B: ABS=6618103
+*
+* Actually, Apple-style interaction is appropriate for 
Chromebooks.
+*/
weston_log("Found a buttonpad of unknown type, assuming 
Apple-style\n");
touchpad->interaction_model = INTERACTION_MODEL_APPLE;
break;
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 7/8] evdev-touchpad: Use multitouch for Sony touchpads

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

Track finger poritions and virtual buttons
---
 src/evdev-touchpad.c | 168 +--
 1 file changed, 149 insertions(+), 19 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 01c52aa..53de1e7 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -76,9 +76,10 @@ struct touchpad_motion {
 };
 
 enum touchpad_fingers_state {
-   TOUCHPAD_FINGERS_ONE   = (1 << 0),
-   TOUCHPAD_FINGERS_TWO   = (1 << 1),
-   TOUCHPAD_FINGERS_THREE = (1 << 2)
+   TOUCHPAD_FINGERS_NONE_YET = 1,
+   TOUCHPAD_FINGERS_ONE   = (1 << 1),
+   TOUCHPAD_FINGERS_TWO   = (1 << 2),
+   TOUCHPAD_FINGERS_THREE = (1 << 3)
 };
 
 enum fsm_event {
@@ -106,6 +107,7 @@ struct touchpad_dispatch {
int last_finger_state;
int slot;
int relevant_touch;
+   int virtual_buttons;
 
double constant_accel_factor;
double min_accel_factor;
@@ -127,6 +129,7 @@ struct touchpad_dispatch {
 
bool is_moving;
bool is_pressed;
+   bool tracking_id_changed;
} hw_abs[MAX_SLOTS + 1];
 
bool has_moved;
@@ -145,6 +148,11 @@ struct touchpad_dispatch {
int32_t center_y;
} hysteresis;
 
+   struct {
+   int32_t center_x;
+   int32_t separator_y;
+   } boundaries;
+
struct touchpad_motion motion_history[TOUCHPAD_HISTORY_LENGTH];
int motion_index;
unsigned int motion_count;
@@ -441,7 +449,7 @@ fsm_timout_handler(void *data)
 }
 
 static bool
-is_valid_touch(struct touchpad_dispatch *touchpad, int slot)
+is_valid_touch(struct touchpad_dispatch *touchpad, int slot, bool for_buttons)
 {
if (!touchpad->hw_abs[slot].x_valid)
return false;
@@ -449,6 +457,14 @@ is_valid_touch(struct touchpad_dispatch *touchpad, int 
slot)
return false;
if (!touchpad->hw_abs[slot].is_pressed)
return false;
+   if (touchpad->interaction_model == INTERACTION_MODEL_SONY) {
+   if (for_buttons &&
+   touchpad->hw_abs[slot].y < touchpad->boundaries.separator_y)
+   return false;
+   if (!for_buttons &&
+   touchpad->hw_abs[slot].y >= 
touchpad->boundaries.separator_y)
+   return false;
+   }
return true;
 }
 
@@ -466,12 +482,24 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
int last_valid_touch = -1;
int relevant_touch = touchpad->relevant_touch;
bool reset_motion = false;
+   int mt_finger_state = TOUCHPAD_FINGERS_NONE_YET;
 
-   for (i = 0; i < MAX_SLOTS; i++)
-   if (is_valid_touch(touchpad, i)) {
+   for (i = 0; i < MAX_SLOTS; i++) {
+   if (touchpad->hw_abs[i].tracking_id_changed)
+   touchpad->hw_abs[i].tracking_id_changed = false;
+   else if (is_valid_touch(touchpad, i, false)) {
touch_state |= 1 << i;
last_valid_touch = i;
+   if (mt_finger_state < TOUCHPAD_FINGERS_THREE)
+   mt_finger_state = mt_finger_state << 1;
}
+   }
+
+   if (touchpad->interaction_model == INTERACTION_MODEL_SONY) {
+   touchpad->finger_state = 0;
+   if (mt_finger_state != TOUCHPAD_FINGERS_NONE_YET)
+   touchpad->finger_state = mt_finger_state;
+   }
 
if (touch_state && !touchpad->touch_state) {
push_fsm_event(touchpad, FSM_EVENT_TOUCH);
@@ -634,13 +662,81 @@ process_absolute(struct touchpad_dispatch *touchpad,
 }
 
 static inline void
+process_absolute_sony(struct touchpad_dispatch *touchpad,
+ struct evdev_device *device,
+ struct input_event *e)
+{
+   int slot = touchpad->slot;
+   switch (e->code) {
+   case ABS_MT_SLOT:
+   slot = e->value;
+   if (slot < 0 || slot >= MAX_SLOTS)
+   slot = MAX_SLOTS;
+   touchpad->slot = slot;
+   break;
+   case ABS_MT_TRACKING_ID:
+   touchpad->hw_abs[slot].tracking_id_changed = true;
+   touchpad->hw_abs[slot].x_valid = false;
+   touchpad->hw_abs[slot].y_valid = false;
+   touchpad->hw_abs[slot].is_pressed = false;
+   touchpad->hw_abs[slot].is_moving = false;
+   break;
+   case ABS_MT_PRESSURE:
+   if (e->value > touchpad->pressure.touch_high &&
+   !touchpad->hw_abs[slot].is_pressed)
+   on_touch(touchpad, slot);
+   else if (e->value < touchpad->pressure.touch_low &&
+touchpad->hw_abs[slot].is_pressed)
+   on_release(touchpad, slot);
+   break;
+   case ABS_MT_POSIT

[PATCH 6/8] evdev-touchpad: Made hw_abs an array

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

In the non-multitouch case, the 0th entry tracks motion just as the old
scalar hw_abs. In the multitouch case, there will be one entry for each
slot, and relevant_touch is used to select which one is motion-tracked.
---
 src/evdev-touchpad.c | 146 +++
 1 file changed, 102 insertions(+), 44 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 1ed2dbb..01c52aa 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -51,6 +51,7 @@ enum touchpad_model {
 enum interaction_model {
INTERACTION_MODEL_SIMPLE = 0,
INTERACTION_MODEL_APPLE,
+   INTERACTION_MODEL_SONY,
 };
 
 struct touchpad_model_spec {
@@ -103,6 +104,8 @@ struct touchpad_dispatch {
enum interaction_model interaction_model;
int finger_state;
int last_finger_state;
+   int slot;
+   int relevant_touch;
 
double constant_accel_factor;
double min_accel_factor;
@@ -114,6 +117,7 @@ struct touchpad_dispatch {
struct wl_event_source *timer_source;
} fsm;
 
+   /* the extra dummy slot is used for out-of-range slots reported by 
mtdev */
struct {
int32_t x;
int32_t y;
@@ -123,7 +127,7 @@ struct touchpad_dispatch {
 
bool is_moving;
bool is_pressed;
-   } hw_abs;
+   } hw_abs[MAX_SLOTS + 1];
 
bool has_moved;
uint16_t touch_state;
@@ -436,29 +440,80 @@ fsm_timout_handler(void *data)
return 1;
 }
 
+static bool
+is_valid_touch(struct touchpad_dispatch *touchpad, int slot)
+{
+   if (!touchpad->hw_abs[slot].x_valid)
+   return false;
+   if (!touchpad->hw_abs[slot].y_valid)
+   return false;
+   if (!touchpad->hw_abs[slot].is_pressed)
+   return false;
+   return true;
+}
+
 static void
 touchpad_update_state(struct touchpad_dispatch *touchpad, uint32_t time)
 {
+   int i;
int motion_index;
int center_x, center_y;
double dx = 0.0, dy = 0.0;
 
/* For multitouch case, this will be a bitmask */
-   uint16_t touch_state = touchpad->hw_abs.is_pressed;
 
-   if (touch_state && !touchpad->touch_state)
+   uint16_t touch_state = 0;
+   int last_valid_touch = -1;
+   int relevant_touch = touchpad->relevant_touch;
+   bool reset_motion = false;
+
+   for (i = 0; i < MAX_SLOTS; i++)
+   if (is_valid_touch(touchpad, i)) {
+   touch_state |= 1 << i;
+   last_valid_touch = i;
+   }
+
+   if (touch_state && !touchpad->touch_state) {
push_fsm_event(touchpad, FSM_EVENT_TOUCH);
+   reset_motion = true;
+   }
+
if (!touch_state && touchpad->touch_state) {
push_fsm_event(touchpad, FSM_EVENT_RELEASE);
touchpad->has_moved = false;
+   reset_motion = true;
}
 
+   if (touch_state && touchpad->touch_state &&
+   !(touch_state & touchpad->touch_state)) {
+   push_fsm_event(touchpad, FSM_EVENT_RELEASE);
+   push_fsm_event(touchpad, FSM_EVENT_TOUCH);
+   touchpad->has_moved = false;
+   reset_motion = true;
+   }
+
+
+   if (relevant_touch != -1 && !(touch_state & (1 << relevant_touch))) {
+   reset_motion = true;
+   relevant_touch = -1;
+   }
+   if (relevant_touch == -1)
+   relevant_touch = last_valid_touch;
+
+   if (touchpad->last_finger_state != touchpad->finger_state)
+   reset_motion = true;
+
touchpad->touch_state = touch_state;
+   touchpad->last_finger_state = touchpad->finger_state;
+   touchpad->relevant_touch = relevant_touch;
 
-   if (touchpad->last_finger_state != touchpad->finger_state) {
+   if (reset_motion) {
touchpad->motion_count = 0;
-   touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
-   touchpad->hw_abs.is_moving = false;
+   if (touchpad->interaction_model != INTERACTION_MODEL_SONY) {
+   touchpad->hw_abs[0].x_valid = false;
+   touchpad->hw_abs[0].y_valid = false;
+   touchpad->hw_abs[0].is_moving = false;
+   }
 
touchpad->last_finger_state = touchpad->finger_state;
 
@@ -466,37 +521,36 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
 
return;
}
-   touchpad->last_finger_state = touchpad->finger_state;
 
-   if (!touchpad->hw_abs.x_valid || !touchpad->hw_abs.y_valid)
+   if (relevant_touch == -1)
return;
 
-   if (!touchpad->hw_abs.is_moving)
+   if (!touchpad->hw_abs[relevant_touch].is_moving)
return;
 
/* Avoid noice by moving center only when delta reaches a threshold
  

[PATCH 5/8] evdev-touchpad: Introduced the notion of interaction model

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

Different hardware can be interacted with differently. So far, there is
some code for simple trackpads and for buttonpads. For buttonpads,
currently the FSM is disabled and the right click is emulated through
two-finger click. This is OK for Apple hardware, but not for Sony. A
Sony-specific interaction model will be introduced later.
---
 src/evdev-touchpad.c | 47 ++-
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index a9b21b8..1ed2dbb 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -45,7 +45,12 @@ enum touchpad_model {
TOUCHPAD_MODEL_SYNAPTICS,
TOUCHPAD_MODEL_ALPS,
TOUCHPAD_MODEL_APPLETOUCH,
-   TOUCHPAD_MODEL_ELANTECH
+   TOUCHPAD_MODEL_ELANTECH,
+};
+
+enum interaction_model {
+   INTERACTION_MODEL_SIMPLE = 0,
+   INTERACTION_MODEL_APPLE,
 };
 
 struct touchpad_model_spec {
@@ -95,6 +100,7 @@ struct touchpad_dispatch {
struct evdev_device *device;
 
enum touchpad_model model;
+   enum interaction_model interaction_model;
int finger_state;
int last_finger_state;
 
@@ -103,8 +109,6 @@ struct touchpad_dispatch {
double max_accel_factor;
 
struct {
-   bool enable;
-
struct wl_array events;
enum fsm_state state;
struct wl_event_source *timer_source;
@@ -163,6 +167,28 @@ get_touchpad_model(struct evdev_device *device)
 }
 
 static void
+configure_interaction_model(struct touchpad_dispatch *touchpad)
+{
+   unsigned long prop_bits[INPUT_PROP_MAX];
+
+   touchpad->interaction_model = INTERACTION_MODEL_SIMPLE;
+
+   ioctl(touchpad->device->fd, EVIOCGPROP(sizeof(prop_bits)), prop_bits);
+   if (!TEST_BIT(prop_bits, INPUT_PROP_BUTTONPAD))
+   return;
+
+   switch (touchpad->model) {
+   case TOUCHPAD_MODEL_APPLETOUCH:
+   touchpad->interaction_model = INTERACTION_MODEL_APPLE;
+   break;
+   default:
+   weston_log("Found a buttonpad of unknown type, assuming 
Apple-style\n");
+   touchpad->interaction_model = INTERACTION_MODEL_APPLE;
+   break;
+   }
+}
+
+static void
 configure_touchpad_pressure(struct touchpad_dispatch *touchpad,
int32_t pressure_min, int32_t pressure_max)
 {
@@ -293,7 +319,7 @@ process_fsm_events(struct touchpad_dispatch *touchpad, 
uint32_t time)
enum fsm_event *pevent;
enum fsm_event event;
 
-   if (!touchpad->fsm.enable)
+   if (touchpad->interaction_model == INTERACTION_MODEL_APPLE)
return;
 
if (touchpad->fsm.events.size == 0)
@@ -387,7 +413,7 @@ push_fsm_event(struct touchpad_dispatch *touchpad,
 {
enum fsm_event *pevent;
 
-   if (!touchpad->fsm.enable)
+   if (touchpad->interaction_model == INTERACTION_MODEL_APPLE)
return;
 
pevent = wl_array_add(&touchpad->fsm.events, sizeof event);
@@ -578,7 +604,8 @@ process_key(struct touchpad_dispatch *touchpad,
case BTN_FORWARD:
case BTN_BACK:
case BTN_TASK:
-   if (!touchpad->fsm.enable && e->code == BTN_LEFT &&
+   if (touchpad->interaction_model == INTERACTION_MODEL_APPLE &&
+   e->code == BTN_LEFT &&
touchpad->finger_state == TOUCHPAD_FINGERS_TWO)
code = BTN_RIGHT;
else
@@ -667,12 +694,9 @@ touchpad_init(struct touchpad_dispatch *touchpad,
struct weston_motion_filter *accel;
struct wl_event_loop *loop;
 
-   unsigned long prop_bits[INPUT_PROP_MAX];
struct input_absinfo absinfo;
unsigned long abs_bits[NBITS(ABS_MAX)];
 
-   bool has_buttonpad;
-
double width;
double height;
double diagonal;
@@ -682,9 +706,7 @@ touchpad_init(struct touchpad_dispatch *touchpad,
 
/* Detect model */
touchpad->model = get_touchpad_model(device);
-
-   ioctl(device->fd, EVIOCGPROP(sizeof(prop_bits)), prop_bits);
-   has_buttonpad = TEST_BIT(prop_bits, INPUT_PROP_BUTTONPAD);
+   configure_interaction_model(touchpad);
 
/* Configure pressure */
ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits);
@@ -746,7 +768,6 @@ touchpad_init(struct touchpad_dispatch *touchpad,
}
 
/* Configure */
-   touchpad->fsm.enable = !has_buttonpad;
 
return 0;
 }
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 4/8] evdev-touchpad: Don't push FSM events from process_absolute

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

In the multitouch case on Sony trackpads, not all touches are valid.
However, the information needed to filter out invalid touches is
consistent only on the SYN_REPORT event.
---
 src/evdev-touchpad.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index aafa705..a9b21b8 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -122,6 +122,7 @@ struct touchpad_dispatch {
} hw_abs;
 
bool has_moved;
+   uint16_t touch_state;
 
int has_pressure;
struct {
@@ -416,6 +417,18 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
int center_x, center_y;
double dx = 0.0, dy = 0.0;
 
+   /* For multitouch case, this will be a bitmask */
+   uint16_t touch_state = touchpad->hw_abs.is_pressed;
+
+   if (touch_state && !touchpad->touch_state)
+   push_fsm_event(touchpad, FSM_EVENT_TOUCH);
+   if (!touch_state && touchpad->touch_state) {
+   push_fsm_event(touchpad, FSM_EVENT_RELEASE);
+   touchpad->has_moved = false;
+   }
+
+   touchpad->touch_state = touch_state;
+
if (touchpad->last_finger_state != touchpad->finger_state) {
touchpad->motion_count = 0;
touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
@@ -498,19 +511,14 @@ static void
 on_touch(struct touchpad_dispatch *touchpad)
 {
touchpad->hw_abs.is_pressed = true;
-
-   push_fsm_event(touchpad, FSM_EVENT_TOUCH);
 }
 
 static void
 on_release(struct touchpad_dispatch *touchpad)
 {
-
-   touchpad->has_moved = touchpad->hw_abs.is_pressed = false;
-   touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
+   touchpad->hw_abs.is_pressed = false;
touchpad->hw_abs.is_moving = false;
-
-   push_fsm_event(touchpad, FSM_EVENT_RELEASE);
+   touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
 }
 
 static inline void
@@ -721,6 +729,7 @@ touchpad_init(struct touchpad_dispatch *touchpad,
touchpad->hw_abs.is_pressed = false;
touchpad->hw_abs.is_moving = false;
touchpad->has_moved = false;
+   touchpad->touch_state = 0;
 
touchpad->last_finger_state = 0;
touchpad->finger_state = 0;
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 3/8] evdev-touchpad: Moved has_moved out of hw_abs

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

For FSM purposes, it is a global property of a touchpad, not a property
of each touch point.
---
 src/evdev-touchpad.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 6646896..aafa705 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -117,11 +117,12 @@ struct touchpad_dispatch {
bool x_valid;
bool y_valid;
 
-   bool has_moved;
bool is_moving;
bool is_pressed;
} hw_abs;
 
+   bool has_moved;
+
int has_pressure;
struct {
int32_t touch_low;
@@ -484,9 +485,9 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
}
}
 
-   if (!touchpad->hw_abs.has_moved &&
+   if (!touchpad->has_moved &&
((int)dx || (int)dy)) {
-   touchpad->hw_abs.has_moved = true;
+   touchpad->has_moved = true;
push_fsm_event(touchpad, FSM_EVENT_MOTION);
}
 
@@ -505,7 +506,7 @@ static void
 on_release(struct touchpad_dispatch *touchpad)
 {
 
-   touchpad->hw_abs.has_moved = touchpad->hw_abs.is_pressed = false;
+   touchpad->has_moved = touchpad->hw_abs.is_pressed = false;
touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
touchpad->hw_abs.is_moving = false;
 
@@ -719,7 +720,7 @@ touchpad_init(struct touchpad_dispatch *touchpad,
touchpad->hw_abs.y_valid = false;
touchpad->hw_abs.is_pressed = false;
touchpad->hw_abs.is_moving = false;
-   touchpad->hw_abs.has_moved = false;
+   touchpad->has_moved = false;
 
touchpad->last_finger_state = 0;
touchpad->finger_state = 0;
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/8] evdev-touchpad: Split the reset logic

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

In old code, the reset both cleared the (global) motion history and
invalidated some state associated with (the) touch point. In the
multitouch case, there is still the global motion history that may need
to be cleared, and there are potentially many touch points that are
certainly not appropriate to invalidate at once. So copy-paste the
logic in order to be able to separate these two kinds of actions as
needed.
---
 src/evdev-touchpad.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 35be921..6646896 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -102,8 +102,6 @@ struct touchpad_dispatch {
double min_accel_factor;
double max_accel_factor;
 
-   int reset;
-
struct {
bool enable;
 
@@ -417,13 +415,10 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
int center_x, center_y;
double dx = 0.0, dy = 0.0;
 
-   if (touchpad->reset ||
-   touchpad->last_finger_state != touchpad->finger_state) {
-   touchpad->reset = 0;
+   if (touchpad->last_finger_state != touchpad->finger_state) {
touchpad->motion_count = 0;
touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
touchpad->hw_abs.is_moving = false;
-   /* XXX what about is_pressed? */
 
touchpad->last_finger_state = touchpad->finger_state;
 
@@ -511,7 +506,8 @@ on_release(struct touchpad_dispatch *touchpad)
 {
 
touchpad->hw_abs.has_moved = touchpad->hw_abs.is_pressed = false;
-   touchpad->reset = 1;
+   touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
+   touchpad->hw_abs.is_moving = false;
 
push_fsm_event(touchpad, FSM_EVENT_RELEASE);
 }
@@ -589,7 +585,11 @@ process_key(struct touchpad_dispatch *touchpad,
case BTN_TOOL_AIRBRUSH:
case BTN_TOOL_MOUSE:
case BTN_TOOL_LENS:
-   touchpad->reset = 1;
+   /* The reset-logic below was copied without understanding
+* and may be inappropriate */
+   touchpad->motion_count = 0;
+   touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
+   touchpad->hw_abs.is_moving = false;
break;
case BTN_TOOL_FINGER:
if (e->value)
@@ -711,8 +711,6 @@ touchpad_init(struct touchpad_dispatch *touchpad,
touchpad->filter = accel;
 
/* Setup initial state */
-   touchpad->reset = 1;
-
memset(touchpad->motion_history, 0, sizeof touchpad->motion_history);
touchpad->motion_index = 0;
touchpad->motion_count = 0;
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 1/8] evdev-touchpad: Replaced flags with boolean variabes

2013-08-05 Thread Alexander E. Patrakov
From: "Alexander E. Patrakov" 

...and put them inside hw_abs, because they will need to be made
per-touch-point later.
---
 src/evdev-touchpad.c | 78 +---
 1 file changed, 32 insertions(+), 46 deletions(-)

diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c
index 53300ce..35be921 100644
--- a/src/evdev-touchpad.c
+++ b/src/evdev-touchpad.c
@@ -48,14 +48,6 @@ enum touchpad_model {
TOUCHPAD_MODEL_ELANTECH
 };
 
-enum touchpad_event {
-   TOUCHPAD_EVENT_NONE = 0,
-   TOUCHPAD_EVENT_ABSOLUTE_ANY = (1 << 0),
-   TOUCHPAD_EVENT_ABSOLUTE_X   = (1 << 1),
-   TOUCHPAD_EVENT_ABSOLUTE_Y   = (1 << 2),
-   TOUCHPAD_EVENT_REPORT   = (1 << 3)
-};
-
 struct touchpad_model_spec {
short vendor;
short product;
@@ -70,12 +62,6 @@ static struct touchpad_model_spec touchpad_spec_table[] = {
{0x, 0x, TOUCHPAD_MODEL_UNKNOWN}
 };
 
-enum touchpad_state {
-   TOUCHPAD_STATE_NONE  = 0,
-   TOUCHPAD_STATE_TOUCH = (1 << 0),
-   TOUCHPAD_STATE_MOVE  = (1 << 1)
-};
-
 #define TOUCHPAD_HISTORY_LENGTH 4
 
 struct touchpad_motion {
@@ -109,7 +95,6 @@ struct touchpad_dispatch {
struct evdev_device *device;
 
enum touchpad_model model;
-   unsigned int state;
int finger_state;
int last_finger_state;
 
@@ -117,9 +102,6 @@ struct touchpad_dispatch {
double min_accel_factor;
double max_accel_factor;
 
-   unsigned int event_mask;
-   unsigned int event_mask_filter;
-
int reset;
 
struct {
@@ -133,6 +115,13 @@ struct touchpad_dispatch {
struct {
int32_t x;
int32_t y;
+
+   bool x_valid;
+   bool y_valid;
+
+   bool has_moved;
+   bool is_moving;
+   bool is_pressed;
} hw_abs;
 
int has_pressure;
@@ -432,9 +421,9 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
touchpad->last_finger_state != touchpad->finger_state) {
touchpad->reset = 0;
touchpad->motion_count = 0;
-   touchpad->event_mask = TOUCHPAD_EVENT_NONE;
-   touchpad->event_mask_filter =
-   TOUCHPAD_EVENT_ABSOLUTE_X | TOUCHPAD_EVENT_ABSOLUTE_Y;
+   touchpad->hw_abs.x_valid = touchpad->hw_abs.y_valid = false;
+   touchpad->hw_abs.is_moving = false;
+   /* XXX what about is_pressed? */
 
touchpad->last_finger_state = touchpad->finger_state;
 
@@ -444,18 +433,12 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
}
touchpad->last_finger_state = touchpad->finger_state;
 
-   if (!(touchpad->event_mask & TOUCHPAD_EVENT_REPORT))
+   if (!touchpad->hw_abs.x_valid || !touchpad->hw_abs.y_valid)
return;
-   else
-   touchpad->event_mask &= ~TOUCHPAD_EVENT_REPORT;
 
-   if ((touchpad->event_mask & touchpad->event_mask_filter) !=
-   touchpad->event_mask_filter)
+   if (!touchpad->hw_abs.is_moving)
return;
 
-   touchpad->event_mask_filter = TOUCHPAD_EVENT_ABSOLUTE_ANY;
-   touchpad->event_mask = 0;
-
/* Avoid noice by moving center only when delta reaches a threshold
 * distance from the old center. */
if (touchpad->motion_count > 0) {
@@ -506,9 +489,9 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
}
}
 
-   if (!(touchpad->state & TOUCHPAD_STATE_MOVE) &&
+   if (!touchpad->hw_abs.has_moved &&
((int)dx || (int)dy)) {
-   touchpad->state |= TOUCHPAD_STATE_MOVE;
+   touchpad->hw_abs.has_moved = true;
push_fsm_event(touchpad, FSM_EVENT_MOTION);
}
 
@@ -518,7 +501,7 @@ touchpad_update_state(struct touchpad_dispatch *touchpad, 
uint32_t time)
 static void
 on_touch(struct touchpad_dispatch *touchpad)
 {
-   touchpad->state |= TOUCHPAD_STATE_TOUCH;
+   touchpad->hw_abs.is_pressed = true;
 
push_fsm_event(touchpad, FSM_EVENT_TOUCH);
 }
@@ -527,8 +510,8 @@ static void
 on_release(struct touchpad_dispatch *touchpad)
 {
 
+   touchpad->hw_abs.has_moved = touchpad->hw_abs.is_pressed = false;
touchpad->reset = 1;
-   touchpad->state &= ~(TOUCHPAD_STATE_MOVE | TOUCHPAD_STATE_TOUCH);
 
push_fsm_event(touchpad, FSM_EVENT_RELEASE);
 }
@@ -541,25 +524,25 @@ process_absolute(struct touchpad_dispatch *touchpad,
switch (e->code) {
case ABS_PRESSURE:
if (e->value > touchpad->pressure.touch_high &&
-   !(touchpad->state & TOUCHPAD_STATE_TOUCH))
+   !touchpad->hw_abs.is_pressed)
on_touch(touchpad);
else if (e->value < touchpad->pressure.touch_low &&
-touchpad->state & TOUCHPAD_STATE_TOUCH)
+  

[RFC] weston: Sony clickpad support

2013-08-05 Thread Alexander E. Patrakov
This patch series adds support to weston for a special type of touchpads
found in some laptops. These touchpads contain one physical button that
covers the whole surface of the touchpad. Unlike the well-known Apple
touchpad, these touchpads have markings painted on them, that designate
virtual button areas. So the user interaction is quite different from one
gets from Apple touchpads.

+---+
|\/\/\/\/\/\/\/\/\/\/\/\/\/\|
|/\/\/\/\/\/\/\/\/\/\/\/\/\/|
|\/\/\/\/\/\/\/\/\/\/\/\/\/\|
|/\  Cursor-moving area  /\/|
|\/\/\/\/\/\/\/\/\/\/\/\/\/\|
|/\/\/\/\/\/\/\/\/\/\/\/\/\/|
|\/\/\/\/\/\/\/\/\/\/\/\/\/\|
+---+  <-- painted line
|   Left  |   Right |
|  virtual|  virtual|
|  button |  button |
+-+-+
  ^
  |
painted line

E.g., currently, in order to get a right-click on such "clickpad", one has
to click anywhere with two fingers. This is, however, inappropriate for
touchpads I am talking about. See: one needs to drag something, he places a
finger on the upper part of the touchpad surface (on the part of surface
designated for moving the cursor), then places another finger into the
left half of the button area, clicks with the intention to move the first
finger. However, what he currently gets is a right-click. Also, if one
wants to make a right click, he places his finger into the right half of
the button area, clicks, but currently gets a left click. In other words,
the touchpad is unusable for users that are accustomed to the way the
interaction with the touchpad is done in Windows.

I have implemented the interaction model that looks more like what one
gets in Windows. In order to do so, I had to refactor the existing code a
bit and add support for multitouch protocol to evdev-touchpad.c.

Tested all of this on my Sony VAIO VPC-Z23A4R laptop. Here is what works:

 * Moving the cursor by moving the finger in the cursor-moving area of
   the touchpad.
 * Not moving the cursor if one moves the finger in the virtual button
   area.
 * Tap-to-click.
 * Tap-and-drag gesture (unreliable).
 * Left and right virtual buttons.
 * Dragging, as explaining above.
 * Insensitivity to bad clicks (those outside the designated button area).
 * Two-finger scrolling.

...i.e. the touchpad is now quite usable. Zoom gestures are not implemented,
though.

I have also added autodetection of the interaction model based on the
laptops with clickpads that GUADEC participants brought with themselves.
Result: the current interaction model is valid only for Apple and Chromebook
Pixel laptops, for everyone else the alternative model in this patch is
needed because there are buttons painted on the clickpad.

-- 
Alexander E. Patrakov


___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel