Re: [PATCH libinput 5/8] evdev: Early out during configure if not using fallback dispatch

2014-07-16 Thread Peter Hutterer
On Wed, Jul 16, 2014 at 10:39:10PM +0200, Jonas Ådahl wrote:
> The feature set configured otherwise would not work anyway as it
> would need using the fallback dispatch to function.
> 
> Signed-off-by: Jonas Ådahl 
> ---
>  src/evdev.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index f980812..fec24f5 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -700,9 +700,11 @@ evdev_configure_device(struct evdev_device *device)
>   !libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN) &&
>   (has_abs || has_mt)) {
>   device->dispatch = evdev_mt_touchpad_create(device);
> + device->seat_caps |= EVDEV_DEVICE_POINTER;
>   log_info(libinput,
>"input device '%s', %s is a touchpad\n",
>device->devname, device->devnode);
> + return device->dispatch == NULL ? -1 : 0;

for something that is a touchpad with extra keys you're losing the keyboard
seat_cap here. same for touch, which iirc you can get for wireless receivers
where you may have more than one device multiplexed. which the touchpad code
probably won't handle yet anyway, but still.

Cheers,
   Peter

>   }
>   for (i = KEY_ESC; i < KEY_MAX; i++) {
>   if (i >= BTN_MISC && i < KEY_OK)
> -- 
> 1.8.5.1
 
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH libinput 2/8] test: Use only one test device for some udev and path tests

2014-07-16 Thread Peter Hutterer
On Wed, Jul 16, 2014 at 10:39:07PM +0200, Jonas Ådahl wrote:
> Some tests in test/path.c and test/udev.c are not dependent on
> device behaviour but rather managing of device lifetime etc. Run those
> tests only once with only one device, resulting more or less the same
> code coverage but shorter run time.
> 
> Signed-off-by: Jonas Ådahl 

hmm, I think instead of litest_add_once which is pretty much unpredictable
maybe just add a litest_add_for_device() call where you can pass the enum
litest_device_type in. That way you get the same benefits as your patch
here, with the benefit of knowing which device the test runs for on any
given system.

so instad of 
litest_add_once("udev:suspend", udev_double_suspend, LITEST_ANY, 
LITEST_ANY);
you have
litest_add_for_device("udev:suspend", udev_double_suspend, 
LITEST_SYNAPTICS_CLICKPAD);

Cheers,
   Peter

> ---
>  test/litest.c | 65 
> ++-
>  test/litest.h |  3 +++
>  test/path.c   | 13 ++--
>  test/udev.c   | 15 +++---
>  4 files changed, 65 insertions(+), 31 deletions(-)
> 
> diff --git a/test/litest.c b/test/litest.c
> index adcbf3e..b64c7e3 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -151,25 +151,33 @@ litest_add_tcase_no_device(struct suite *suite, void 
> *func)
>  static void
>  litest_add_tcase(struct suite *suite, void *func,
>enum litest_device_feature required,
> -  enum litest_device_feature excluded)
> +  enum litest_device_feature excluded,
> +  int num)
>  {
>   struct litest_test_device **dev = devices;
>  
> + if (num == 0)
> + return;
> +
>   if (required == LITEST_DISABLE_DEVICE &&
>   excluded == LITEST_DISABLE_DEVICE) {
>   litest_add_tcase_no_device(suite, func);
> - } else if (required != LITEST_ANY || excluded != LITEST_ANY) {
> - while (*dev) {
> - if (((*dev)->features & required) == required &&
> - ((*dev)->features & excluded) == 0)
> - litest_add_tcase_for_device(suite, func, *dev);
> - dev++;
> - }
> - } else {
> - while (*dev) {
> + return;
> + }
> +
> + while (*dev) {
> + if ((required == LITEST_ANY && excluded == LITEST_ANY) ||
> + (((*dev)->features & required) == required &&
> +  ((*dev)->features & excluded) == 0)) {
>   litest_add_tcase_for_device(suite, func, *dev);
> - dev++;
> +
> + if (num != -1) {
> + num--;
> + if (num == 0)
> + break;
> + }
>   }
> + dev++;
>   }
>  }
>  
> @@ -179,11 +187,12 @@ litest_add_no_device(const char *name, void *func)
>   litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
>  }
>  
> -void
> -litest_add(const char *name,
> -void *func,
> -enum litest_device_feature required,
> -enum litest_device_feature excluded)
> +static void
> +litest_add_common(const char *name,
> +   void *func,
> +   enum litest_device_feature required,
> +   enum litest_device_feature excluded,
> +   int num_devices)
>  {
>   struct suite *s;
>  
> @@ -192,7 +201,9 @@ litest_add(const char *name,
>  
>   list_for_each(s, &all_tests, node) {
>   if (strcmp(s->name, name) == 0) {
> - litest_add_tcase(s, func, required, excluded);
> + litest_add_tcase(s, func,
> +  required, excluded,
> +  num_devices);
>   return;
>   }
>   }
> @@ -203,7 +214,25 @@ litest_add(const char *name,
>  
>   list_init(&s->tests);
>   list_insert(&all_tests, &s->node);
> - litest_add_tcase(s, func, required, excluded);
> + litest_add_tcase(s, func, required, excluded, num_devices);
> +}
> +
> +void
> +litest_add(const char *name,
> +void *func,
> +enum litest_device_feature required,
> +enum litest_device_feature excluded)
> +{
> + litest_add_common(name, func, required, excluded, -1);
> +}
> +
> +void
> +litest_add_once(const char *name,
> + void *func,
> + enum litest_device_feature required,
> + enum litest_device_feature excluded)
> +{
> + litest_add_common(name, func, required, excluded, 1);
>  }
>  
>  static int
> diff --git a/test/litest.h b/test/litest.h
> index 3e75dd5..b66a74f 100644
> --- a/test/litest.h
> +++ b/test/litest.h
> @@ -74,6 +74,9 @@ struct libinput *litest_create_context(void);
>  void litest_add(const char *name, void *func,
>   enum litest_device_feature required_feature,
>   enu

Re: [PATCH libinput 7/8] evdev: Release still pressed keys/buttons when removing device

2014-07-16 Thread Peter Hutterer
On Wed, Jul 16, 2014 at 10:39:12PM +0200, Jonas Ådahl wrote:
> Keep track of pressed keys and buttons in a bitmask array and iterate
> through it on device removal releasing every still pressed key.

fwiw, the kernel should release all keys on disconnect these days, but for
the manual removal it's necessary.

> This commit enables _GNU_SOURCE features in evdev.c, more specifically
> static_assert(). This is supported by gcc 4.6 and above, but is not part
> of the C standard until C11. configure will fail if static_assert()
> doesn't work whith _GNU_SOURCE defined.
> 
> Signed-off-by: Jonas Ådahl 
> ---
>  configure.ac|  11 +
>  src/evdev.c | 132 
> ++--
>  src/evdev.h |  14 ++
>  test/keyboard.c | 118 ++
>  test/pointer.c  |  91 ++
>  5 files changed, 362 insertions(+), 4 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index fd402e2..e35fff6 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -67,6 +67,17 @@ fi
>  AC_SUBST(GCC_CFLAGS)
>  AC_SUBST(GCC_CXXFLAGS)
>  
> +AC_MSG_CHECKING([whether static_assert() is supported])
> +AC_COMPILE_IFELSE(
> + [AC_LANG_SOURCE([[#define _GNU_SOURCE
> +   #include 
> +   static_assert(1, "Test");
> +   ]])],
> + [have_static_assert=1
> +  AC_MSG_RESULT([yes])],
> + [have_static_assert=0
> +  AC_MSG_ERROR([no built-in static_assert])])

we don't seem to be using have_static_assert anywhere.

> +
>  AC_PATH_PROG(DOXYGEN, [doxygen])
>  if test "x$DOXYGEN" = "x"; then
>   AC_MSG_WARN([doxygen not found - required for documentation])
> diff --git a/src/evdev.c b/src/evdev.c
> index c031258..3fb5ab4 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -21,6 +21,8 @@
>   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
>  
> +#define _GNU_SOURCE
> +
>  #include "config.h"
>  
>  #include 
> @@ -47,6 +49,87 @@ enum evdev_key_type {
>   EVDEV_KEY_TYPE_BUTTON,
>  };
>  
> +static void
> +get_key_index_and_bit(int code, int *index, int *bit)
> +{
> + static_assert((KEY_CNT % 64) == 0, "KEY_CNT not aligned to 64");

we could just use NLONGS and LONG_BITS from libevdev. not that I'm against
static_assert but using the same macros across the board makes things a bit
easier.

> +
> + *index = code / 64;
> + *bit = code % 64;
> +}
> +
> +static int
> +get_key_state(struct evdev_device *device, int code)
> +{
> + int index = 0;
> + int bit = 0;
> +
> + get_key_index_and_bit(code, &index, &bit);
> + return !!(device->key_mask[index] & (1ULL << bit));
> +}
> +
> +static void
> +set_key_state(struct evdev_device *device, int code, int pressed)
> +{
> + int index = 0;
> + int bit = 0;
> +
> + get_key_index_and_bit(code, &index, &bit);
> +
> + if (pressed)
> + device->key_mask[index] |= (1ULL << bit);
> + else
> + device->key_mask[index] &= ~(1ULL << bit);
> +}

I think it'd be easier to use bit_is_set/set_bit/clear_bit helper functions
like in 812ea542e7023c4a16c02a0c2264fb873d34abe4 on the tablet-support
branch? those came from libevdev which handles longs, so just copying the
ones from libevdev-util.h and renaming them to longbit_is_set, etc. would be
the best approach here IMO.

> +
> +void
> +evdev_keyboard_notify_key(struct evdev_device *device,
> +   uint32_t time,
> +   int key,
> +   enum libinput_key_state state)
> +{
> + struct libinput *libinput = device->base.seat->libinput;
> +
> + if ((state == LIBINPUT_KEY_STATE_PRESSED &&
> +  get_key_state(device, key) != 0) ||
> + (state == LIBINPUT_KEY_STATE_RELEASED &&
> +  get_key_state(device, key) != 1)) {

I'd prefer a boolean key_is_down() instead of get_state, especially since we're
not the LIBINPUT_KEY_STATE enums here. but given get_key_state is only used
here it'd be even easier to return the enum from get_key_state and 
check for state != get_key_state directly.

> + log_bug_kernel(
> + libinput,
> + "%s: Driver sent multiple (0x%x) pressed/released",
> + device->devnode, key);

use libevdev_event_code_get_name(device->evdev, EV_KEY, key)

> + return;
> + }
> +
> + set_key_state(device, key, state == LIBINPUT_KEY_STATE_PRESSED);

just pass the enum through and let set_key_state handle it, much easier to
read

> +
> + keyboard_notify_key(&device->base, time, key, state);
> +}
> +
> +void
> +evdev_pointer_notify_button(struct evdev_device *device,
> + uint32_t time,
> + int button,
> + enum libinput_button_state state)
> +{
> + struct libinput *libinput = device->base.seat->libinput;
> +
> + if ((state == LIBINPUT_BUTTON_STATE_

Re: [PATCH libinput 1/8] test/path: Avoid creating ignored test devices

2014-07-16 Thread Peter Hutterer
On Wed, Jul 16, 2014 at 10:39:06PM +0200, Jonas Ådahl wrote:
> Some tests doesn't use or doesn't need to use the test device
> automatically created when adding a test case for certain types of
> devices. For these tests, to shorten test run time, don't create the
> test devices that would be ignored.
> 
> Signed-off-by: Jonas Ådahl 


Patches 1, 3, 4, 6, 8 are
Reviewed-by: Peter Hutterer 

see the in-line comments for the others.

Cheers,
   Peter


> ---
>  test/path.c | 30 +++---
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/test/path.c b/test/path.c
> index 99b474e..9cc5b04 100644
> --- a/test/path.c
> +++ b/test/path.c
> @@ -244,12 +244,11 @@ END_TEST
>  
>  START_TEST(path_add_invalid_path)
>  {
> - struct litest_device *dev = litest_current_device();
> - struct libinput *li = dev->libinput;
> + struct libinput *li;
>   struct libinput_event *event;
>   struct libinput_device *device;
>  
> - litest_drain_events(li);
> + li = litest_create_context();
>  
>   device = libinput_path_add_device(li, "/tmp/");
>   ck_assert(device == NULL);
> @@ -258,6 +257,8 @@ START_TEST(path_add_invalid_path)
>  
>   while ((event = libinput_get_event(li)))
>   ck_abort();
> +
> + libinput_unref(li);
>  }
>  END_TEST
>  
> @@ -798,24 +799,23 @@ END_TEST
>  
>  int main (int argc, char **argv) {
>  
> - litest_add("path:create", path_create_NULL, LITEST_ANY, LITEST_ANY);
> - litest_add("path:create", path_create_invalid, LITEST_ANY, LITEST_ANY);
> - litest_add("path:create", path_create_destroy, LITEST_ANY, LITEST_ANY);
> - litest_add("path:suspend", path_suspend, LITEST_ANY, LITEST_ANY);
> - litest_add("path:suspend", path_double_suspend, LITEST_ANY, LITEST_ANY);
> - litest_add("path:suspend", path_double_resume, LITEST_ANY, LITEST_ANY);
> - litest_add("path:suspend", path_add_device_suspend_resume, LITEST_ANY, 
> LITEST_ANY);
> - litest_add("path:suspend", path_add_device_suspend_resume_fail, 
> LITEST_ANY, LITEST_ANY);
> - litest_add("path:suspend", 
> path_add_device_suspend_resume_remove_device, LITEST_ANY, LITEST_ANY);
> + litest_add_no_device("path:create", path_create_NULL);
> + litest_add_no_device("path:create", path_create_invalid);
> + litest_add_no_device("path:create", path_create_destroy);
> + litest_add_no_device("path:suspend", path_suspend);
> + litest_add_no_device("path:suspend", path_double_suspend);
> + litest_add_no_device("path:suspend", path_double_resume);
> + litest_add_no_device("path:suspend", path_add_device_suspend_resume);
> + litest_add_no_device("path:suspend", 
> path_add_device_suspend_resume_fail);
> + litest_add_no_device("path:suspend", 
> path_add_device_suspend_resume_remove_device);
>   litest_add("path:seat events", path_added_seat, LITEST_ANY, LITEST_ANY);
>   litest_add("path:device events", path_added_device, LITEST_ANY, 
> LITEST_ANY);
>   litest_add("path:device events", path_device_sysname, LITEST_ANY, 
> LITEST_ANY);
>   litest_add("path:device events", path_add_device, LITEST_ANY, 
> LITEST_ANY);
> - litest_add("path:device events", path_add_invalid_path, LITEST_ANY, 
> LITEST_ANY);
> + litest_add_no_device("path:device events", path_add_invalid_path);
>   litest_add("path:device events", path_remove_device, LITEST_ANY, 
> LITEST_ANY);
>   litest_add("path:device events", path_double_remove_device, LITEST_ANY, 
> LITEST_ANY);
> - litest_add("path:seat", path_seat_recycle,
> -LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
> + litest_add_no_device("path:seat", path_seat_recycle);
>  
>   return litest_run(argc, argv);
>  }
> -- 
> 1.8.5.1
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: wl_tablet draft v2

2014-07-16 Thread Peter Hutterer
On Wed, Jul 16, 2014 at 08:08:29PM -0400, Lyude wrote:
> On Mon, 2014-07-14 at 13:25 -0700, Jason Gerecke wrote:
> > On Sun, Jul 13, 2014 at 12:17 PM, Lyude  wrote:
> > >wl_tablet specifications
> > >   Version 2
> > >
> > > General notes:
> > > - Many of the axis values in this are normalized to either 0-65535 or
> > >   (-65535)-65535. I would leave the axis values as-is since libinput 
> > > reports
> > >   them as doubles, but since we only have 8 bits of precision we'd lose 
> > > way
> > >   too many values. 65535 seemed like the best choice since it's the 
> > > maximum
> > >   length of a signed short, it's a whole number, it's way higher then the
> > >   range of any of the axes (with the exception of X and Y, but these 
> > > aren't
> > >   normalized anyway) and we can do just about any basic arithmetic with it
> > >   without having to worry about overflowing. Plus, all we have to do is
> > >   multiply the value by 65535 after we get it from libinput.
> > >
> > Speaking of overflow, what's Wayland's stance on whether the
> > compositor or client is responsible for dealing with it? I remember
> > Google mentioned that while working on Android's input driver, they
> > noticed some input devices could be "turned up to 11" and report
> > values beyond the kernel-indicated minimum/maximum. They decided to
> > punt the problem to app developers and documented that an app may e.g.
> > see 110% pressure if that's what the hardware reported. The question
> > is mostly academic since the Wacom kernel driver shouldn't be an
> > offender, but I might as well ask :)
> If it comes down to handling overflow, it'll probably be up to the
> client. I'm hoping it shouldn't though. The reason I choose 65535 in the
> first place is because it can more then cover any of the axes (other
> then the X and Y axes, but those aren't normalized anyway so I'm not
> worried about that), and it's difficult to accidentally overflow doing
> general arithmetic with a value of 65535. In most situations, addition,
> subtraction, multiplication, etc. shouldn't overflow. In fact you can
> (almost) square it at least once without overflowing. I'm assuming if
> there's a chance they might, then the client's doing something that the
> developers understand the risk of. It's just a number though, so we can
> always turn it down if we need to.

And as for the "turning up to 11", we can/must handle that in libinput
anyway, since that already provides normalized values. The simple approach
of clipping the first event sequence above the max and then rescaling
min/max to fit in the future will probably cater for most use-cases.

> > > Changes since the last version:
> > > - The surface argument is now only included in the proximity-in events
> > > - wl_tablet_manager has been added. Events no longer have a separate id
> > >   argument, and instead rely on wl_tablet objects to differentiate each 
> > > tablet
> > >   from each other. A lot of it was copied from Peter's initial wl_tablet
> > >   proposal, but a few additions have been made; I've added an argument for
> > >   each of the axis events that a tablet supports to the device_added 
> > > event.
> > > - Axis changes have been split up into a couple different events
> > > - Added a generic frame event. Because of the different kinds of click
> > >   emulations done with tablets, having each event packed into a frame is
> > >   convenient.
> > > - All of the starting values for each axis are provided as normal events 
> > > in
> > >   the same frame as a proximity_in event. The same goes for the status of 
> > > each
> > >   button on the tool. This makes the protocol a lot cleaner
> > >
> > > Definitions:
> > > - WL_TABLET_AXIS_MAX = 65535
> > > - WL_TABLET_AXIS_MIN = (-65535)
> > >
> > > Interfaces:
> > > - wl_tablet
> > > Enumerators:
> > > - wl_tablet_tool_type:
> > > - pen
> > > - eraser
> > > - brush
> > > - pencil
> > > - airbrush
> > > - finger
> > > - mouse
> > > - lens
> > > - wl_tablet_button
> > > - stylus_1
> > > - stylus_2
> > > - wl_tablet_button_state
> > > - pressed
> > > - released
> > >
> > > Events:
> > > - proximity_in
> > >   Sent when the tool comes into proximity above the client 
> > > surface,
> > >   either by the tool coming into proximity or a tool being
> > >   in-proximity and moving to the client surface. If a tablet tool
> > >   makes contact with the tablet at the same time that the tool 
> > > comes
> > >   into proximity, the proximity event comes first and the down 
> > > event
> > >   comes afterwards.
> > >   A proximity_in event is immediately followed by the following
> > >   sequence of 

Re: [PATCH libinput 1/2] tablet: Don't swap X and Y in evcode_to_axis()

2014-07-16 Thread Peter Hutterer
On Sun, Jul 13, 2014 at 07:19:28PM -0400, Stephen Chandler Paul wrote:
> Signed-off-by: Stephen Chandler Paul 

pushed, thanks

Cheers,
   Peter

> ---
>  src/evdev-tablet.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index 74447bd..1b53d20 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -75,10 +75,10 @@ evcode_to_axis(const uint32_t evcode)
>   axis = LIBINPUT_TABLET_AXIS_PRESSURE;
>   break;
>   case ABS_TILT_X:
> - axis = LIBINPUT_TABLET_AXIS_TILT_Y;
> + axis = LIBINPUT_TABLET_AXIS_TILT_X;
>   break;
>   case ABS_TILT_Y:
> - axis = LIBINPUT_TABLET_AXIS_TILT_X;
> + axis = LIBINPUT_TABLET_AXIS_TILT_Y;
>   break;
>   default:
>   axis = LIBINPUT_TABLET_AXIS_NONE;
> -- 
> 1.8.5.5
> 
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: wl_tablet draft v2

2014-07-16 Thread Lyude
On Mon, 2014-07-14 at 13:25 -0700, Jason Gerecke wrote:
> On Sun, Jul 13, 2014 at 12:17 PM, Lyude  wrote:
> >wl_tablet specifications
> >   Version 2
> >
> > General notes:
> > - Many of the axis values in this are normalized to either 0-65535 or
> >   (-65535)-65535. I would leave the axis values as-is since libinput reports
> >   them as doubles, but since we only have 8 bits of precision we'd lose way
> >   too many values. 65535 seemed like the best choice since it's the maximum
> >   length of a signed short, it's a whole number, it's way higher then the
> >   range of any of the axes (with the exception of X and Y, but these aren't
> >   normalized anyway) and we can do just about any basic arithmetic with it
> >   without having to worry about overflowing. Plus, all we have to do is
> >   multiply the value by 65535 after we get it from libinput.
> >
> Speaking of overflow, what's Wayland's stance on whether the
> compositor or client is responsible for dealing with it? I remember
> Google mentioned that while working on Android's input driver, they
> noticed some input devices could be "turned up to 11" and report
> values beyond the kernel-indicated minimum/maximum. They decided to
> punt the problem to app developers and documented that an app may e.g.
> see 110% pressure if that's what the hardware reported. The question
> is mostly academic since the Wacom kernel driver shouldn't be an
> offender, but I might as well ask :)
If it comes down to handling overflow, it'll probably be up to the
client. I'm hoping it shouldn't though. The reason I choose 65535 in the
first place is because it can more then cover any of the axes (other
then the X and Y axes, but those aren't normalized anyway so I'm not
worried about that), and it's difficult to accidentally overflow doing
general arithmetic with a value of 65535. In most situations, addition,
subtraction, multiplication, etc. shouldn't overflow. In fact you can
(almost) square it at least once without overflowing. I'm assuming if
there's a chance they might, then the client's doing something that the
developers understand the risk of. It's just a number though, so we can
always turn it down if we need to.

> 
> > Changes since the last version:
> > - The surface argument is now only included in the proximity-in events
> > - wl_tablet_manager has been added. Events no longer have a separate id
> >   argument, and instead rely on wl_tablet objects to differentiate each 
> > tablet
> >   from each other. A lot of it was copied from Peter's initial wl_tablet
> >   proposal, but a few additions have been made; I've added an argument for
> >   each of the axis events that a tablet supports to the device_added event.
> > - Axis changes have been split up into a couple different events
> > - Added a generic frame event. Because of the different kinds of click
> >   emulations done with tablets, having each event packed into a frame is
> >   convenient.
> > - All of the starting values for each axis are provided as normal events in
> >   the same frame as a proximity_in event. The same goes for the status of 
> > each
> >   button on the tool. This makes the protocol a lot cleaner
> >
> > Definitions:
> > - WL_TABLET_AXIS_MAX = 65535
> > - WL_TABLET_AXIS_MIN = (-65535)
> >
> > Interfaces:
> > - wl_tablet
> > Enumerators:
> > - wl_tablet_tool_type:
> > - pen
> > - eraser
> > - brush
> > - pencil
> > - airbrush
> > - finger
> > - mouse
> > - lens
> > - wl_tablet_button
> > - stylus_1
> > - stylus_2
> > - wl_tablet_button_state
> > - pressed
> > - released
> >
> > Events:
> > - proximity_in
> >   Sent when the tool comes into proximity above the client surface,
> >   either by the tool coming into proximity or a tool being
> >   in-proximity and moving to the client surface. If a tablet tool
> >   makes contact with the tablet at the same time that the tool comes
> >   into proximity, the proximity event comes first and the down event
> >   comes afterwards.
> >   A proximity_in event is immediately followed by the following
> >   sequence of events in the same frame:
> > - motion
> > - down (if the tool is touching the tablet's surface at the
> >   same time it comes into proximity)
> > - a button press event for each button held down on the tool
> >   as it comes into proximity
> > - pressure (if supported by the tablet)
> > - distance (if supported by the tablet)
> > - tilt (if supported by the tablet)
> >   This allows a client to get the starting values for all of th

[PATCH weston 2/3] desktop-shell: use panel location to calculate correct sizes and ranges

2014-07-16 Thread Jonny Lamb
Now the client can let us know where the panel is using
desktop_shell.set_panel_position, we can correctly calculate where to
put new views and how big maximized views should be.
---
 desktop-shell/shell.c | 175 ++
 1 file changed, 120 insertions(+), 55 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 0f364d4..e51c299 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -251,9 +251,10 @@ shell_fade_startup(struct desktop_shell *shell);
 static struct shell_seat *
 get_shell_seat(struct weston_seat *seat);
 
-static int
-get_output_panel_height(struct desktop_shell *shell,
-   struct weston_output *output);
+static void
+get_output_panel_size(struct desktop_shell *shell,
+ struct weston_output *output,
+ int *width, int *height);
 
 static void
 shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
@@ -351,24 +352,85 @@ shell_grab_start(struct shell_grab *grab,
}
 }
 
-static int
-get_output_panel_height(struct desktop_shell *shell,
-   struct weston_output *output)
+static void
+get_output_panel_size(struct desktop_shell *shell,
+ struct weston_output *output,
+ int *width,
+ int *height)
 {
struct weston_view *view;
-   int panel_height = 0;
+
+   *width = 0;
+   *height = 0;
 
if (!output)
-   return 0;
+   return;
 
wl_list_for_each(view, &shell->panel_layer.view_list, layer_link) {
-   if (view->surface->output == output) {
-   panel_height = view->surface->height;
+   float x, y;
+
+   if (view->surface->output != output)
+   continue;
+
+   switch (shell->panel_position) {
+   case DESKTOP_SHELL_PANEL_POSITION_TOP:
+   case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
+
+   weston_view_to_global_float(view,
+   view->surface->width, 0,
+   &x, &y);
+
+   *width = (int) x;
+   *height = view->surface->height + (int) y;
+   return;
+
+   case DESKTOP_SHELL_PANEL_POSITION_LEFT:
+   case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
+   weston_view_to_global_float(view,
+   0, view->surface->height,
+   &x, &y);
+
+   *width = view->surface->width + (int) x;
+   *height = (int) y;
+   return;
+
+   default:
+   /* we've already set width and height to
+* fallback values. */
break;
}
}
 
-   return panel_height;
+   /* the correct view wasn't found */
+}
+
+static void
+get_output_work_area(struct desktop_shell *shell,
+struct weston_output *output,
+pixman_rectangle32_t *area)
+{
+   int32_t panel_width = 0, panel_height = 0;
+
+   area->x = 0;
+   area->y = 0;
+
+   get_output_panel_size(shell, output, &panel_width, &panel_height);
+
+   switch (shell->panel_position) {
+   case DESKTOP_SHELL_PANEL_POSITION_TOP:
+   default:
+   area->y = panel_height;
+   case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
+   area->width = output->width;
+   area->height = output->height - panel_height;
+   break;
+   case DESKTOP_SHELL_PANEL_POSITION_LEFT:
+   area->x = panel_width;
+   case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
+   area->width = output->width - panel_width;
+   area->height = output->height;
+   break;
+   }
 }
 
 static void
@@ -389,13 +451,13 @@ send_configure_for_surface(struct shell_surface *shsurf)
height = shsurf->output->height;
} else if (state->maximized) {
struct desktop_shell *shell;
-   uint32_t panel_height = 0;
+   pixman_rectangle32_t area;
 
shell = shell_surface_get_shell(shsurf);
-   panel_height = get_output_panel_height(shell, shsurf->output);
+   get_output_work_area(shell, shsurf->output, &area);
 
-   width = shsurf->output->width;
-   height = shsurf->output->height - panel_height;
+   width = area.width;
+   height = area.height;
} else {
width = 0;
height = 0;
@@ -1546,22 +1608,25 @@ constrain_position(struct weston_move_grab *move, int 
*cx, int *cy)
 {
struct shell_surface *shsurf = move->base.shsurf;
struct weston_point

[PATCH weston 1/3] desktop-shell: add set_panel_position to help place views onscreen

2014-07-16 Thread Jonny Lamb
Panels are always assumed to be on the top edge of the output. If this
is not the case views will be placed under the panel, wherever it is,
and maximize doesn't use the correct space allocated for views.

By telling the server on which edge the panel is located, it can
correctly calculate where to put new views and how big maximized views
should be.
---
 desktop-shell/shell.c  | 29 ++---
 desktop-shell/shell.h  |  2 ++
 protocol/desktop-shell.xml | 20 +++-
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index f22cef8..0f364d4 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -4106,13 +4106,34 @@ desktop_shell_desktop_ready(struct wl_client *client,
shell_fade_startup(shell);
 }
 
+static void
+desktop_shell_set_panel_position(struct wl_client *client,
+struct wl_resource *resource,
+uint32_t position)
+{
+   struct desktop_shell *shell = wl_resource_get_user_data(resource);
+
+   if (position != DESKTOP_SHELL_PANEL_POSITION_TOP &&
+   position != DESKTOP_SHELL_PANEL_POSITION_BOTTOM &&
+   position != DESKTOP_SHELL_PANEL_POSITION_LEFT &&
+   position != DESKTOP_SHELL_PANEL_POSITION_RIGHT) {
+   wl_resource_post_error(resource,
+  WL_DISPLAY_ERROR_INVALID_OBJECT,
+  "bad position argument");
+   return;
+   }
+
+   shell->panel_position = position;
+}
+
 static const struct desktop_shell_interface desktop_shell_implementation = {
desktop_shell_set_background,
desktop_shell_set_panel,
desktop_shell_set_lock_surface,
desktop_shell_unlock,
desktop_shell_set_grab_surface,
-   desktop_shell_desktop_ready
+   desktop_shell_desktop_ready,
+   desktop_shell_set_panel_position
 };
 
 static enum shell_surface_type
@@ -5319,7 +5340,7 @@ bind_desktop_shell(struct wl_client *client,
struct wl_resource *resource;
 
resource = wl_resource_create(client, &desktop_shell_interface,
- MIN(version, 2), id);
+ MIN(version, 3), id);
 
if (client == shell->child.client) {
wl_resource_set_implementation(resource,
@@ -6240,7 +6261,7 @@ module_init(struct weston_compositor *ec,
return -1;
 
if (wl_global_create(ec->wl_display,
-&desktop_shell_interface, 2,
+&desktop_shell_interface, 3,
 shell, bind_desktop_shell) == NULL)
return -1;
 
@@ -6254,6 +6275,8 @@ module_init(struct weston_compositor *ec,
 
shell->child.deathstamp = weston_compositor_get_time();
 
+   shell->panel_position = DESKTOP_SHELL_PANEL_POSITION_TOP;
+
setup_output_destroy_handler(ec, shell);
 
loop = wl_display_get_event_loop(ec->wl_display);
diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
index 6e63785..f50acac 100644
--- a/desktop-shell/shell.h
+++ b/desktop-shell/shell.h
@@ -204,6 +204,8 @@ struct desktop_shell {
struct wl_listener output_move_listener;
struct wl_list output_list;
 
+   uint32_t panel_position;
+
char *client;
 };
 
diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml
index fdcb17b..57c204a 100644
--- a/protocol/desktop-shell.xml
+++ b/protocol/desktop-shell.xml
@@ -1,6 +1,6 @@
 
 
-  
+  
 
   Traditional user interfaces can rely on this interface to define the
   foundations of typical desktops. Currently it's possible to set up
@@ -94,6 +94,24 @@
   
 
 
+
+
+
+  
+  
+  
+  
+
+
+
+  
+  
+Tell the shell which side of the screen the panel is
+located. This is so that new windows do not overlap the panel
+and maximized windows maximize properly.
+  
+
+
   
 
   
-- 
2.0.0

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


[PATCH weston 3/3] shell: constrain resize grabs so windows don't go under the panel

2014-07-16 Thread Jonny Lamb
https://bugs.freedesktop.org/show_bug.cgi?id=80228
---
 desktop-shell/shell.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index e51c299..e0f001d 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -1754,6 +1754,32 @@ struct weston_resize_grab {
 };
 
 static void
+constrain_move_grab(struct weston_pointer_grab *grab,
+   int32_t *width, int32_t *height)
+{
+   struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
+   struct shell_surface *shsurf = resize->base.shsurf;
+
+   int32_t height_difference;
+
+   height_difference = *height - shsurf->surface->height;
+
+   /* this is only really necessary when the panel is at the top */
+   if (shsurf->shell->panel_position == DESKTOP_SHELL_PANEL_POSITION_TOP &&
+   resize->edges & WL_SHELL_SURFACE_RESIZE_TOP &&
+   height_difference > 0) {
+   int32_t panel_width, panel_height, top;
+
+   get_output_panel_size(shsurf->shell, shsurf->surface->output,
+ &panel_width, &panel_height);
+
+   top = (shsurf->view->geometry.y - height_difference) + 
shsurf->margin.top;
+   if (top < panel_height)
+   *height = shsurf->surface->height;
+   }
+}
+
+static void
 resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
   wl_fixed_t x, wl_fixed_t y)
 {
@@ -1789,6 +1815,8 @@ resize_grab_motion(struct weston_pointer_grab *grab, 
uint32_t time,
height += wl_fixed_to_int(to_y - from_y);
}
 
+   constrain_move_grab(grab, &width, &height);
+
shsurf->client->send_configure(shsurf->surface, width, height);
 }
 
-- 
2.0.0

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


[PATCH wayland] protocol: add repeat_info event to wl_keyboard

2014-07-16 Thread Jonny Lamb
In the process wl_keyboard's version has been incremented. Given
clients get the wl_keyboard from wl_seat without a version, wl_seat's
version has also been incremented (wl_seat version 4 implies
wl_keyboard version 4).
---
 protocol/wayland.xml | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 4e65b32..5c90a19 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -1277,7 +1277,7 @@
 

 
-  
+  
 
   A seat is a group of keyboards, pointer and touch devices. This
   object is published as a global during start up, or when such a
@@ -1505,7 +1505,7 @@
 
   
 
-  
+  
 
   The wl_keyboard interface represents one or more keyboards
   associated with a seat.
@@ -1593,6 +1593,30 @@
 
   
 
+
+
+
+
+  
+Informs the client about the keyboard's repeat rate and delay.
+
+This event guaranteed to be sent as soon as the wl_keyboard object has
+been created, so after the wl_keyboard is created, one roundtrip will
+be sufficient in receiving this event.
+
+Negative values for either rate or delay are illegal. A rate of zero
+will disable any repeating (regardless of the value of delay).
+
+This event can be sent later on as well with a new value if necessary,
+so clients should continue listening for the event past the creation
+of wl_keyboard.
+  
+
+  
+  
+
   
 
   
-- 
2.0.0

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


Re: [PATCH weston] input: send wl_keyboard.repeat_info with rate and delay info

2014-07-16 Thread Jonny Lamb
On lun, 2014-06-02 at 10:43 +0300, Pekka Paalanen wrote:
> Looks good, only few comments there.

They should all be fixed now.

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


[PATCH weston] input: send wl_keyboard.repeat_info with rate and delay info

2014-07-16 Thread Jonny Lamb
The compositor reads the values out from weston.ini, the weston
compositor passes on the values, the weston-info client prints out the
values, and the values are respected in toytoolkit.
---
 clients/weston-info.c| 89 +++-
 clients/window.c | 24 +++--
 src/compositor-wayland.c | 18 --
 src/compositor.c |  5 +++
 src/compositor.h |  3 ++
 src/input.c  | 12 +--
 6 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/clients/weston-info.c b/clients/weston-info.c
index df869e3..c53ac74 100644
--- a/clients/weston-info.c
+++ b/clients/weston-info.c
@@ -32,6 +32,8 @@
 
 #include "../shared/os-compatibility.h"
 
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+
 typedef void (*print_info_t)(void *info);
 typedef void (*destroy_info_t)(void *info);
 
@@ -87,9 +89,13 @@ struct shm_info {
 struct seat_info {
struct global_info global;
struct wl_seat *seat;
+   struct weston_info *info;
 
uint32_t capabilities;
char *name;
+
+   int32_t repeat_rate;
+   int32_t repeat_delay;
 };
 
 struct weston_info {
@@ -291,14 +297,89 @@ print_seat_info(void *data)
printf(" touch");
 
printf("\n");
+
+   if (seat->repeat_rate > 0)
+   printf("\tkeyboard repeat rate: %d\n", seat->repeat_rate);
+   if (seat->repeat_delay > 0)
+   printf("\tkeyboard repeat delay: %d\n", seat->repeat_delay);
+}
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+  uint32_t format, int fd, uint32_t size)
+{
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, struct wl_surface *surface,
+ struct wl_array *keys)
+{
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, struct wl_surface *surface)
+{
 }
 
 static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
+   uint32_t serial, uint32_t time, uint32_t key,
+   uint32_t state)
+{
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+ uint32_t serial, uint32_t mods_depressed,
+ uint32_t mods_latched, uint32_t mods_locked,
+ uint32_t group)
+{
+}
+
+static void
+keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
+   int32_t rate, int32_t delay)
+{
+   struct seat_info *seat = data;
+
+   seat->repeat_rate = rate;
+   seat->repeat_delay = delay;
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+   keyboard_handle_keymap,
+   keyboard_handle_enter,
+   keyboard_handle_leave,
+   keyboard_handle_key,
+   keyboard_handle_modifiers,
+   keyboard_handle_repeat_info,
+};
+
+static void
 seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
 enum wl_seat_capability caps)
 {
struct seat_info *seat = data;
+
seat->capabilities = caps;
+
+   /* we want listen for repeat_info from wl_keyboard, but only
+* do so if the seat info is >= 4 and if we actually have a
+* keyboard */
+   if (seat->global.version < 4)
+   return;
+
+   if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+   struct wl_keyboard *keyboard;
+
+   keyboard = wl_seat_get_keyboard(seat->seat);
+   wl_keyboard_add_listener(keyboard, &keyboard_listener,
+seat);
+
+   seat->info->roundtrip_needed = true;
+   }
 }
 
 static void
@@ -330,14 +411,20 @@ add_seat_info(struct weston_info *info, uint32_t id, 
uint32_t version)
 {
struct seat_info *seat = xzalloc(sizeof *seat);
 
+   /* required to set roundtrip_needed to true in capabilities
+* handler */
+   seat->info = info;
+
init_global_info(info, &seat->global, id, "wl_seat", version);
seat->global.print = print_seat_info;
seat->global.destroy = destroy_seat_info;
 
seat->seat = wl_registry_bind(info->registry,
- id, &wl_seat_interface, 2);
+ id, &wl_seat_interface, MIN(version, 4));
wl_seat_add_listener(seat->seat, &seat_listener, seat);
 
+   seat->repeat_rate = seat->repeat_delay = -1;
+
info->roundtrip_needed = true;
 }
 
diff --git a/clients/window.c b/clients/window.c
index b82a93e..906dce6 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -334,6 +334,9 @@ struct input {
xkb_mod_mask_t shift_mask;
} xkb;
 
+   int32_t repeat_rate;
+   int32_t repeat_delay;
+
struct task repeat_task;
int repeat_timer_fd;
uint32_t repeat_sym;
@@ -2865,9 +2868,9 @@ keyboard_handle_ke

Re: [PATCH wayland] protocol: add repeat_info event to wl_keyboard

2014-07-16 Thread Jonny Lamb
(finally got around to looking at this again)

On Mon, 2 Jun 2014 10:22:40 +0300 Pekka Paalanen wrote:
> this looks good to me, but I'd like to see text about when this event
> is sent. I assume it is sent once as soon as a wl_keyboard object has
> been created, and this is also required/guaranteed. IOW, if a client
> creates a wl_keyboard and then does a roundtrip, it is guaranteed to
> have received the event at least once. Right?

Right! I've addressed all these issues.

> Or should sending it be optional? Should we define any defaults in case
> no event has been received? I'd assume not.

I agree not. I defined some defaults in weston but that's weston.

> Can it be sent later, too? (Likely yes.)

I added a note to say it can.

> Was this ever discussed before this email thread? I'd like to see at
> least one more ack (Daniel already ack'd) before I'm comfortable pushing
> this to wayland master, as this is part of the core protocol.

No it wasn't, although Daniel was the one who told me to implement it in
the first place.

On Mon, 2014-06-02 at 10:36 +0300, Pekka Paalanen wrote:
> Would we want to specify "no repeat" values?

I used Giulio Camuffo's suggestion of using zero for no repeat.

> Also, while it is just an event and error codes would not make sense in
> the protocol, we should probably still mention, that negative values are
> illegal - what to do with zero?

I added a note about negative values.

> Re-reading it, this seems funnily said:
> > > +   summary="time in milliseconds between keys repeating"/>
> I think it wants to say: "delay in milliseconds since key-down until
> repeating starts" or something. Not "between keys" since that sounds
> like repeat rate. :-)

Yes, good point, fixed.

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


[PATCH libinput 8/8] touchpad: Use evdev_pointer_notify_button()

2014-07-16 Thread Jonas Ådahl
Make use of the key mask in struct evdev_device to keep track of pressed
buttons.

Signed-off-by: Jonas Ådahl 
---
 src/evdev-mt-touchpad-buttons.c | 24 
 src/evdev-mt-touchpad-tap.c |  8 
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 520a47f..308a3be 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -607,10 +607,10 @@ tp_post_clickfinger_buttons(struct tp_dispatch *tp, 
uint64_t time)
}
 
if (button)
-   pointer_notify_button(&tp->device->base,
- time,
- button,
- state);
+   evdev_pointer_notify_button(tp->device,
+   time,
+   button,
+   state);
return 1;
 }
 
@@ -632,10 +632,10 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t 
time)
else
state = LIBINPUT_BUTTON_STATE_RELEASED;
 
-   pointer_notify_button(&tp->device->base,
- time,
- button,
- state);
+   evdev_pointer_notify_button(tp->device,
+   time,
+   button,
+   state);
}
 
button++;
@@ -708,10 +708,10 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, 
uint64_t time)
tp->buttons.click_pending = false;
 
if (button)
-   pointer_notify_button(&tp->device->base,
- time,
- button,
- state);
+   evdev_pointer_notify_button(tp->device,
+   time,
+   button,
+   state);
return 1;
 }
 
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 0f1f837..3d99e0f 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -113,10 +113,10 @@ tp_tap_notify(struct tp_dispatch *tp,
return;
}
 
-   pointer_notify_button(&tp->device->base,
- time,
- button,
- state);
+   evdev_pointer_notify_button(tp->device,
+   time,
+   button,
+   state);
 }
 
 static void
-- 
1.8.5.1

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


[PATCH libinput 2/8] test: Use only one test device for some udev and path tests

2014-07-16 Thread Jonas Ådahl
Some tests in test/path.c and test/udev.c are not dependent on
device behaviour but rather managing of device lifetime etc. Run those
tests only once with only one device, resulting more or less the same
code coverage but shorter run time.

Signed-off-by: Jonas Ådahl 
---
 test/litest.c | 65 ++-
 test/litest.h |  3 +++
 test/path.c   | 13 ++--
 test/udev.c   | 15 +++---
 4 files changed, 65 insertions(+), 31 deletions(-)

diff --git a/test/litest.c b/test/litest.c
index adcbf3e..b64c7e3 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -151,25 +151,33 @@ litest_add_tcase_no_device(struct suite *suite, void 
*func)
 static void
 litest_add_tcase(struct suite *suite, void *func,
 enum litest_device_feature required,
-enum litest_device_feature excluded)
+enum litest_device_feature excluded,
+int num)
 {
struct litest_test_device **dev = devices;
 
+   if (num == 0)
+   return;
+
if (required == LITEST_DISABLE_DEVICE &&
excluded == LITEST_DISABLE_DEVICE) {
litest_add_tcase_no_device(suite, func);
-   } else if (required != LITEST_ANY || excluded != LITEST_ANY) {
-   while (*dev) {
-   if (((*dev)->features & required) == required &&
-   ((*dev)->features & excluded) == 0)
-   litest_add_tcase_for_device(suite, func, *dev);
-   dev++;
-   }
-   } else {
-   while (*dev) {
+   return;
+   }
+
+   while (*dev) {
+   if ((required == LITEST_ANY && excluded == LITEST_ANY) ||
+   (((*dev)->features & required) == required &&
+((*dev)->features & excluded) == 0)) {
litest_add_tcase_for_device(suite, func, *dev);
-   dev++;
+
+   if (num != -1) {
+   num--;
+   if (num == 0)
+   break;
+   }
}
+   dev++;
}
 }
 
@@ -179,11 +187,12 @@ litest_add_no_device(const char *name, void *func)
litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
 }
 
-void
-litest_add(const char *name,
-  void *func,
-  enum litest_device_feature required,
-  enum litest_device_feature excluded)
+static void
+litest_add_common(const char *name,
+ void *func,
+ enum litest_device_feature required,
+ enum litest_device_feature excluded,
+ int num_devices)
 {
struct suite *s;
 
@@ -192,7 +201,9 @@ litest_add(const char *name,
 
list_for_each(s, &all_tests, node) {
if (strcmp(s->name, name) == 0) {
-   litest_add_tcase(s, func, required, excluded);
+   litest_add_tcase(s, func,
+required, excluded,
+num_devices);
return;
}
}
@@ -203,7 +214,25 @@ litest_add(const char *name,
 
list_init(&s->tests);
list_insert(&all_tests, &s->node);
-   litest_add_tcase(s, func, required, excluded);
+   litest_add_tcase(s, func, required, excluded, num_devices);
+}
+
+void
+litest_add(const char *name,
+  void *func,
+  enum litest_device_feature required,
+  enum litest_device_feature excluded)
+{
+   litest_add_common(name, func, required, excluded, -1);
+}
+
+void
+litest_add_once(const char *name,
+   void *func,
+   enum litest_device_feature required,
+   enum litest_device_feature excluded)
+{
+   litest_add_common(name, func, required, excluded, 1);
 }
 
 static int
diff --git a/test/litest.h b/test/litest.h
index 3e75dd5..b66a74f 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -74,6 +74,9 @@ struct libinput *litest_create_context(void);
 void litest_add(const char *name, void *func,
enum litest_device_feature required_feature,
enum litest_device_feature excluded_feature);
+void litest_add_once(const char *name, void *func,
+enum litest_device_feature required_feature,
+enum litest_device_feature excluded_feature);
 void litest_add_no_device(const char *name, void *func);
 
 int litest_run(int argc, char **argv);
diff --git a/test/path.c b/test/path.c
index 9cc5b04..8bfe329 100644
--- a/test/path.c
+++ b/test/path.c
@@ -797,8 +797,9 @@ START_TEST(path_seat_recycle)
 }
 END_TEST
 
-int main (int argc, char **argv) {
-
+int
+main(int argc, char **argv)
+{
litest_add_no_device("path:create", path_create_NULL);
litest_add_no_device("path:create", path_create_invalid);

[PATCH libinput 1/8] test/path: Avoid creating ignored test devices

2014-07-16 Thread Jonas Ådahl
Some tests doesn't use or doesn't need to use the test device
automatically created when adding a test case for certain types of
devices. For these tests, to shorten test run time, don't create the
test devices that would be ignored.

Signed-off-by: Jonas Ådahl 
---
 test/path.c | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/test/path.c b/test/path.c
index 99b474e..9cc5b04 100644
--- a/test/path.c
+++ b/test/path.c
@@ -244,12 +244,11 @@ END_TEST
 
 START_TEST(path_add_invalid_path)
 {
-   struct litest_device *dev = litest_current_device();
-   struct libinput *li = dev->libinput;
+   struct libinput *li;
struct libinput_event *event;
struct libinput_device *device;
 
-   litest_drain_events(li);
+   li = litest_create_context();
 
device = libinput_path_add_device(li, "/tmp/");
ck_assert(device == NULL);
@@ -258,6 +257,8 @@ START_TEST(path_add_invalid_path)
 
while ((event = libinput_get_event(li)))
ck_abort();
+
+   libinput_unref(li);
 }
 END_TEST
 
@@ -798,24 +799,23 @@ END_TEST
 
 int main (int argc, char **argv) {
 
-   litest_add("path:create", path_create_NULL, LITEST_ANY, LITEST_ANY);
-   litest_add("path:create", path_create_invalid, LITEST_ANY, LITEST_ANY);
-   litest_add("path:create", path_create_destroy, LITEST_ANY, LITEST_ANY);
-   litest_add("path:suspend", path_suspend, LITEST_ANY, LITEST_ANY);
-   litest_add("path:suspend", path_double_suspend, LITEST_ANY, LITEST_ANY);
-   litest_add("path:suspend", path_double_resume, LITEST_ANY, LITEST_ANY);
-   litest_add("path:suspend", path_add_device_suspend_resume, LITEST_ANY, 
LITEST_ANY);
-   litest_add("path:suspend", path_add_device_suspend_resume_fail, 
LITEST_ANY, LITEST_ANY);
-   litest_add("path:suspend", 
path_add_device_suspend_resume_remove_device, LITEST_ANY, LITEST_ANY);
+   litest_add_no_device("path:create", path_create_NULL);
+   litest_add_no_device("path:create", path_create_invalid);
+   litest_add_no_device("path:create", path_create_destroy);
+   litest_add_no_device("path:suspend", path_suspend);
+   litest_add_no_device("path:suspend", path_double_suspend);
+   litest_add_no_device("path:suspend", path_double_resume);
+   litest_add_no_device("path:suspend", path_add_device_suspend_resume);
+   litest_add_no_device("path:suspend", 
path_add_device_suspend_resume_fail);
+   litest_add_no_device("path:suspend", 
path_add_device_suspend_resume_remove_device);
litest_add("path:seat events", path_added_seat, LITEST_ANY, LITEST_ANY);
litest_add("path:device events", path_added_device, LITEST_ANY, 
LITEST_ANY);
litest_add("path:device events", path_device_sysname, LITEST_ANY, 
LITEST_ANY);
litest_add("path:device events", path_add_device, LITEST_ANY, 
LITEST_ANY);
-   litest_add("path:device events", path_add_invalid_path, LITEST_ANY, 
LITEST_ANY);
+   litest_add_no_device("path:device events", path_add_invalid_path);
litest_add("path:device events", path_remove_device, LITEST_ANY, 
LITEST_ANY);
litest_add("path:device events", path_double_remove_device, LITEST_ANY, 
LITEST_ANY);
-   litest_add("path:seat", path_seat_recycle,
-  LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
+   litest_add_no_device("path:seat", path_seat_recycle);
 
return litest_run(argc, argv);
 }
-- 
1.8.5.1

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


[PATCH libinput 4/8] test: Don't fail when events are enabled multiple times

2014-07-16 Thread Jonas Ådahl
When overriding events of a test device, if one would enable an event
that was already enabled by default for the overridden device, an assert
checking if the event was already enabled would fail and cause the test
to fail.

Since the merging of the default and overriding event lists is implemented
by simply concatinating them letting libevdev deal with ignoring
superfluous event enabling, remove the assert to allow the implementation
to work.

Signed-off-by: Jonas Ådahl 
---
 test/litest.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/test/litest.c b/test/litest.c
index 961b917..459eafe 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -879,8 +879,6 @@ litest_create_uinput_device_from_description(const char 
*name,
if (type == INPUT_PROP_MAX) {
rc = libevdev_enable_property(dev, code);
} else {
-   if (type != EV_SYN)
-   ck_assert(!libevdev_has_event_code(dev, type, 
code));
rc = libevdev_enable_event_code(dev, type, code,
type == EV_ABS ? 
&default_abs : NULL);
}
-- 
1.8.5.1

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


[PATCH libinput 5/8] evdev: Early out during configure if not using fallback dispatch

2014-07-16 Thread Jonas Ådahl
The feature set configured otherwise would not work anyway as it
would need using the fallback dispatch to function.

Signed-off-by: Jonas Ådahl 
---
 src/evdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/evdev.c b/src/evdev.c
index f980812..fec24f5 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -700,9 +700,11 @@ evdev_configure_device(struct evdev_device *device)
!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN) &&
(has_abs || has_mt)) {
device->dispatch = evdev_mt_touchpad_create(device);
+   device->seat_caps |= EVDEV_DEVICE_POINTER;
log_info(libinput,
 "input device '%s', %s is a touchpad\n",
 device->devname, device->devnode);
+   return device->dispatch == NULL ? -1 : 0;
}
for (i = KEY_ESC; i < KEY_MAX; i++) {
if (i >= BTN_MISC && i < KEY_OK)
-- 
1.8.5.1

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


[PATCH libinput 6/8] evdev: Use helper for separating buttons from keys

2014-07-16 Thread Jonas Ådahl
Signed-off-by: Jonas Ådahl 
---
 src/evdev.c | 83 ++---
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index fec24f5..c031258 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -41,6 +41,12 @@
 
 #define DEFAULT_AXIS_STEP_DISTANCE 10
 
+enum evdev_key_type {
+   EVDEV_KEY_TYPE_NONE,
+   EVDEV_KEY_TYPE_KEY,
+   EVDEV_KEY_TYPE_BUTTON,
+};
+
 void
 evdev_device_led_update(struct evdev_device *device, enum libinput_led leds)
 {
@@ -254,6 +260,23 @@ evdev_flush_pending_event(struct evdev_device *device, 
uint64_t time)
device->pending_event = EVDEV_NONE;
 }
 
+static enum evdev_key_type
+get_key_type(uint16_t code)
+{
+   if (code == BTN_TOUCH)
+   return EVDEV_KEY_TYPE_NONE;
+
+   if (code >= KEY_ESC && code <= KEY_MICMUTE)
+   return EVDEV_KEY_TYPE_KEY;
+   if (code >= BTN_MISC && code <= BTN_GEAR_UP)
+   return EVDEV_KEY_TYPE_BUTTON;
+   if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE)
+   return EVDEV_KEY_TYPE_KEY;
+   if (code >= BTN_DPAD_UP && code <= BTN_TRIGGER_HAPPY40)
+   return EVDEV_KEY_TYPE_BUTTON;
+   return EVDEV_KEY_TYPE_NONE;
+}
+
 static void
 evdev_process_touch_button(struct evdev_device *device,
   uint64_t time, int value)
@@ -275,9 +298,6 @@ evdev_process_key(struct evdev_device *device,
if (e->value == 2)
return;
 
-   if (e->code > KEY_MAX)
-   return;
-
if (e->code == BTN_TOUCH) {
if (!device->is_mt)
evdev_process_touch_button(device, time, e->value);
@@ -286,29 +306,10 @@ evdev_process_key(struct evdev_device *device,
 
evdev_flush_pending_event(device, time);
 
-   switch (e->code) {
-   case BTN_LEFT:
-   case BTN_RIGHT:
-   case BTN_MIDDLE:
-   case BTN_SIDE:
-   case BTN_EXTRA:
-   case BTN_FORWARD:
-   case BTN_BACK:
-   case BTN_TASK:
-   pointer_notify_button(
-   &device->base,
-   time,
-   e->code,
-   e->value ? LIBINPUT_BUTTON_STATE_PRESSED :
-  LIBINPUT_BUTTON_STATE_RELEASED);
+   switch (get_key_type(e->code)) {
+   case EVDEV_KEY_TYPE_NONE:
break;
-
-   default:
-   /* Only let KEY_* codes pass through. */
-   if (!(e->code <= KEY_MICMUTE ||
- (e->code >= KEY_OK && e->code <= KEY_LIGHTS_TOGGLE)))
-   break;
-
+   case EVDEV_KEY_TYPE_KEY:
keyboard_notify_key(
&device->base,
time,
@@ -316,6 +317,14 @@ evdev_process_key(struct evdev_device *device,
e->value ? LIBINPUT_KEY_STATE_PRESSED :
   LIBINPUT_KEY_STATE_RELEASED);
break;
+   case EVDEV_KEY_TYPE_BUTTON:
+   pointer_notify_button(
+   &device->base,
+   time,
+   e->code,
+   e->value ? LIBINPUT_BUTTON_STATE_PRESSED :
+  LIBINPUT_BUTTON_STATE_RELEASED);
+   break;
}
 }
 
@@ -706,22 +715,24 @@ evdev_configure_device(struct evdev_device *device)
 device->devname, device->devnode);
return device->dispatch == NULL ? -1 : 0;
}
-   for (i = KEY_ESC; i < KEY_MAX; i++) {
-   if (i >= BTN_MISC && i < KEY_OK)
-   continue;
+
+   for (i = 0; i < KEY_MAX; i++) {
if (libevdev_has_event_code(evdev, EV_KEY, i)) {
-   has_keyboard = 1;
-   break;
+   switch (get_key_type(i)) {
+   case EVDEV_KEY_TYPE_NONE:
+   break;
+   case EVDEV_KEY_TYPE_KEY:
+   has_keyboard = 1;
+   break;
+   case EVDEV_KEY_TYPE_BUTTON:
+   has_button = 1;
+   break;
+   }
}
}
+
if (libevdev_has_event_code(evdev, EV_KEY, BTN_TOUCH))
has_touch = 1;
-   for (i = BTN_MISC; i < BTN_JOYSTICK; i++) {
-   if (libevdev_has_event_code(evdev, EV_KEY, i)) {
-   has_button = 1;
-   break;
-   }
-   }
}
if (libevdev_has_event_type(evdev, EV_LED))
has_keyboard = 1;
-- 
1.8

[PATCH libinput 7/8] evdev: Release still pressed keys/buttons when removing device

2014-07-16 Thread Jonas Ådahl
Keep track of pressed keys and buttons in a bitmask array and iterate
through it on device removal releasing every still pressed key.

This commit enables _GNU_SOURCE features in evdev.c, more specifically
static_assert(). This is supported by gcc 4.6 and above, but is not part
of the C standard until C11. configure will fail if static_assert()
doesn't work whith _GNU_SOURCE defined.

Signed-off-by: Jonas Ådahl 
---
 configure.ac|  11 +
 src/evdev.c | 132 ++--
 src/evdev.h |  14 ++
 test/keyboard.c | 118 ++
 test/pointer.c  |  91 ++
 5 files changed, 362 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index fd402e2..e35fff6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,6 +67,17 @@ fi
 AC_SUBST(GCC_CFLAGS)
 AC_SUBST(GCC_CXXFLAGS)
 
+AC_MSG_CHECKING([whether static_assert() is supported])
+AC_COMPILE_IFELSE(
+   [AC_LANG_SOURCE([[#define _GNU_SOURCE
+ #include 
+ static_assert(1, "Test");
+ ]])],
+   [have_static_assert=1
+AC_MSG_RESULT([yes])],
+   [have_static_assert=0
+AC_MSG_ERROR([no built-in static_assert])])
+
 AC_PATH_PROG(DOXYGEN, [doxygen])
 if test "x$DOXYGEN" = "x"; then
AC_MSG_WARN([doxygen not found - required for documentation])
diff --git a/src/evdev.c b/src/evdev.c
index c031258..3fb5ab4 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -21,6 +21,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define _GNU_SOURCE
+
 #include "config.h"
 
 #include 
@@ -47,6 +49,87 @@ enum evdev_key_type {
EVDEV_KEY_TYPE_BUTTON,
 };
 
+static void
+get_key_index_and_bit(int code, int *index, int *bit)
+{
+   static_assert((KEY_CNT % 64) == 0, "KEY_CNT not aligned to 64");
+
+   *index = code / 64;
+   *bit = code % 64;
+}
+
+static int
+get_key_state(struct evdev_device *device, int code)
+{
+   int index = 0;
+   int bit = 0;
+
+   get_key_index_and_bit(code, &index, &bit);
+   return !!(device->key_mask[index] & (1ULL << bit));
+}
+
+static void
+set_key_state(struct evdev_device *device, int code, int pressed)
+{
+   int index = 0;
+   int bit = 0;
+
+   get_key_index_and_bit(code, &index, &bit);
+
+   if (pressed)
+   device->key_mask[index] |= (1ULL << bit);
+   else
+   device->key_mask[index] &= ~(1ULL << bit);
+}
+
+void
+evdev_keyboard_notify_key(struct evdev_device *device,
+ uint32_t time,
+ int key,
+ enum libinput_key_state state)
+{
+   struct libinput *libinput = device->base.seat->libinput;
+
+   if ((state == LIBINPUT_KEY_STATE_PRESSED &&
+get_key_state(device, key) != 0) ||
+   (state == LIBINPUT_KEY_STATE_RELEASED &&
+get_key_state(device, key) != 1)) {
+   log_bug_kernel(
+   libinput,
+   "%s: Driver sent multiple (0x%x) pressed/released",
+   device->devnode, key);
+   return;
+   }
+
+   set_key_state(device, key, state == LIBINPUT_KEY_STATE_PRESSED);
+
+   keyboard_notify_key(&device->base, time, key, state);
+}
+
+void
+evdev_pointer_notify_button(struct evdev_device *device,
+   uint32_t time,
+   int button,
+   enum libinput_button_state state)
+{
+   struct libinput *libinput = device->base.seat->libinput;
+
+   if ((state == LIBINPUT_BUTTON_STATE_PRESSED &&
+get_key_state(device, button) != 0) ||
+   (state == LIBINPUT_BUTTON_STATE_RELEASED &&
+get_key_state(device, button) != 1)) {
+   log_bug_kernel(
+   libinput,
+   "%s: Driver sent multiple (0%x) pressed/released",
+   device->devnode, button);
+   return;
+   }
+
+   set_key_state(device, button, state == LIBINPUT_BUTTON_STATE_PRESSED);
+
+   pointer_notify_button(&device->base, time, button, state);
+}
+
 void
 evdev_device_led_update(struct evdev_device *device, enum libinput_led leds)
 {
@@ -278,6 +361,45 @@ get_key_type(uint16_t code)
 }
 
 static void
+release_pressed_keys(struct evdev_device *device)
+{
+   struct libinput *libinput = device->base.seat->libinput;
+   struct timespec ts;
+   uint64_t time;
+   int code;
+
+   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
+   log_error(libinput, "clock_gettime: %s\n", strerror(errno));
+   return;
+   }
+
+   time = ts.tv_sec * 1000ULL + ts.tv_nsec / 100;
+
+   for (code = 0; code < KEY_CNT; code++) {
+   if (get_key_state(device, code) == 1) {
+   switch (get_key_type(code)) {
+  

[PATCH libinput 3/8] test: Remove test device from context when deleting

2014-07-16 Thread Jonas Ådahl
Signed-off-by: Jonas Ådahl 
---
 test/litest.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/litest.c b/test/litest.c
index b64c7e3..961b917 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -605,6 +605,7 @@ litest_delete_device(struct litest_device *d)
return;
 
libinput_device_unref(d->libinput_device);
+   libinput_path_remove_device(d->libinput_device);
if (d->owns_context)
libinput_unref(d->libinput);
libevdev_free(d->evdev);
-- 
1.8.5.1

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


Re: [PATCH 10/11] weston-image --help works. Also help if no filename is given

2014-07-16 Thread Bill Spitzak

On 07/09/2014 06:32 PM, Jason Ekstrand wrote:


 > One little nitpick: Should we really be returning 1 if --help is
given?  That's not an error.

On second thought, I ran a bunch of little utilities and things and some
of them always given an error with the usage and others don't.  However,
if we're going to claim to have a --help or -h option, we shouldn't
error on it.  Considering it to be malformed input and printing an error
message is fine.


Yea, these patches were mainly concerned with getting all the programs 
to not run and produce usage information if there is anything wrong with 
the argument line. In most cases -h "works" to print the help because it 
is not recognized, so the return value is the same. I was most concerned 
with making these demos a little less annoying for somebody unfamiliar 
with them, not sure if it is worth it to complicate them to make them 
return different values depending on whether -h is passed or not.


In addition, unix command-line utilities are pretty inconsistent about 
whether they return success or failure when they print usage 
information. Some succeed all the time, some fail all the time.



Perhaps the thing to do in this client is to simply have failing to open
the file dump the usage.


That should print an error describing why it can't open the file. I will 
post a patch that fixes that.



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


[PATCH 3/4] add get_geometry & geometry request/event

2014-07-16 Thread Marek Chalupa
---
 protocol/wayland-test.xml | 11 +++
 tests/weston-test-client-helper.c | 18 ++
 tests/weston-test-client-helper.h |  6 ++
 tests/weston-test.c   | 23 +++
 4 files changed, 58 insertions(+)

diff --git a/protocol/wayland-test.xml b/protocol/wayland-test.xml
index 18b6625..b4a6bc7 100644
--- a/protocol/wayland-test.xml
+++ b/protocol/wayland-test.xml
@@ -3,6 +3,7 @@
 
   
 Copyright © 2012 Intel Corporation
+Copyright © 2014 Red Hat, Inc.
 
 Permission to use, copy, modify, distribute, and sell this
 software and its documentation for any purpose is hereby granted
@@ -58,5 +59,15 @@
 
   
 
+
+  
+
+
+  
+  
+  
+  
+  
+
   
 
diff --git a/tests/weston-test-client-helper.c 
b/tests/weston-test-client-helper.c
index b1dbd04..4510241 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -468,9 +468,27 @@ test_handle_n_egl_buffers(void *data, struct wl_test 
*wl_test, uint32_t n)
test->n_egl_buffers = n;
 }
 
+static void
+test_handle_geometry(void *data, struct wl_test *wl_test,
+struct wl_surface *surface,
+uint32_t width, uint32_t height,
+int32_t x, int32_t y)
+{
+   struct test *test = data;
+
+   test->geometry.width = width;
+   test->geometry.height = height;
+   test->geometry.x = x;
+   test->geometry.y = y;
+
+   fprintf(stderr, "test-client: got geometry w: %u, h: %u, x: %d y: %d\n",
+   width, height, x, y);
+}
+
 static const struct wl_test_listener test_listener = {
test_handle_pointer_position,
test_handle_n_egl_buffers,
+   test_handle_geometry,
 };
 
 static void
diff --git a/tests/weston-test-client-helper.h 
b/tests/weston-test-client-helper.h
index 231cb61..add607f 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -57,6 +57,12 @@ struct test {
int pointer_x;
int pointer_y;
uint32_t n_egl_buffers;
+   struct {
+   uint32_t width;
+   uint32_t height;
+   int32_t x;
+   int32_t y;
+   } geometry;
 };
 
 struct input {
diff --git a/tests/weston-test.c b/tests/weston-test.c
index 75a0884..44875a6 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -221,6 +221,28 @@ get_n_buffers(struct wl_client *client, struct wl_resource 
*resource)
wl_test_send_n_egl_buffers(resource, n_buffers);
 }
 
+static void
+get_geometry(struct wl_client *client, struct wl_resource *resource,
+struct wl_resource *surface_resource)
+{
+   struct weston_view *view;
+   struct weston_surface *surface =
+   wl_resource_get_user_data (surface_resource);
+
+   if (surface->configure)
+   view = wl_container_of(surface->views.next, view, surface_link);
+   else
+   view = surface->configure_private;
+
+   /* not created yet */
+   if (!view)
+   return;
+
+   wl_test_send_geometry(resource, surface_resource,
+ surface->width, surface->height,
+ view->geometry.x, view->geometry.y);
+}
+
 static const struct wl_test_interface test_implementation = {
move_surface,
move_pointer,
@@ -228,6 +250,7 @@ static const struct wl_test_interface test_implementation = 
{
activate_surface,
send_key,
get_n_buffers,
+   get_geometry
 };
 
 static void
-- 
2.0.1

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


Use xdg-shell in tests

2014-07-16 Thread Marek Chalupa
Hi,

in this series of patches I added support for xdg-shell/surface
to the test-suite.

The thing that led me to this is captured in the last patch, that is
that maximizing and fullscreening didn't work as expected for really
simple client (just bare xdg-surface and nothing more). However, I'm
not sure if that was error in client or bug in weston, so I created
this tests and I'd like to ask you for review - maybe it's really bug,
maybe I've just forgotten something.

Thanks,
Marek

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


[PATCH 1/4] tests: simplify move_client and make it more generic

2014-07-16 Thread Marek Chalupa
Move client right in the move_client funciton. This allows the surface
use its own configure function, so from now the client can be any
weston surface (xdg, wl_shell, ..)
---
 tests/weston-test.c | 62 +
 1 file changed, 24 insertions(+), 38 deletions(-)

diff --git a/tests/weston-test.c b/tests/weston-test.c
index 35ccaa4..75a0884 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -41,13 +41,6 @@ struct weston_test {
struct weston_process process;
 };
 
-struct weston_test_surface {
-   struct weston_surface *surface;
-   struct weston_view *view;
-   int32_t x, y;
-   struct weston_test *test;
-};
-
 static void
 test_client_sigchld(struct weston_process *process, int status)
 {
@@ -88,19 +81,15 @@ notify_pointer_position(struct weston_test *test, struct 
wl_resource *resource)
 }
 
 static void
-test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+update_position(struct weston_test *test, struct weston_view *view,
+   int32_t x, int32_t y)
 {
-   struct weston_test_surface *test_surface = surface->configure_private;
-   struct weston_test *test = test_surface->test;
-
-   if (wl_list_empty(&test_surface->view->layer_link))
+   if (wl_list_empty(&view->layer_link))
wl_list_insert(&test->layer.view_list,
-  &test_surface->view->layer_link);
+  &view->layer_link);
 
-   weston_view_set_position(test_surface->view,
-test_surface->x, test_surface->y);
-
-   weston_view_update_transform(test_surface->view);
+   weston_view_set_position(view, x, y);
+   weston_view_update_transform(view);
 }
 
 static void
@@ -110,31 +99,28 @@ move_surface(struct wl_client *client, struct wl_resource 
*resource,
 {
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
-   struct weston_test_surface *test_surface;
-
-   test_surface = surface->configure_private;
-   if (!test_surface) {
-   test_surface = malloc(sizeof *test_surface);
-   if (!test_surface) {
-   wl_resource_post_no_memory(resource);
-   return;
-   }
+   struct weston_test *test = wl_resource_get_user_data(resource);
+   struct weston_view *view;
 
-   test_surface->view = weston_view_create(surface);
-   if (!test_surface->view) {
-   wl_resource_post_no_memory(resource);
-   free(test_surface);
-   return;
+   /* has shell surface? */
+   if (surface->configure) {
+   view = wl_container_of(surface->views.next, view, surface_link);
+   assert (view && "No view in surface views list");
+   } else {
+   if (!surface->configure_private) {
+   view = weston_view_create(surface);
+   if (!view) {
+   wl_resource_post_no_memory(resource);
+   return;
+   }
+
+   surface->configure_private = view;
+   } else {
+   view = surface->configure_private;
}
-
-   surface->configure_private = test_surface;
-   surface->configure = test_surface_configure;
}
 
-   test_surface->surface = surface;
-   test_surface->test = wl_resource_get_user_data(resource);
-   test_surface->x = x;
-   test_surface->y = y;
+   update_position(test, view, x, y);
 }
 
 static void
-- 
2.0.1

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


[PATCH 2/4] tests: handle xdg events in client

2014-07-16 Thread Marek Chalupa
Bind to xdg-shell, create xdg-surface and handle event comming
from it.
---
 Makefile.am   |   4 +-
 tests/weston-test-client-helper.c | 133 --
 tests/weston-test-client-helper.h |   9 +++
 3 files changed, 140 insertions(+), 6 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 191dcc9..d7a07d2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -902,7 +902,9 @@ libtest_client_la_SOURCES = \
tests/weston-test-client-helper.h
 nodist_libtest_client_la_SOURCES = \
protocol/wayland-test-protocol.c\
-   protocol/wayland-test-client-protocol.h
+   protocol/wayland-test-client-protocol.h \
+   protocol/xdg-shell-protocol.c   \
+   protocol/xdg-shell-client-protocol.h
 libtest_client_la_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
 libtest_client_la_LIBADD = $(TEST_CLIENT_LIBS) libshared.la libtest-runner.la
 
diff --git a/tests/weston-test-client-helper.c 
b/tests/weston-test-client-helper.c
index 186b395..b1dbd04 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -293,6 +293,115 @@ static const struct wl_surface_listener surface_listener 
= {
surface_leave
 };
 
+
+static void
+xdg_shell_handle_ping (void *data, struct xdg_shell *xdg_shell, uint32_t 
serial)
+{
+   struct client *client = data;
+
+   if (client->last_ping_serial && client->last_ping_serial != serial - 1)
+   fprintf(stderr, "test-client: got non-sequential ping serial."
+   "(%u instead of %u)\n", serial,
+   client->last_ping_serial + 1);
+
+   client->last_ping_serial = serial;
+
+   xdg_shell_pong (xdg_shell, serial);
+   fprintf (stderr, "test-client: got ping with serial %u, sent pong\n", 
serial);
+}
+
+static const struct xdg_shell_listener xdg_shell_listener = {
+   xdg_shell_handle_ping
+};
+
+static void
+resize_surface(struct client *client, int32_t width, int32_t height)
+{
+   struct surface *surface = client->surface;
+
+   if (!width && !height)
+   return;
+
+   assert(surface->wl_surface);
+
+   if (surface->wl_buffer)
+   wl_buffer_destroy(surface->wl_buffer);
+
+   surface->wl_buffer = create_shm_buffer(client, width, height,
+  &surface->data);
+   assert(surface->wl_buffer);
+
+   memset(surface->data, 64, width * height * 4);
+
+   wl_surface_attach(surface->wl_surface, surface->wl_buffer, 0, 0);
+   wl_surface_damage(surface->wl_surface, 0, 0, width, height);
+   wl_surface_commit(surface->wl_surface);
+
+   surface->width = width;
+   surface->height = height;
+}
+
+static void
+xdg_surface_handle_configure (void *data, struct xdg_surface *xdg_surface,
+ int32_t width, int32_t height,
+ struct wl_array *states, uint32_t serial)
+{
+   struct client *client = data;
+   struct surface *surface = client->surface;
+   enum xdg_surface_state *st;
+
+   fprintf (stderr, "test-client: xdg_surface.configure:\n");
+   fprintf (stderr, "\twidth: %d, height: %d\n", width, height);
+
+   surface->fullscreen = 0;
+   surface->maximized = 0;
+   surface->resizing = 0;
+   surface->activated = 0;
+
+   wl_array_for_each(st, states) {
+   switch (*st) {
+   case XDG_SURFACE_STATE_FULLSCREEN:
+   fprintf (stderr, "\tfullscreen\n");
+   surface->fullscreen = 1;
+   break;
+   case XDG_SURFACE_STATE_MAXIMIZED:
+   fprintf (stderr, "\tmaximized\n");
+   surface->maximized = 1;
+   break;
+   case XDG_SURFACE_STATE_RESIZING:
+   fprintf (stderr, "\tresizing\n");
+   surface->resizing = 1;
+   break;
+   case XDG_SURFACE_STATE_ACTIVATED:
+   fprintf (stderr, "\tactivated\n");
+   surface->activated = 1;
+   break;
+   default:
+   assert (0 && "Unkown state");
+   }
+   }
+
+   if (surface->width != width || surface->height != height)
+   resize_surface(client, width, height);
+
+   xdg_surface_ack_configure (xdg_surface, serial);
+}
+
+static void
+xdg_surface_handle_close (void *data, struct xdg_surface *xdg_surface)
+{
+   struct client *client = data;
+
+   client->surface->close = 1;
+
+   fprintf (stderr, "test-client: xdg_surface.close\n");
+}
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+   xdg_surface_handle_configure,
+   xdg_surface_handle_close
+};
+
 struct wl_buffer *
 create_shm_buffer(struct client *client, int width, int height, void **pixels)
 {

[PATCH 4/4] tests: add client test

2014-07-16 Thread Marek Chalupa
Test xdg-shell features.
Add tests for maximizing and fullscreening the client.
---
 Makefile.am |   7 +++-
 tests/client-test.c | 114 
 2 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 tests/client-test.c

diff --git a/Makefile.am b/Makefile.am
index d7a07d2..e95c6e7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -831,7 +831,8 @@ weston_tests =  \
event.weston\
button.weston   \
text.weston \
-   subsurface.weston
+   subsurface.weston   \
+   client.weston
 
 
 AM_TESTS_ENVIRONMENT = \
@@ -924,6 +925,10 @@ button_weston_SOURCES = tests/button-test.c
 button_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
 button_weston_LDADD = libtest-client.la
 
+client_weston_SOURCES = tests/client-test.c
+client_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+client_weston_LDADD = libtest-client.la
+
 text_weston_SOURCES = tests/text-test.c
 nodist_text_weston_SOURCES =   \
protocol/text-protocol.c\
diff --git a/tests/client-test.c b/tests/client-test.c
new file mode 100644
index 000..0f80222
--- /dev/null
+++ b/tests/client-test.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include 
+#include "weston-test-client-helper.h"
+#include "xdg-shell-client-protocol.h"
+
+static struct client *
+setup(void)
+{
+   struct client *client;
+
+   client = client_create(100, 100, 200, 200);
+   assert(client);
+
+   if (!client->xdg_shell)
+   skip("Need xdg-shell for this test\n");
+
+   wl_test_get_geometry(client->test->wl_test, 
client->surface->wl_surface);
+   client_roundtrip(client);
+
+   assert(client->test->geometry.x == 100);
+   assert(client->test->geometry.y == 100);
+   assert(client->test->geometry.width == 200);
+   assert(client->test->geometry.height == 200);
+
+   return client;
+}
+
+TEST(create_xdg_client_test)
+{
+   /* sort of sanity test. Create client and check if it is on
+* the right place and has the right size */
+   setup();
+}
+
+TEST(simple_maximize_test)
+{
+   struct client *client = setup();
+
+   xdg_surface_set_maximized(client->surface->xdg_surface);
+   client_roundtrip(client);
+
+   wl_test_get_geometry(client->test->wl_test, 
client->surface->wl_surface);
+   client_roundtrip(client);
+
+   assert(client->test->geometry.x == 0);
+   assert(client->test->geometry.y == 0);
+   /* hmm, what should be the height? Anyway, the width should be the same
+* as of the output */
+   assert(client->test->geometry.width = client->output->width);
+
+   xdg_surface_unset_maximized(client->surface->xdg_surface);
+   client_roundtrip(client);
+
+   wl_test_get_geometry(client->test->wl_test, 
client->surface->wl_surface);
+   client_roundtrip(client);
+
+   /* the old size and position should get recovered */
+   assert(client->test->geometry.x == 100);
+   assert(client->test->geometry.y == 100);
+   assert(client->test->geometry.width == 200);
+   assert(client->test->geometry.height == 200);
+}
+
+TEST(simple_fullscreen_test)
+{
+   struct client *client = setup();
+
+   xdg_surface_set_fullscreen(client->surface->xdg_surface,
+  client->output->wl_output);
+   client_roundtrip(client);
+
+   wl_test_get_geometry(client->test->wl_test, 
client->surface->wl_surface);
+   client_roundtrip(client);
+
+   assert(client->test->geometry.x == 0);
+   assert(client->test->geometry.y == 0);
+   assert(client->t

Re: New guy

2014-07-16 Thread Stefanos A.
2014-07-16 14:14 GMT+02:00 Magnus Hoff :

> Hi Jasper :) Thanks for your response! :)
>
> On Tue, Jul 15, 2014 at 1:59 PM, Jasper St. Pierre
>  wrote:
> > On Tue, Jul 15, 2014 at 7:48 AM, Magnus Hoff 
> > wrote:
> >>  * Support for (sub-)pixel resolution of two-finger scroll. In X.org,
> >> two-finger scroll is mapped to button-events, which means that the
> >> resolution of scrolling is reduced to line-level. Can we support such
> >> smooth scrolling in wayland?
> >
> >
> > Smooth scrolling is supported in XI2 by some special axes, but not a lot
> of
> > applications support this.
>
> XI2... is that this thing?
> http://www.x.org/releases/X11R7.6/doc/inputproto/XI2proto.txt
>
> So, you're telling me that X.org does indeed support smooth scrolling,
> but I have not experienced it because (basically) none of the
> applications have implemented support?
>

Exactly.

Gnome 3 applications tend to have smooth scrolling support, provided your
touchpad drivers support it. Try testing with gedit or web (the web
browser), for example. Alternatively, run "xinput --test-xi2" in a terminal
and try two-finger scrolling. If you see floating-point values, then your
system supports smooth scrolling.

(Unfortunately, the scrolling acceleration curve is terrible, at least for
synaptics, so smooth scrolling is simply not as good as it could/should be.)

> Scrolling in Wayland is done by the "axis" event [0], which describes
> > relative changes on an axis, and not by button presses. So apps couldn't
> do
> > chunky scrolling even if they wanted to!
>
> That sounds good :)
>

Tell that to SDL2, which still thinks scrolling is happening in integer
chunks. Yeah, one whole class of applications that really *could* use
smooth scrolling, namely games, simply does not support that when using the
leading toolkit.

It's the same chicken-and-egg problem as XI2: to get smooth scrolling you
have to jump over so many hoops that prefer to simple use core X11 events.
Yes, scrolling sucks then, but the code is dead simple: just add a new case
in a switch statement. (It doesn't help that XI2 documentation is hard to
come by, compared to X11 documentation. The only available sample code is
found in Peter Hutterer's blog and half a dozen random repositories, like
Qt...)

Which is to say, libinput/Wayland do the right thing here: provide the
proper solution in the common code path, so application developers can't go
wrong even if they try. Hopefully, this will mean that Firefox/Chrome etc
will finally get proper smooth scrolling on Linux. Here's to hoping!

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


Re: New guy

2014-07-16 Thread Magnus Hoff
Hi Jasper :) Thanks for your response! :)

On Tue, Jul 15, 2014 at 1:59 PM, Jasper St. Pierre
 wrote:
> On Tue, Jul 15, 2014 at 7:48 AM, Magnus Hoff 
> wrote:
>>  * Support for (sub-)pixel resolution of two-finger scroll. In X.org,
>> two-finger scroll is mapped to button-events, which means that the
>> resolution of scrolling is reduced to line-level. Can we support such
>> smooth scrolling in wayland?
>
>
> Smooth scrolling is supported in XI2 by some special axes, but not a lot of
> applications support this.

XI2... is that this thing?
http://www.x.org/releases/X11R7.6/doc/inputproto/XI2proto.txt

So, you're telling me that X.org does indeed support smooth scrolling,
but I have not experienced it because (basically) none of the
applications have implemented support?


> Scrolling in Wayland is done by the "axis" event [0], which describes
> relative changes on an axis, and not by button presses. So apps couldn't do
> chunky scrolling even if they wanted to!

That sounds good :)

However, the reason I brought this issue up is that I can't seem to do
two-finger scrolling at all in wayland/weston. Does weston-terminal
support this? Or any of the other example apps?

I see now that scrolling works for X-apps running on Xwayland (both
for stand-alone weston and weston nested inside X), so maybe my
problem is primarily that none of my wayland apps support scrolling?

I have noticed what looks like a bug, by the way: When turning smooth
scrolling into chunky scrolling, the system doesn't seem to accumulate
fractional chunks, so if you're moving your fingers slower than a
threshold speed, no scrolling happens.


> If you're running Weston under X11, then that doesn't have support for XI2
> smooth scrolling, it just uses the button presses [1]. The nested X11 is
> more meant as a testing and debugging, so it only supports core events. If
> you want to get XI2 and smooth scrolling working for the nested X11
> compositor, I don't think anybody would mind.

Ah, cool. Noted. But maybe Weston under X11 isn't the most important component.


>> * Similar support for several-finger-gestures. In X.org, I use
>> touchegg to switch workspaces by a four-finger swipe. The interaction
>> is like this: 1. put four fingers on touchpad, 2. swipe left/right, 3.
>> let fingers go, 4. observe that the workspace changes. The
>> corresponding interaction in OS X is like this: 1. put three fingers
>> on touchpad, 2. as I swipe left or right, the workspaces on the screen
>> respond proportionately by moving right/left, 3. as I let go, one of
>> the workspaces snap to fill the screen.
>
>
>> The feedback in OS X is immediate, making the interaction feel much
>> better and leaves the user with a much greater feeling of control. Can
>> we support this in wayland?
>
>
> XI2 is really unfortunate with how its protocol handles touch. We recently
> added gesture support in GNOME for X11. I'm not too familiar with it myself,
> so I'm CC'ing Carlos Garnacho, who wrote our gestures implementation, to see
> if he has any feedback about whether the Wayland protocol works fine and
> would allow for really smooth gestures.

OK. I would love smooth gestures, so I would appreciate input here :)


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


[PATCH v2 3/3] tests: use expect_protocol_error in tests

2014-07-16 Thread Marek Chalupa
Turn FAIL_TESTs to TESTs. FAIL_TESTs are bad...
---
 tests/bad-buffer-test.c | 35 +--
 tests/subsurface-test.c | 40 
 2 files changed, 29 insertions(+), 46 deletions(-)

diff --git a/tests/bad-buffer-test.c b/tests/bad-buffer-test.c
index 86e0299..3b54ac6 100644
--- a/tests/bad-buffer-test.c
+++ b/tests/bad-buffer-test.c
@@ -60,34 +60,12 @@ create_bad_shm_buffer(struct client *client, int width, int 
height)
return buffer;
 }
 
-static void sighandler(int signum)
-{
-   /* this means failure */
-   exit(0);
-}
-
-FAIL_TEST(test_truncated_shm_file)
+TEST(test_truncated_shm_file)
 {
struct client *client;
struct wl_buffer *bad_buffer;
struct wl_surface *surface;
int frame;
-   struct sigaction new_action, old_action;
-
-   /* until the bad buffer creation, the SIGABRT or SIGSEGV signals
-* should fail the test. That means returning 0 */
-   new_action.sa_handler = sighandler;
-   sigemptyset(&new_action.sa_mask);
-   new_action.sa_flags = 0;
-
-   if (sigaction(SIGSEGV, &new_action, NULL) != 0) {
-   fprintf(stderr, "Failed setting new sigaction for SIGSEGV");
-   exit(0);
-   }
-   if (sigaction(SIGABRT, &new_action, &old_action) != 0) {
-   fprintf(stderr, "Failed setting new sigaction for SIGABRT");
-   exit(0);
-   }
 
client = client_create(46, 76, 111, 134);
assert(client);
@@ -95,15 +73,12 @@ FAIL_TEST(test_truncated_shm_file)
 
bad_buffer = create_bad_shm_buffer(client, 200, 200);
 
-   /* from this point we expect the signal */
-   if (sigaction(SIGABRT, &old_action, NULL) != 0) {
-   fprintf(stderr, "Failed setting old sigaction for SIGABRT");
-   exit(0);
-   }
-
wl_surface_attach(surface, bad_buffer, 0, 0);
wl_surface_damage(surface, 0, 0, 200, 200);
frame_callback_set(surface, &frame);
wl_surface_commit(surface);
-   frame_callback_wait(client, &frame);
+   frame_callback_wait_nofail(client, &frame);
+
+   expect_protocol_error(client, &wl_buffer_interface,
+ WL_SHM_ERROR_INVALID_FD);
 }
diff --git a/tests/subsurface-test.c b/tests/subsurface-test.c
index 0670e7f..bee249b 100644
--- a/tests/subsurface-test.c
+++ b/tests/subsurface-test.c
@@ -133,7 +133,7 @@ TEST(test_subsurface_placement_protocol)
client_roundtrip(client);
 }
 
-FAIL_TEST(test_subsurface_paradox)
+TEST(test_subsurface_paradox)
 {
struct client *client;
struct wl_surface *parent;
@@ -148,10 +148,11 @@ FAIL_TEST(test_subsurface_paradox)
/* surface is its own parent */
wl_subcompositor_get_subsurface(subco, parent, parent);
 
-   client_roundtrip(client);
+   expect_protocol_error(client, &wl_subcompositor_interface,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE);
 }
 
-FAIL_TEST(test_subsurface_identical_link)
+TEST(test_subsurface_identical_link)
 {
struct client *client;
struct compound_surface com;
@@ -164,10 +165,11 @@ FAIL_TEST(test_subsurface_identical_link)
/* surface is already a subsurface */
wl_subcompositor_get_subsurface(com.subco, com.child[0], com.parent);
 
-   client_roundtrip(client);
+   expect_protocol_error(client, &wl_subcompositor_interface,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE);
 }
 
-FAIL_TEST(test_subsurface_change_link)
+TEST(test_subsurface_change_link)
 {
struct client *client;
struct compound_surface com;
@@ -182,7 +184,8 @@ FAIL_TEST(test_subsurface_change_link)
/* surface is already a subsurface */
wl_subcompositor_get_subsurface(com.subco, com.child[0], stranger);
 
-   client_roundtrip(client);
+   expect_protocol_error(client, &wl_subcompositor_interface,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE);
 }
 
 TEST(test_subsurface_nesting)
@@ -221,7 +224,7 @@ TEST(test_subsurface_nesting_parent)
client_roundtrip(client);
 }
 
-FAIL_TEST(test_subsurface_loop_paradox)
+TEST(test_subsurface_loop_paradox)
 {
struct client *client;
struct wl_surface *surface[3];
@@ -240,10 +243,11 @@ FAIL_TEST(test_subsurface_loop_paradox)
wl_subcompositor_get_subsurface(subco, surface[2], surface[1]);
wl_subcompositor_get_subsurface(subco, surface[0], surface[2]);
 
-   client_roundtrip(client);
+   expect_protocol_error(client, &wl_subcompositor_interface,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE);
 }
 
-FAIL_TEST(test_subsurface_place_above_stranger)
+TEST(test_subsurface_place_above_stranger)
 {
struct client *client;
struct compound_surface com;
@@ -258,10 +262,11 @@ FAIL_TEST(test_subsurface_place_above_stranger)
/* bad sibling */
wl_subsurface_place_above(com.sub[0], stranger);
 
-   

[PATCH v2 2/3] tests: add frame_callback_wait_nofail

2014-07-16 Thread Marek Chalupa
With expect_protocol_error, we need a possibility to wait for a frame
without aborting the test when wl_display_dispatch returns -1;
This patch adds function frame_callback_wait_nofail that only
returns 1 or 0 (instead of aborting on error).
---
 tests/weston-test-client-helper.c | 9 ++---
 tests/weston-test-client-helper.h | 6 --
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/tests/weston-test-client-helper.c 
b/tests/weston-test-client-helper.c
index 92cee9f..79097fa 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -80,12 +80,15 @@ frame_callback_set(struct wl_surface *surface, int *done)
return callback;
 }
 
-void
-frame_callback_wait(struct client *client, int *done)
+int
+frame_callback_wait_nofail(struct client *client, int *done)
 {
while (!*done) {
-   assert(wl_display_dispatch(client->wl_display) >= 0);
+   if (wl_display_dispatch(client->wl_display) < 0)
+   return 0;
}
+
+   return 1;
 }
 
 void
diff --git a/tests/weston-test-client-helper.h 
b/tests/weston-test-client-helper.h
index f154661..684afc6 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -120,8 +120,10 @@ move_client(struct client *client, int x, int y);
 struct wl_callback *
 frame_callback_set(struct wl_surface *surface, int *done);
 
-void
-frame_callback_wait(struct client *client, int *done);
+int
+frame_callback_wait_nofail(struct client *client, int *done);
+
+#define frame_callback_wait(c, d) assert(frame_callback_wait_nofail((c), (d)))
 
 int
 get_n_egl_buffers(struct client *client);
-- 
2.0.1

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


[PATCH 1/3] tests: add expect_protocol_error function

2014-07-16 Thread Marek Chalupa
This function checks if a particular protocol error came in wire.
It's usefull in the cases where we hitherto used FAIL_TEST.
The problem with FAIL_TEST is that *any* assert will pass the test,
but we want only some asserts to pass the test (i. e. we don't
want the test to pass when it, for example, can't connect to display).
FAIL_TESTs are good only for sanity testing.

The expect_protocol_error allows us to turn all FAIL_TESTs to TESTs
as will be introduced in following patches.

v2: fixed white-space error and a mistake in comment

Reviewed-by: Bryce Harrington 
---
 tests/weston-test-client-helper.c | 48 +++
 tests/weston-test-client-helper.h |  4 
 2 files changed, 52 insertions(+)

diff --git a/tests/weston-test-client-helper.c 
b/tests/weston-test-client-helper.c
index 186b395..92cee9f 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "../shared/os-compatibility.h"
@@ -512,6 +513,53 @@ skip(const char *fmt, ...)
exit(77);
 }
 
+void
+expect_protocol_error(struct client *client,
+ const struct wl_interface *intf,
+ uint32_t code)
+{
+   int err;
+   uint32_t errcode, failed = 0;
+   const struct wl_interface *interface;
+   unsigned int id;
+
+   /* if the error has not come yet, make it happen */
+   wl_display_roundtrip(client->wl_display);
+
+   err = wl_display_get_error(client->wl_display);
+
+   assert(err && "Expected protocol error but nothing came");
+   assert(err == EPROTO && "Expected protocol error but got local error");
+
+   errcode = wl_display_get_protocol_error(client->wl_display,
+   &interface, &id);
+
+   /* check error */
+   if (errcode != code) {
+   fprintf(stderr, "Should get error code %d but got %d\n",
+   code, errcode);
+   failed = 1;
+   }
+
+   /* this should be definitely set */
+   assert(interface);
+
+   if (strcmp(intf->name, interface->name) != 0) {
+   fprintf(stderr, "Should get interface '%s' but got '%s'\n",
+   intf->name, interface->name);
+   failed = 1;
+   }
+
+   if (failed) {
+   fprintf(stderr, "Expected other protocol error\n");
+   abort();
+   }
+
+   /* all OK */
+   fprintf(stderr, "Got expected protocol error on '%s' (object id: %d) "
+   "with code %d\n", interface->name, id, errcode);
+}
+
 static void
 log_handler(const char *fmt, va_list args)
 {
diff --git a/tests/weston-test-client-helper.h 
b/tests/weston-test-client-helper.h
index 4bfc3fa..f154661 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -129,4 +129,8 @@ get_n_egl_buffers(struct client *client);
 void
 skip(const char *fmt, ...);
 
+void
+expect_protocol_error(struct client *client,
+ const struct wl_interface *intf, uint32_t code);
+
 #endif
-- 
2.0.1

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


Re: [PATCH 1/3] tests: add expect_protocol_error function

2014-07-16 Thread Marek Chalupa
Hi,

I fixed the comment as Bryce wrote (s/came/come) and fixed a white-space
error.
The logic of this version of the patch is equivalent to the old one.

Thanks,
Marek


On 7 July 2014 20:41, Bryce W. Harrington  wrote:

> On Mon, Jul 07, 2014 at 05:47:41PM +0300, Pekka Paalanen wrote:
> > On Thu, 19 Jun 2014 02:37:40 +
> > "Bryce W. Harrington"  wrote:
> >
> > > On Mon, May 26, 2014 at 04:58:05PM +0200, Marek Chalupa wrote:
> > > > This function checks if a particular protocol error came in wire.
> > > > It's usefull in the cases where we hitherto used FAIL_TEST.
> > > > The problem with FAIL_TEST is that *any* assert will pass the test,
> > > > but we want only some asserts to pass the test (i. e. we don't
> > > > want the test to pass when it, for example, can't connect to
> display).
> > > > FAIL_TESTs are good only for sanity testing.
> > > >
> > > > The expect_protocol_error allows us to turn all FAIL_TESTs to TESTs
> > > > as will be introduced in following patches.
> > > > ---
> > > >  tests/weston-test-client-helper.c | 49
> +++
> > > >  tests/weston-test-client-helper.h |  4 
> > > >  2 files changed, 53 insertions(+)
> > > >
> > > > diff --git a/tests/weston-test-client-helper.c
> b/tests/weston-test-client-helper.c
> > > > index 186b395..fb2e477 100644
> > > > --- a/tests/weston-test-client-helper.c
> > > > +++ b/tests/weston-test-client-helper.c
> > > > @@ -26,6 +26,7 @@
> > > >  #include 
> > > >  #include 
> > > >  #include 
> > > > +#include 
> > > >  #include 
> > > >
> > > >  #include "../shared/os-compatibility.h"
> > > > @@ -512,6 +513,54 @@ skip(const char *fmt, ...)
> > > >   exit(77);
> > > >  }
> > > >
> > > > +void
> > > > +expect_protocol_error(struct client *client,
> > > > +   const struct wl_interface *intf,
> > > > +   uint32_t code)
> > > > +{
> > > > + int err;
> > > > + uint32_t errcode, failed = 0;
> > > > + const struct wl_interface *interface;
> > > > + unsigned int id;
> > > > +
> > > > + /* if the error has not came yet, make it happen */
> > >
> > > "has not come yet"
> > >
> > > > + wl_display_roundtrip(client->wl_display);
> > > > +
> > > > + err = wl_display_get_error(client->wl_display);
> > > > +
> > > > + assert(err && "Expected protocol error but nothing came");
> > > > + assert(err == EPROTO && "Expected protocol error but got local
> error");
> > > > +
> > > > +
> > > > + errcode = wl_display_get_protocol_error(client->wl_display,
> > > > + &interface, &id);
> > > > +
> > > > + /* check error */
> > > > + if (errcode != code) {
> > > > + fprintf(stderr, "Should get error code %d but got %d\n",
> > > > + code, errcode);
> > > > + failed = 1;
> > > > + }
> > > > +
> > > > + /* this should be definitely set */
> > > > + assert(interface);
> > > > +
> > > > + if (strcmp(intf->name, interface->name) != 0) {
> > > > + fprintf(stderr, "Should get interface '%s' but got '%s'\n",
> > > > + intf->name, interface->name);
> > > > + failed = 1;
> > > > + }
> > > > +
> > > > + if (failed) {
> > > > + fprintf(stderr, "Expected other protocol error\n");
> > > > + abort();
> > > > + }
> > > > +
> > > > + /* all OK */
> > > > + fprintf(stderr, "Got expected protocol error on '%s' (object id:
> %d) "
> > > > + "with code %d\n", interface->name, id, errcode);
> > > > +}
> > > > +
> > >
> > > I think if you move the assert higher, you can condense the logic a
> > > bit.  Maybe it's clearer:
> > >
> > > /* this should be definitely set */
> > > assert(interface);
> > >
> > > if (errcode != code) {
> > > fprintf(stderr, "Should get error code %d but got %d\n",
> > > code, errcode);
> > > } else if (strcmp(intf->name, interface->name) != 0) {
> > > fprintf(stderr, "Should get interface '%s' but got '%s'\n",
> > > intf->name, interface->name);
> > > } else {
> > > fprintf(stderr, "Got expected protocol error on '%s'
> (object id: %d) "
> > > "with code %d\n", interface->name, id, errcode);
> > > return;
> > > }
> > >
> > > fprintf(stderr, "Expected a different protocol error\n");
> > > abort();
> > > }
> > >
> > > I wonder if the final error message is a bit redundant.
> > >
> > > >  static void
> > > >  log_handler(const char *fmt, va_list args)
> > > >  {
> > > > diff --git a/tests/weston-test-client-helper.h
> b/tests/weston-test-client-helper.h
> > > > index 4bfc3fa..f154661 100644
> > > > --- a/tests/weston-test-client-helper.h
> > > > +++ b/tests/weston-test-client-helper.h
> > > > @@ -129,4 +129,8 @@ get_n_egl_buffers(struct client *client);
> > > >  void
> > > >  skip(const char *fmt, ...);
> > > >
> > > > +void
> > > > +expect_protocol_error(struct client *client,
> > > > +   const struct wl_interface *intf, uint32_t code);

Re: [PATCH wayland] client: add a public function to make a roundtrip on a custom queue

2014-07-16 Thread Giulio Camuffo
2014-07-15 20:39 GMT+03:00 Daniel Stone :
> Hi,
>
>
> On Tuesday, July 15, 2014, Giulio Camuffo  wrote:
>>
>> 2014-07-14 22:31 GMT+03:00 Jason Ekstrand :
>> > Guilio,
>> > Would it be better to name it wl_event_queue_roundtrip and just have it
>> > take
>> > the wl_event_queue?  I guess it is sort-of a wl_display operation, but
>> > you
>> > could argue it either way.  Thoughts?
>>
>> You have a point here, it makes more sense.
>
>
> TBH I'd rather steer clear of that nomenclature, since the 'queue' in an
> immediate request context implies delayed dispatch, rather than on a queue.

I didn't realize you could read it as "queue a roundtrip on a
wl_event". I think that the meaning is quite obvious once you know
that there is a wl_event_queue type in Wayland.

Giulio

>
> Sorry for being that bikeshed guy ...
> -d
>
>
>>
>> > --Jason Ekstrand
>> >
>> >
>> > On Mon, Jul 14, 2014 at 7:15 AM, Giulio Camuffo
>> > 
>> > wrote:
>> >>
>> >> wl_display_roundtrip() works on the default queue. Add a parallel
>> >> wl_display_roundtrip_queue().
>> >> ---
>> >>
>> >> v3: fixed dispatch call in place of dispatch_queue
>> >> documented the queue parameter
>> >>  src/wayland-client.c | 24 +---
>> >>  src/wayland-client.h |  2 ++
>> >>  2 files changed, 23 insertions(+), 3 deletions(-)
>> >>
>> >> diff --git a/src/wayland-client.c b/src/wayland-client.c
>> >> index e8aab7e..d2c1b5c 100644
>> >> --- a/src/wayland-client.c
>> >> +++ b/src/wayland-client.c
>> >> @@ -834,15 +834,16 @@ static const struct wl_callback_listener
>> >> sync_listener = {
>> >>  /** Block until all pending request are processed by the server
>> >>   *
>> >>   * \param display The display context object
>> >> + * \param queue The queue on which to run the roundtrip
>> >>   * \return The number of dispatched events on success or -1 on failure
>> >>   *
>> >>   * Blocks until the server process all currently issued requests and
>> >> - * sends out pending events on all event queues.
>> >> + * sends out pending events on the event queue.
>> >>   *
>> >>   * \memberof wl_display
>> >>   */
>> >>  WL_EXPORT int
>> >> -wl_display_roundtrip(struct wl_display *display)
>> >> +wl_display_roundtrip_queue(struct wl_display *display, struct
>> >> wl_event_queue *queue)
>> >>  {
>> >> struct wl_callback *callback;
>> >> int done, ret = 0;
>> >> @@ -851,9 +852,10 @@ wl_display_roundtrip(struct wl_display *display)
>> >> callback = wl_display_sync(display);
>> >> if (callback == NULL)
>> >> return -1;
>> >> +   wl_proxy_set_queue(callback, queue);
>> >> wl_callback_add_listener(callback, &sync_listener, &done);
>> >> while (!done && ret >= 0)
>> >> -   ret = wl_display_dispatch(display);
>> >> +   ret = wl_display_dispatch_queue(display, queue);
>> >>
>> >> if (ret == -1 && !done)
>> >> wl_callback_destroy(callback);
>> >> @@ -861,6 +863,22 @@ wl_display_roundtrip(struct wl_display *display)
>> >> return ret;
>> >>  }
>> >>
>> >> +/** Block until all pending request are processed by the server
>> >> + *
>> >> + * \param display The display context object
>> >> + * \return The number of dispatched events on success or -1 on failure
>> >> + *
>> >> + * Blocks until the server process all currently issued requests and
>> >> + * sends out pending events on the default event queue.
>> >> + *
>> >> + * \memberof wl_display
>> >> + */
>> >> +WL_EXPORT int
>> >> +wl_display_roundtrip(struct wl_display *display)
>> >> +{
>> >> +   wl_display_roundtrip_queue(display, &display->default_queue);
>> >> +}
>> >> +
>> >>  static int
>> >>  create_proxies(struct wl_proxy *sender, struct wl_closure *closure)
>> >>  {
>> >> diff --git a/src/wayland-client.h b/src/wayland-client.h
>> >> index 2a32785..4377207 100644
>> >> --- a/src/wayland-client.h
>> >> +++ b/src/wayland-client.h
>> >> @@ -163,6 +163,8 @@ int wl_display_dispatch_pending(struct wl_display
>> >> *display);
>> >>  int wl_display_get_error(struct wl_display *display);
>> >>
>> >>  int wl_display_flush(struct wl_display *display);
>> >> +int wl_display_roundtrip_queue(struct wl_display *display,
>> >> +   struct wl_event_queue *queue);
>> >>  int wl_display_roundtrip(struct wl_display *display);
>> >>  struct wl_event_queue *wl_display_create_queue(struct wl_display
>> >> *display);
>> >>
>> >> --
>> >> 2.0.1
>> >>
>> >> ___
>> >> wayland-devel mailing list
>> >> wayland-devel@lists.freedesktop.org
>> >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>> >
>> >
>> ___
>> wayland-devel mailing list
>> wayland-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinf