forked from 12to11/12to11
Add scroll valuator tests
* 12to11-test.xml (test_manager): <error>: New errors. (test_XIDeviceInfo, test_device_controller): New interfaces. (test_seat_controller): <get_device_controller>: New request. <device_id>: New event. * seat.c (NoticeDeviceDisabled): Ignore test seats. (XLSeatDispatchCoreKeyEvent): Expand commentary. * test_seat.c (struct _TestDeviceController) (struct _TestXIDeviceInfo): New structs. (DestroyXIValuatorState): New function. (AddValuatorToTestXIValuatorState): Fix crashes. (XIValuatorState_impl): Add DestroyXIValuatorState. (DestroyDeviceInfo, SetDeviceId, SetName, SetUse, SetAttachment) (SetEnabled, AddXIScrollClassInfo, AddXIValuatorClassInfo): New functions. (XIDeviceInfo_impl): New interface implementation. (HandleXIDeviceInfoDestroy): New function. (DestroyDeviceController, AddDeviceInfo, GetDeviceInfo): New functions. (device_controller_impl): New interface. (HandleTestDeviceControllerDestroy): New function. (GetDeviceController): New function. (seat_controller_impl): Add it. (XLGetTestSeat): Send new `device_id' event. * tests/seat_test.c (enum test_expect_event_kind): Add POINTER_AXIS_VALUE120_EVENT. (struct test_recorded_axis_value120_event): New event kind. (enum test_kind): Add TEST_VALUATOR_KIND. (test_names): Add test_valuator. (LAST_TEST): Set to TEST_VALUATOR_KIND. (run_valuator_test): New function. (test_single_step): Implement accordingly. (expect_axis_value120_event, handle_pointer_axis_value120): New functions. * tests/test_harness.c (handle_seat_controller_device_id): New function. (seat_controller_listener): New listener. (test_init_seat): Wait for device ID and init device controller. * tests/test_harness.h (struct test_seat): Add device controller and device ID fields.
This commit is contained in:
parent
e2afe671df
commit
163dca96bd
6 changed files with 992 additions and 12 deletions
168
12to11-test.xml
168
12to11-test.xml
|
@ -45,6 +45,14 @@
|
||||||
summary="an invalid version was specified"/>
|
summary="an invalid version was specified"/>
|
||||||
<entry name="invalid_valuator" value="7"
|
<entry name="invalid_valuator" value="7"
|
||||||
summary="the specified valuator is invalid"/>
|
summary="the specified valuator is invalid"/>
|
||||||
|
<entry name="invalid_device_id" value="8"
|
||||||
|
summary="the specified device ID is too small"/>
|
||||||
|
<entry name="incomplete_device_info" value="9"
|
||||||
|
summary="the specified device info is incomplete"/>
|
||||||
|
<entry name="device_exists" value="10"
|
||||||
|
summary="the specified artifical device already exists"/>
|
||||||
|
<entry name="invalid_label" value="11"
|
||||||
|
summary="the specified label is invalid"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="get_test_surface">
|
<request name="get_test_surface">
|
||||||
|
@ -239,12 +247,156 @@
|
||||||
</request>
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
|
<interface name="test_XIDeviceInfo" version="1">
|
||||||
|
<description summary="XInput 2 device information">
|
||||||
|
Simulated XInput 2 device information for a device.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy test device info">
|
||||||
|
Destroy the test device info resource.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_device_id">
|
||||||
|
<description summary="set the device ID">
|
||||||
|
Set the device ID of this device info structure to the
|
||||||
|
specified ID. If the ID is less than 65536, post an
|
||||||
|
invalid_device_id error.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="device_id" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_name">
|
||||||
|
<description summary="set the device name">
|
||||||
|
Set the name of this device to the specified name.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="name" type="string"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_use">
|
||||||
|
<description summary="set the device use">
|
||||||
|
Set the use of this device to the specified value.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="use" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_attachment">
|
||||||
|
<description summary="set the device attachment">
|
||||||
|
Set the device attachment to the master pointer and keyboard
|
||||||
|
of the specified seat controller.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="attachment" type="object"
|
||||||
|
interface="test_seat_controller"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_enabled">
|
||||||
|
<description summary="set device enabled">
|
||||||
|
Set whether or not the device is enabled.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="enabled" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="add_XIScrollClassInfo">
|
||||||
|
<description summary="add a scroll class to the device information">
|
||||||
|
Add a scroll class with the specified type, source ID, number,
|
||||||
|
scroll type, increment and flags to the device info.
|
||||||
|
|
||||||
|
If the specified source device ID is less than 65536, post an
|
||||||
|
invalid_device_id error.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="sourceid" type="int"/>
|
||||||
|
<arg name="number" type="int"/>
|
||||||
|
<arg name="scroll_type" type="int"/>
|
||||||
|
<arg name="increment" type="fixed"/>
|
||||||
|
<arg name="flags" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="add_XIValuatorClassInfo">
|
||||||
|
<description summary="add a valuator class to the device information">
|
||||||
|
Add a valuator class with the specified type, source ID,
|
||||||
|
number, label, min, max, value, resolution and mode to the
|
||||||
|
device info.
|
||||||
|
|
||||||
|
If the specified source device ID is less than 65536, post an
|
||||||
|
invalid_device_id error.
|
||||||
|
|
||||||
|
Intern the label into an atom. If the string is empty, raise
|
||||||
|
an invalid_label error.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="sourceid" type="int"/>
|
||||||
|
<arg name="number" type="int"/>
|
||||||
|
<arg name="label" type="string"/>
|
||||||
|
<arg name="min" type="fixed"/>
|
||||||
|
<arg name="max" type="fixed"/>
|
||||||
|
<arg name="value" type="fixed"/>
|
||||||
|
<arg name="resolution" type="int"/>
|
||||||
|
<arg name="mode" type="int"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="test_device_controller" version="1">
|
||||||
|
<description summary="test device controller">
|
||||||
|
This object allows registering a list of artificial input
|
||||||
|
devices to use during tests. These devices must have a device
|
||||||
|
ID larger than 65535, and are removed upon destruction of the
|
||||||
|
test controller resource.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy test device controller">
|
||||||
|
Destroy the test device controller resource.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="add_device_info">
|
||||||
|
<description summary="add artificial device">
|
||||||
|
Register a device with the specified device information. If
|
||||||
|
the device info is incomplete, meaning that one of
|
||||||
|
set_device_id, set_name, set_use, set_attachment, or
|
||||||
|
set_enabled was not called after it was created, post an
|
||||||
|
incomplete_device_info error. If the device ID already
|
||||||
|
exists, post a device_exists error if the device was not
|
||||||
|
created by this device controller, or update the device with
|
||||||
|
the new information if it was.
|
||||||
|
|
||||||
|
If a test seat is created with the device ID in the specified
|
||||||
|
device info after add_device_info is called, then the seat
|
||||||
|
will not possess this device info.
|
||||||
|
|
||||||
|
The device will be removed upon destruction of the
|
||||||
|
test_device_controller resource.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="device_info" type="object" interface="test_XIDeviceInfo"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_device_info">
|
||||||
|
<description summary="create device info">
|
||||||
|
Create a device information object. The device information
|
||||||
|
object is not associated with the test controller in any way.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="id" type="new_id" interface="test_XIDeviceInfo"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
<interface name="test_seat_controller" version="1">
|
<interface name="test_seat_controller" version="1">
|
||||||
<description summary="test seat">
|
<description summary="test seat">
|
||||||
This object extends a wl_seat created with the
|
This object extends a wl_seat created with the
|
||||||
test_manager.get_test_seat request with several requests to
|
test_manager.get_test_seat request with several requests to
|
||||||
dispatch generated events.
|
dispatch generated events.
|
||||||
|
|
||||||
|
Immediately after being created, a device_id event is sent with
|
||||||
|
the device ID of this seat.
|
||||||
|
|
||||||
If the seat associated with the test controller is destroyed by
|
If the seat associated with the test controller is destroyed by
|
||||||
the time a request is made with the test controller, the latter
|
the time a request is made with the test controller, the latter
|
||||||
request is simply ignored.
|
request is simply ignored.
|
||||||
|
@ -420,5 +572,21 @@
|
||||||
<arg name="group" type="object" interface="test_XIModifierState"
|
<arg name="group" type="object" interface="test_XIModifierState"
|
||||||
allow-null="true"/>
|
allow-null="true"/>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
|
<request name="get_device_controller">
|
||||||
|
<description summary="get device controller">
|
||||||
|
Obtain a new device controller.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="id" type="new_id" interface="test_device_controller"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="device_id">
|
||||||
|
<description summary="device ID">
|
||||||
|
This event is sent immediately after the test_seat_controller
|
||||||
|
is created, with the device ID of the test seat.
|
||||||
|
</description>
|
||||||
|
<arg name="device_id" type="uint"/>
|
||||||
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
</protocol>
|
</protocol>
|
||||||
|
|
16
seat.c
16
seat.c
|
@ -95,6 +95,7 @@ enum
|
||||||
IsInPinchGesture = (1 << 9),
|
IsInPinchGesture = (1 << 9),
|
||||||
IsInSwipeGesture = (1 << 10),
|
IsInSwipeGesture = (1 << 10),
|
||||||
IsTestSeat = (1 << 11),
|
IsTestSeat = (1 << 11),
|
||||||
|
IsTestDeviceSpecified = (1 << 12),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -2189,7 +2190,9 @@ NoticeDeviceDisabled (int deviceid)
|
||||||
|
|
||||||
seat = XLLookUpAssoc (seats, deviceid);
|
seat = XLLookUpAssoc (seats, deviceid);
|
||||||
|
|
||||||
if (seat)
|
/* Test seats should not be destroyed here. */
|
||||||
|
|
||||||
|
if (seat && !(seat->flags & IsTestSeat))
|
||||||
{
|
{
|
||||||
/* The device has been disabled, mark the seat inert and
|
/* The device has been disabled, mark the seat inert and
|
||||||
dereference it. The seat is still referred to by the
|
dereference it. The seat is still referred to by the
|
||||||
|
@ -6181,13 +6184,16 @@ XLSeatDispatchCoreKeyEvent (Seat *seat, Surface *surface, XEvent *event,
|
||||||
if (keysym)
|
if (keysym)
|
||||||
{
|
{
|
||||||
/* If looking up the event keycode also results in the keysym,
|
/* If looking up the event keycode also results in the keysym,
|
||||||
then just use the keycode specified in the event. */
|
then just use the keycode specified in the event. This is
|
||||||
|
because French keyboard layouts have multiple keycodes that
|
||||||
|
decode to the same keysym, which causes problems later on
|
||||||
|
when Wayland clients keep repeating the "a" key, as a keysym
|
||||||
|
was looked up for the key press but not for the corresponding
|
||||||
|
key release. */
|
||||||
if (XkbLookupKeySym (compositor.display, event->xkey.keycode,
|
if (XkbLookupKeySym (compositor.display, event->xkey.keycode,
|
||||||
event->xkey.state, &mods_return, &sym_return)
|
event->xkey.state, &mods_return, &sym_return)
|
||||||
&& keysym == sym_return)
|
&& keysym == sym_return)
|
||||||
{
|
keycode = event->xkey.keycode;
|
||||||
keycode = event->xkey.keycode;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
keycode = XKeysymToKeycode (compositor.display, keysym);
|
keycode = XKeysymToKeycode (compositor.display, keysym);
|
||||||
|
|
||||||
|
|
453
test_seat.c
453
test_seat.c
|
@ -23,9 +23,11 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
have to include anything itself! */
|
have to include anything itself! */
|
||||||
|
|
||||||
typedef struct _TestSeatController TestSeatController;
|
typedef struct _TestSeatController TestSeatController;
|
||||||
|
typedef struct _TestDeviceController TestDeviceController;
|
||||||
typedef struct _TestXIModifierState TestXIModifierState;
|
typedef struct _TestXIModifierState TestXIModifierState;
|
||||||
typedef struct _TestXIValuatorState TestXIValuatorState;
|
typedef struct _TestXIValuatorState TestXIValuatorState;
|
||||||
typedef struct _TestXIButtonState TestXIButtonState;
|
typedef struct _TestXIButtonState TestXIButtonState;
|
||||||
|
typedef struct _TestXIDeviceInfo TestXIDeviceInfo;
|
||||||
|
|
||||||
/* The current test seat counter. */
|
/* The current test seat counter. */
|
||||||
static unsigned int test_seat_counter;
|
static unsigned int test_seat_counter;
|
||||||
|
@ -42,6 +44,18 @@ struct _TestSeatController
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _TestDeviceController
|
||||||
|
{
|
||||||
|
/* The associated struct wl_resource. */
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
/* Array of device IDs used by this test device controller. */
|
||||||
|
int *device_ids;
|
||||||
|
|
||||||
|
/* Number of device IDs associated with this controller. */
|
||||||
|
int num_ids;
|
||||||
|
};
|
||||||
|
|
||||||
struct _TestXIModifierState
|
struct _TestXIModifierState
|
||||||
{
|
{
|
||||||
/* Modifier state. These fields mean the same as they do in
|
/* Modifier state. These fields mean the same as they do in
|
||||||
|
@ -73,6 +87,43 @@ struct _TestXIButtonState
|
||||||
unsigned char mask[XIMaskLen (8)];
|
unsigned char mask[XIMaskLen (8)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
StateDeviceIdSet = 1,
|
||||||
|
StateNameSet = 1 << 1,
|
||||||
|
StateUseSet = 1 << 2,
|
||||||
|
StateAttachmentSet = 1 << 3,
|
||||||
|
StateEnabledSet = 1 << 4,
|
||||||
|
StateComplete = 0x1f,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TestXIDeviceInfo
|
||||||
|
{
|
||||||
|
/* The associated resource. */
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
/* The device name. */
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* Array of classes. */
|
||||||
|
XIAnyClassInfo **classes;
|
||||||
|
|
||||||
|
/* The device ID. */
|
||||||
|
int device_id;
|
||||||
|
|
||||||
|
/* The use, attachment. */
|
||||||
|
int use, attachment;
|
||||||
|
|
||||||
|
/* Whether or not the device is enabled. */
|
||||||
|
Bool enabled;
|
||||||
|
|
||||||
|
/* The number of classes there are. */
|
||||||
|
int num_classes;
|
||||||
|
|
||||||
|
/* How many fields are set. */
|
||||||
|
int state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -168,6 +219,13 @@ HandleXIButtonStateDestroy (struct wl_resource *resource)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DestroyXIValuatorState (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AddValuatorToTestXIValuatorState (struct wl_client *client,
|
AddValuatorToTestXIValuatorState (struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
|
@ -200,7 +258,7 @@ AddValuatorToTestXIValuatorState (struct wl_client *client,
|
||||||
if (state->mask_len < XIMaskLen (valuator))
|
if (state->mask_len < XIMaskLen (valuator))
|
||||||
{
|
{
|
||||||
state->mask = XLRealloc (state->mask,
|
state->mask = XLRealloc (state->mask,
|
||||||
state->mask_len);
|
XIMaskLen (valuator));
|
||||||
|
|
||||||
/* Clear the newly allocated part of the mask. */
|
/* Clear the newly allocated part of the mask. */
|
||||||
memset (state->mask + state->mask_len,
|
memset (state->mask + state->mask_len,
|
||||||
|
@ -221,7 +279,7 @@ AddValuatorToTestXIValuatorState (struct wl_client *client,
|
||||||
if (i == valuator)
|
if (i == valuator)
|
||||||
/* Insert the new value. */
|
/* Insert the new value. */
|
||||||
new_values[j++] = wl_fixed_to_double (value);
|
new_values[j++] = wl_fixed_to_double (value);
|
||||||
else if (XIMaskIsSet (state->mask, valuator))
|
else if (XIMaskIsSet (state->mask, i))
|
||||||
/* Use the old value. */
|
/* Use the old value. */
|
||||||
new_values[j++] = *old_values++;
|
new_values[j++] = *old_values++;
|
||||||
}
|
}
|
||||||
|
@ -238,6 +296,7 @@ AddValuatorToTestXIValuatorState (struct wl_client *client,
|
||||||
|
|
||||||
static const struct test_XIValuatorState_interface XIValuatorState_impl =
|
static const struct test_XIValuatorState_interface XIValuatorState_impl =
|
||||||
{
|
{
|
||||||
|
.destroy = DestroyXIValuatorState,
|
||||||
.add_valuator = AddValuatorToTestXIValuatorState,
|
.add_valuator = AddValuatorToTestXIValuatorState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -261,8 +320,355 @@ HandleXIValuatorStateDestroy (struct wl_resource *resource)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DestroyTestSeatController (struct wl_client *client,
|
DestroyDeviceInfo (struct wl_client *client, struct wl_resource *resource)
|
||||||
struct wl_resource *resource)
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetDeviceId (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t device_id)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (device_id < 65536)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, TEST_MANAGER_ERROR_INVALID_DEVICE_ID,
|
||||||
|
"invalid device id specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->device_id = device_id;
|
||||||
|
info->state |= StateDeviceIdSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetName (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (info->name)
|
||||||
|
XLFree (info->name);
|
||||||
|
info->name = XLStrdup (name);
|
||||||
|
info->state |= StateNameSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetUse (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
int32_t use)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
info->use = use;
|
||||||
|
info->state |= StateUseSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetAttachment (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
struct wl_resource *attachment_resource)
|
||||||
|
{
|
||||||
|
TestSeatController *controller;
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
|
||||||
|
controller = wl_resource_get_user_data (attachment_resource);
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
info->attachment = controller->seat->master_pointer;
|
||||||
|
info->state |= StateAttachmentSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetEnabled (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t enabled)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
info->enabled = True;
|
||||||
|
else
|
||||||
|
info->enabled = False;
|
||||||
|
info->state |= StateEnabledSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
AddXIScrollClassInfo (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
int32_t sourceid, int32_t number, int32_t scroll_type,
|
||||||
|
wl_fixed_t increment, int32_t flags)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
XIScrollClassInfo *class;
|
||||||
|
|
||||||
|
if (sourceid < 65536)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, TEST_MANAGER_ERROR_INVALID_DEVICE_ID,
|
||||||
|
"invalid device ID specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
class = XLMalloc (sizeof *class);
|
||||||
|
class->type = XIScrollClass;
|
||||||
|
class->sourceid = sourceid;
|
||||||
|
class->number = number;
|
||||||
|
class->scroll_type = scroll_type;
|
||||||
|
class->increment = wl_fixed_to_double (increment);
|
||||||
|
class->flags = flags;
|
||||||
|
|
||||||
|
/* Extend info->classes to hold more classes. */
|
||||||
|
info->num_classes++;
|
||||||
|
info->classes = XLRealloc (info->classes,
|
||||||
|
sizeof *info->classes * info->num_classes);
|
||||||
|
|
||||||
|
/* Attach the class. */
|
||||||
|
info->classes[info->num_classes - 1] = (XIAnyClassInfo *) class;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
AddXIValuatorClassInfo (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
int32_t sourceid, int32_t number, const char *label,
|
||||||
|
wl_fixed_t min, wl_fixed_t max, wl_fixed_t value,
|
||||||
|
int32_t resolution, int32_t mode)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
XIValuatorClassInfo *class;
|
||||||
|
|
||||||
|
if (sourceid < 65536)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, TEST_MANAGER_ERROR_INVALID_DEVICE_ID,
|
||||||
|
"invalid device ID specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Avoid interning empty strings. */
|
||||||
|
|
||||||
|
if (!strlen (label))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource, TEST_MANAGER_ERROR_INVALID_LABEL,
|
||||||
|
"the specified label is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
class = XLMalloc (sizeof *class);
|
||||||
|
class->type = XIValuatorClass;
|
||||||
|
class->sourceid = sourceid;
|
||||||
|
class->number = number;
|
||||||
|
class->label = InternAtom (label);
|
||||||
|
class->min = wl_fixed_to_double (min);
|
||||||
|
class->max = wl_fixed_to_double (max);
|
||||||
|
class->value = wl_fixed_to_double (value);
|
||||||
|
class->resolution = resolution;
|
||||||
|
class->mode = mode;
|
||||||
|
|
||||||
|
/* Extend info->classes to hold more classes. */
|
||||||
|
info->num_classes++;
|
||||||
|
info->classes = XLRealloc (info->classes,
|
||||||
|
sizeof *info->classes * info->num_classes);
|
||||||
|
|
||||||
|
/* Attach the class. */
|
||||||
|
info->classes[info->num_classes - 1] = (XIAnyClassInfo *) class;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct test_XIDeviceInfo_interface XIDeviceInfo_impl =
|
||||||
|
{
|
||||||
|
.destroy = DestroyDeviceInfo,
|
||||||
|
.set_device_id = SetDeviceId,
|
||||||
|
.set_name = SetName,
|
||||||
|
.set_use = SetUse,
|
||||||
|
.set_attachment = SetAttachment,
|
||||||
|
.set_enabled = SetEnabled,
|
||||||
|
.add_XIScrollClassInfo = AddXIScrollClassInfo,
|
||||||
|
.add_XIValuatorClassInfo = AddXIValuatorClassInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
HandleXIDeviceInfoDestroy (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
info = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
/* Free the name. */
|
||||||
|
XLFree (info->name);
|
||||||
|
|
||||||
|
/* Free each of the classes. */
|
||||||
|
for (i = 0; i < info->num_classes; ++i)
|
||||||
|
XLFree (info->classes[i]);
|
||||||
|
|
||||||
|
/* Free the class array. */
|
||||||
|
XLFree (info->classes);
|
||||||
|
|
||||||
|
/* Free the info itself. */
|
||||||
|
XLFree (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DestroyDeviceController (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
AddDeviceInfo (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
struct wl_resource *device_info)
|
||||||
|
{
|
||||||
|
TestDeviceController *controller;
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
Seat *seat;
|
||||||
|
DeviceInfo *deviceinfo;
|
||||||
|
int i;
|
||||||
|
XIDeviceInfo test_info;
|
||||||
|
|
||||||
|
/* Add a virtual device to the device controller. */
|
||||||
|
controller = wl_resource_get_user_data (resource);
|
||||||
|
info = wl_resource_get_user_data (device_info);
|
||||||
|
|
||||||
|
/* First, ensure that the device info is completely specified. */
|
||||||
|
|
||||||
|
if ((info->state & StateComplete) != StateComplete)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (resource,
|
||||||
|
TEST_MANAGER_ERROR_INCOMPLETE_DEVICE_INFO,
|
||||||
|
"the specified device information was not"
|
||||||
|
" completely specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next, check whether or not a device already exists. */
|
||||||
|
seat = XLLookUpAssoc (seats, info->device_id);
|
||||||
|
deviceinfo = XLLookUpAssoc (devices, info->device_id);
|
||||||
|
|
||||||
|
if ((seat && seat->flags & IsTestDeviceSpecified) || deviceinfo)
|
||||||
|
{
|
||||||
|
/* If a device already exists, see whether or not it was created
|
||||||
|
by this test device controller. */
|
||||||
|
|
||||||
|
for (i = 0; i < controller->num_ids; ++i)
|
||||||
|
{
|
||||||
|
if (controller->device_ids[i] == info->device_id)
|
||||||
|
/* It was created by this controller. Simply update the
|
||||||
|
values. */
|
||||||
|
goto continue_update;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, post an error. */
|
||||||
|
wl_resource_post_error (resource,
|
||||||
|
TEST_MANAGER_ERROR_DEVICE_EXISTS,
|
||||||
|
"the device %d already exists, and was "
|
||||||
|
"not created by this controller",
|
||||||
|
info->device_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue_update:
|
||||||
|
|
||||||
|
/* Now, construct the XIDeviceInfo. */
|
||||||
|
test_info.deviceid = info->device_id;
|
||||||
|
test_info.name = info->name;
|
||||||
|
test_info.use = info->use;
|
||||||
|
test_info.attachment = info->attachment;
|
||||||
|
test_info.enabled = info->enabled;
|
||||||
|
test_info.num_classes = info->num_classes;
|
||||||
|
test_info.classes = info->classes;
|
||||||
|
|
||||||
|
/* If the seat exists, repopulate its valuators with that specified
|
||||||
|
in the device info. */
|
||||||
|
|
||||||
|
if (seat)
|
||||||
|
{
|
||||||
|
FreeValuators (seat);
|
||||||
|
UpdateValuators (seat, &test_info);
|
||||||
|
|
||||||
|
/* Next, set a flag that means the seat has its information
|
||||||
|
provided by device info. */
|
||||||
|
seat->flags |= IsTestDeviceSpecified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now, record the device info. */
|
||||||
|
RecordDeviceInformation (&test_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GetDeviceInfo (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
TestXIDeviceInfo *info;
|
||||||
|
|
||||||
|
info = XLSafeMalloc (sizeof *info);
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
{
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (info, 0, sizeof *info);
|
||||||
|
info->resource
|
||||||
|
= wl_resource_create (client, &test_XIDeviceInfo_interface,
|
||||||
|
wl_resource_get_version (resource), id);
|
||||||
|
|
||||||
|
if (!info->resource)
|
||||||
|
{
|
||||||
|
XLFree (info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_set_implementation (info->resource, &XIDeviceInfo_impl,
|
||||||
|
info, HandleXIDeviceInfoDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct test_device_controller_interface device_controller_impl =
|
||||||
|
{
|
||||||
|
.destroy = DestroyDeviceController,
|
||||||
|
.add_device_info = AddDeviceInfo,
|
||||||
|
.get_device_info = GetDeviceInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
HandleTestDeviceControllerDestroy (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
TestDeviceController *controller;
|
||||||
|
int i;
|
||||||
|
Seat *seat;
|
||||||
|
|
||||||
|
controller = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
/* Remove each device associated with the device controller. */
|
||||||
|
for (i = 0; i < controller->num_ids; ++i)
|
||||||
|
{
|
||||||
|
NoticeDeviceDisabled (controller->device_ids[i]);
|
||||||
|
|
||||||
|
/* NoticeDeviceDisabled is special-cased to not free valuators
|
||||||
|
for test seats. If there is a seat associated with this
|
||||||
|
device ID, free the valuators on it as well. */
|
||||||
|
seat = XLLookUpAssoc (seats, controller->device_ids[i]);
|
||||||
|
FreeValuators (seat);
|
||||||
|
|
||||||
|
/* Clear the test device specified flag. */
|
||||||
|
seat->flags &= ~IsTestDeviceSpecified;
|
||||||
|
}
|
||||||
|
|
||||||
|
XLFree (controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DestroySeatController (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
wl_resource_destroy (resource);
|
wl_resource_destroy (resource);
|
||||||
}
|
}
|
||||||
|
@ -664,9 +1070,41 @@ DispatchXIButtonRelease (struct wl_client *client, struct wl_resource *resource,
|
||||||
DispatchTestEvent (controller, event, (XIEvent *) &test_event);
|
DispatchTestEvent (controller, event, (XIEvent *) &test_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GetDeviceController (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
TestDeviceController *controller;
|
||||||
|
|
||||||
|
controller = XLSafeMalloc (sizeof *controller);
|
||||||
|
|
||||||
|
if (!controller)
|
||||||
|
{
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (controller, 0, sizeof *controller);
|
||||||
|
controller->resource
|
||||||
|
= wl_resource_create (client, &test_device_controller_interface,
|
||||||
|
wl_resource_get_version (resource), id);
|
||||||
|
|
||||||
|
if (!controller->resource)
|
||||||
|
{
|
||||||
|
XLFree (controller);
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_set_implementation (controller->resource,
|
||||||
|
&device_controller_impl,
|
||||||
|
controller,
|
||||||
|
HandleTestDeviceControllerDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct test_seat_controller_interface seat_controller_impl =
|
static const struct test_seat_controller_interface seat_controller_impl =
|
||||||
{
|
{
|
||||||
.destroy = DestroyTestSeatController,
|
.destroy = DestroySeatController,
|
||||||
.bind_seat = BindSeat,
|
.bind_seat = BindSeat,
|
||||||
.get_XIModifierState = GetXIModifierState,
|
.get_XIModifierState = GetXIModifierState,
|
||||||
.get_XIButtonState = GetXIButtonState,
|
.get_XIButtonState = GetXIButtonState,
|
||||||
|
@ -676,6 +1114,7 @@ static const struct test_seat_controller_interface seat_controller_impl =
|
||||||
.dispatch_XI_Motion = DispatchXIMotion,
|
.dispatch_XI_Motion = DispatchXIMotion,
|
||||||
.dispatch_XI_ButtonPress = DispatchXIButtonPress,
|
.dispatch_XI_ButtonPress = DispatchXIButtonPress,
|
||||||
.dispatch_XI_ButtonRelease = DispatchXIButtonRelease,
|
.dispatch_XI_ButtonRelease = DispatchXIButtonRelease,
|
||||||
|
.get_device_controller = GetDeviceController,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -787,4 +1226,8 @@ XLGetTestSeat (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
|
||||||
wl_resource_set_implementation (controller->resource, &seat_controller_impl,
|
wl_resource_set_implementation (controller->resource, &seat_controller_impl,
|
||||||
controller, HandleControllerResourceDestroy);
|
controller, HandleControllerResourceDestroy);
|
||||||
|
|
||||||
|
/* Send the device ID to the client. */
|
||||||
|
test_seat_controller_send_device_id (controller->resource,
|
||||||
|
seat->master_pointer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ enum test_expect_event_kind
|
||||||
POINTER_MOTION_EVENT,
|
POINTER_MOTION_EVENT,
|
||||||
POINTER_LEAVE_EVENT,
|
POINTER_LEAVE_EVENT,
|
||||||
POINTER_BUTTON_EVENT,
|
POINTER_BUTTON_EVENT,
|
||||||
|
POINTER_AXIS_VALUE120_EVENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct test_recorded_event
|
struct test_recorded_event
|
||||||
|
@ -82,6 +83,18 @@ struct test_recorded_button_event
|
||||||
uint32_t button, state;
|
uint32_t button, state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct test_recorded_axis_value120_event
|
||||||
|
{
|
||||||
|
/* The event header. */
|
||||||
|
struct test_recorded_event header;
|
||||||
|
|
||||||
|
/* The axis. */
|
||||||
|
uint32_t axis;
|
||||||
|
|
||||||
|
/* The value120. */
|
||||||
|
int32_t value120;
|
||||||
|
};
|
||||||
|
|
||||||
struct test_subsurface
|
struct test_subsurface
|
||||||
{
|
{
|
||||||
/* The subsurface itself. */
|
/* The subsurface itself. */
|
||||||
|
@ -97,6 +110,7 @@ enum test_kind
|
||||||
TEST_ENTRY_KIND,
|
TEST_ENTRY_KIND,
|
||||||
TEST_CLICK_KIND,
|
TEST_CLICK_KIND,
|
||||||
TEST_GRAB_KIND,
|
TEST_GRAB_KIND,
|
||||||
|
TEST_VALUATOR_KIND,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *test_names[] =
|
static const char *test_names[] =
|
||||||
|
@ -105,9 +119,10 @@ static const char *test_names[] =
|
||||||
"test_entry",
|
"test_entry",
|
||||||
"test_click",
|
"test_click",
|
||||||
"test_grab",
|
"test_grab",
|
||||||
|
"test_valuator",
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LAST_TEST TEST_GRAB_KIND
|
#define LAST_TEST TEST_VALUATOR_KIND
|
||||||
#define TEST_SOURCE_DEVICE 4500000
|
#define TEST_SOURCE_DEVICE 4500000
|
||||||
|
|
||||||
/* The display. */
|
/* The display. */
|
||||||
|
@ -148,6 +163,7 @@ static void expect_enter_event (struct wl_surface *, double, double);
|
||||||
static void expect_motion_event (double, double);
|
static void expect_motion_event (double, double);
|
||||||
static void expect_leave_event (void);
|
static void expect_leave_event (void);
|
||||||
static void expect_button_event (int, int);
|
static void expect_button_event (int, int);
|
||||||
|
static void expect_axis_value120_event (uint32_t, int32_t);
|
||||||
static void expect_no_events (void);
|
static void expect_no_events (void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -466,6 +482,159 @@ run_grab_test (struct test_XIButtonState *button_state,
|
||||||
expect_enter_event (wayland_surface, 0.0, 0.0);
|
expect_enter_event (wayland_surface, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_valuator_test (void)
|
||||||
|
{
|
||||||
|
struct test_XIDeviceInfo *info;
|
||||||
|
struct test_XIValuatorState *valuator_state;
|
||||||
|
|
||||||
|
/* First, create the device info. */
|
||||||
|
info
|
||||||
|
= test_device_controller_get_device_info (display->seat->device_controller);
|
||||||
|
|
||||||
|
/* Send the first leave event. */
|
||||||
|
test_seat_controller_dispatch_XI_Leave (display->seat->controller,
|
||||||
|
test_get_time (),
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
XINotifyAncestor,
|
||||||
|
test_get_root (),
|
||||||
|
test_surface_window,
|
||||||
|
None,
|
||||||
|
wl_fixed_from_double (-1.0),
|
||||||
|
wl_fixed_from_double (-1.0),
|
||||||
|
wl_fixed_from_double (-1.0),
|
||||||
|
wl_fixed_from_double (-1.0),
|
||||||
|
XINotifyNormal,
|
||||||
|
False, True,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
/* Set the device ID and add the valuators. */
|
||||||
|
test_XIDeviceInfo_set_device_id (info, display->seat->device_id);
|
||||||
|
test_XIDeviceInfo_set_use (info, XIMasterPointer);
|
||||||
|
test_XIDeviceInfo_set_attachment (info, display->seat->controller);
|
||||||
|
test_XIDeviceInfo_set_name (info, "Test virtual pointer");
|
||||||
|
test_XIDeviceInfo_set_enabled (info, 1);
|
||||||
|
test_XIDeviceInfo_add_XIScrollClassInfo (info,
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
1,
|
||||||
|
XIScrollTypeVertical,
|
||||||
|
wl_fixed_from_double (1.0),
|
||||||
|
XIScrollFlagPreferred);
|
||||||
|
test_XIDeviceInfo_add_XIScrollClassInfo (info,
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
2,
|
||||||
|
XIScrollTypeHorizontal,
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
XIScrollFlagPreferred);
|
||||||
|
test_XIDeviceInfo_add_XIValuatorClassInfo (info,
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
1,
|
||||||
|
"Rel Scroll Vertical",
|
||||||
|
wl_fixed_from_double (0.0),
|
||||||
|
wl_fixed_from_double (0.0),
|
||||||
|
wl_fixed_from_double (0.0),
|
||||||
|
1,
|
||||||
|
XIModeRelative);
|
||||||
|
test_XIDeviceInfo_add_XIValuatorClassInfo (info,
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
2,
|
||||||
|
"Rel Scroll Horizontal",
|
||||||
|
wl_fixed_from_double (0.0),
|
||||||
|
wl_fixed_from_double (0.0),
|
||||||
|
wl_fixed_from_double (0.0),
|
||||||
|
1,
|
||||||
|
XIModeRelative);
|
||||||
|
test_device_controller_add_device_info (display->seat->device_controller,
|
||||||
|
info);
|
||||||
|
test_XIDeviceInfo_destroy (info);
|
||||||
|
|
||||||
|
/* Dispatch the first entry event. */
|
||||||
|
test_seat_controller_dispatch_XI_Enter (display->seat->controller,
|
||||||
|
test_get_time (),
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
XINotifyAncestor,
|
||||||
|
test_get_root (),
|
||||||
|
test_surface_window,
|
||||||
|
None,
|
||||||
|
wl_fixed_from_double (1.0),
|
||||||
|
wl_fixed_from_double (1.0),
|
||||||
|
wl_fixed_from_double (1.0),
|
||||||
|
wl_fixed_from_double (1.0),
|
||||||
|
XINotifyNormal,
|
||||||
|
False, True, NULL, NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Create the valuator state. */
|
||||||
|
valuator_state
|
||||||
|
= test_seat_controller_get_XIValuatorState (display->seat->controller);
|
||||||
|
|
||||||
|
if (!valuator_state)
|
||||||
|
report_test_failure ("failed to create valuator state");
|
||||||
|
|
||||||
|
test_XIValuatorState_add_valuator (valuator_state, 1,
|
||||||
|
wl_fixed_from_double (1.0));
|
||||||
|
test_XIValuatorState_add_valuator (valuator_state, 2,
|
||||||
|
wl_fixed_from_double (1.0));
|
||||||
|
|
||||||
|
/* Dispatch the first motion event. */
|
||||||
|
test_seat_controller_dispatch_XI_Motion (display->seat->controller,
|
||||||
|
test_get_time (),
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
0,
|
||||||
|
test_get_root (),
|
||||||
|
test_surface_window,
|
||||||
|
None,
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
valuator_state,
|
||||||
|
NULL, NULL);
|
||||||
|
test_XIValuatorState_destroy (valuator_state);
|
||||||
|
|
||||||
|
/* Dispatch the second motion event. */
|
||||||
|
valuator_state
|
||||||
|
= test_seat_controller_get_XIValuatorState (display->seat->controller);
|
||||||
|
|
||||||
|
if (!valuator_state)
|
||||||
|
report_test_failure ("failed to create valuator state");
|
||||||
|
|
||||||
|
test_XIValuatorState_add_valuator (valuator_state, 1,
|
||||||
|
wl_fixed_from_double (1.1));
|
||||||
|
test_XIValuatorState_add_valuator (valuator_state, 2,
|
||||||
|
wl_fixed_from_double (2.6));
|
||||||
|
test_seat_controller_dispatch_XI_Motion (display->seat->controller,
|
||||||
|
test_get_time (),
|
||||||
|
TEST_SOURCE_DEVICE,
|
||||||
|
0,
|
||||||
|
test_get_root (),
|
||||||
|
test_surface_window,
|
||||||
|
None,
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
wl_fixed_from_double (2.0),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
valuator_state,
|
||||||
|
NULL, NULL);
|
||||||
|
test_XIValuatorState_destroy (valuator_state);
|
||||||
|
|
||||||
|
/* Now, verify the events that arrive. */
|
||||||
|
record_events ();
|
||||||
|
expect_frame_event ();
|
||||||
|
expect_axis_value120_event (WL_POINTER_AXIS_VERTICAL_SCROLL, 12);
|
||||||
|
expect_axis_value120_event (WL_POINTER_AXIS_HORIZONTAL_SCROLL, 96);
|
||||||
|
expect_frame_event ();
|
||||||
|
expect_motion_event (2.0, 2.0);
|
||||||
|
expect_frame_event ();
|
||||||
|
expect_enter_event (wayland_surface, 1.0, 1.0);
|
||||||
|
expect_frame_event ();
|
||||||
|
expect_leave_event ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_single_step (enum test_kind kind)
|
test_single_step (enum test_kind kind)
|
||||||
{
|
{
|
||||||
|
@ -473,6 +642,8 @@ test_single_step (enum test_kind kind)
|
||||||
struct test_XIButtonState *button_state;
|
struct test_XIButtonState *button_state;
|
||||||
struct test_subsurface *child;
|
struct test_subsurface *child;
|
||||||
|
|
||||||
|
button_state = NULL;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
test_log ("running test step: %s", test_names[kind]);
|
test_log ("running test step: %s", test_names[kind]);
|
||||||
|
|
||||||
|
@ -613,7 +784,99 @@ test_single_step (enum test_kind kind)
|
||||||
|
|
||||||
/* Run the test. */
|
/* Run the test. */
|
||||||
run_grab_test (button_state, child);
|
run_grab_test (button_state, child);
|
||||||
|
kind = TEST_VALUATOR_KIND;
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
case TEST_VALUATOR_KIND:
|
||||||
|
/* Dispatch a leave event at -1, -1, and then attach the following
|
||||||
|
scroll valuator information to the seat:
|
||||||
|
|
||||||
|
type
|
||||||
|
ScrollClass
|
||||||
|
number
|
||||||
|
1
|
||||||
|
scroll_type
|
||||||
|
Vertical
|
||||||
|
flags
|
||||||
|
Preferred
|
||||||
|
increment
|
||||||
|
1.0
|
||||||
|
|
||||||
|
type
|
||||||
|
ScrollClass
|
||||||
|
number
|
||||||
|
2
|
||||||
|
scroll_type
|
||||||
|
Horizontal
|
||||||
|
flags
|
||||||
|
Preferred
|
||||||
|
increment
|
||||||
|
2.0
|
||||||
|
|
||||||
|
type
|
||||||
|
ValuatorClass
|
||||||
|
sourceid
|
||||||
|
TEST_SOURCE_DEVICE
|
||||||
|
number
|
||||||
|
1
|
||||||
|
label
|
||||||
|
Rel Scroll Vertical
|
||||||
|
min
|
||||||
|
0.0
|
||||||
|
max
|
||||||
|
0.0
|
||||||
|
resolution
|
||||||
|
1
|
||||||
|
mode
|
||||||
|
Relative
|
||||||
|
value
|
||||||
|
0.0
|
||||||
|
|
||||||
|
type
|
||||||
|
ValuatorClass
|
||||||
|
sourceid
|
||||||
|
TEST_SOURCE_DEVICE
|
||||||
|
number
|
||||||
|
2
|
||||||
|
label
|
||||||
|
Rel Scroll Horizontal
|
||||||
|
min
|
||||||
|
0.0
|
||||||
|
max
|
||||||
|
0.0
|
||||||
|
resolution
|
||||||
|
1
|
||||||
|
mode
|
||||||
|
Relative
|
||||||
|
value
|
||||||
|
0.0
|
||||||
|
|
||||||
|
then, dispatch an entry event at 1, 1, followed by two motion
|
||||||
|
events at 2, 2 with the following valuators:
|
||||||
|
|
||||||
|
1, 1.0, 2, 1.0
|
||||||
|
1, 1.1, 2, 2.6
|
||||||
|
|
||||||
|
verify that the following events arrive in the specified order:
|
||||||
|
|
||||||
|
leave ()
|
||||||
|
frame ()
|
||||||
|
enter (SERIAL, PARENT, 1.0, 1.0)
|
||||||
|
frame ()
|
||||||
|
|
||||||
|
motion (TIME, 2.0, 2.0) (this motion event should arrive because
|
||||||
|
the entry event happened after
|
||||||
|
the scroll valuator information was
|
||||||
|
recorded. The first motion event to
|
||||||
|
arrive after that should be used to obtain
|
||||||
|
the current value of the valuator, and
|
||||||
|
not for calculating scroll deltas.)
|
||||||
|
frame ();
|
||||||
|
axis_value120 (WL_POINTER_AXIS_HORIZONTAL_SCROLL, 96)
|
||||||
|
axis_value120 (WL_POINTER_AXIS_VERTICAL_SCROLL, 12)
|
||||||
|
frame (); */
|
||||||
|
|
||||||
|
run_valuator_test ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,6 +1015,37 @@ expect_button_event (int button, int state)
|
||||||
report_test_failure ("expected button event, but it was not received");
|
report_test_failure ("expected button event, but it was not received");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
expect_axis_value120_event (uint32_t axis, int32_t value120)
|
||||||
|
{
|
||||||
|
struct test_recorded_event *event;
|
||||||
|
struct test_recorded_axis_value120_event *axis_value120_event;
|
||||||
|
|
||||||
|
event = record_tail;
|
||||||
|
|
||||||
|
if (!event)
|
||||||
|
report_test_failure ("expected event not sent");
|
||||||
|
|
||||||
|
record_tail = event->last;
|
||||||
|
|
||||||
|
if (event->kind == POINTER_AXIS_VALUE120_EVENT)
|
||||||
|
{
|
||||||
|
axis_value120_event
|
||||||
|
= (struct test_recorded_axis_value120_event *) event;
|
||||||
|
|
||||||
|
if (axis_value120_event->axis == axis
|
||||||
|
&& axis_value120_event->value120 == value120)
|
||||||
|
free (event);
|
||||||
|
else
|
||||||
|
report_test_failure ("expected axis_value120 event received "
|
||||||
|
"with incorrect parameters (axis: %"PRIu32","
|
||||||
|
" value120: %"PRIi32")", axis, value120);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
report_test_failure ("expected axis_value120 event, but it was not "
|
||||||
|
"received");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
expect_no_events (void)
|
expect_no_events (void)
|
||||||
{
|
{
|
||||||
|
@ -1011,7 +1305,34 @@ static void
|
||||||
handle_pointer_axis_value120 (void *data, struct wl_pointer *wl_pointer,
|
handle_pointer_axis_value120 (void *data, struct wl_pointer *wl_pointer,
|
||||||
uint32_t axis, int32_t value120)
|
uint32_t axis, int32_t value120)
|
||||||
{
|
{
|
||||||
/* TODO... */
|
struct test_recorded_axis_value120_event *event;
|
||||||
|
|
||||||
|
if (!recording_events)
|
||||||
|
{
|
||||||
|
test_log ("ignored button event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event = malloc (sizeof *event);
|
||||||
|
|
||||||
|
if (!event)
|
||||||
|
report_test_failure ("failed to record event");
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
event->header.kind = POINTER_AXIS_VALUE120_EVENT;
|
||||||
|
event->header.last = record_tail;
|
||||||
|
record_tail = &event->header;
|
||||||
|
|
||||||
|
event->axis = axis;
|
||||||
|
event->value120 = value120;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_pointer_listener pointer_listener =
|
static const struct wl_pointer_listener pointer_listener =
|
||||||
|
|
|
@ -825,6 +825,26 @@ test_init (void)
|
||||||
= getenv ("TEST_WRITE_REFERENCE") != NULL;
|
= getenv ("TEST_WRITE_REFERENCE") != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_seat_controller_device_id (void *data,
|
||||||
|
struct test_seat_controller *controller,
|
||||||
|
uint32_t device_id)
|
||||||
|
{
|
||||||
|
struct test_display *display;
|
||||||
|
|
||||||
|
display = data;
|
||||||
|
display->seat->device_id = device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct test_seat_controller_listener seat_controller_listener =
|
||||||
|
{
|
||||||
|
handle_seat_controller_device_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
test_init_seat (struct test_display *display)
|
test_init_seat (struct test_display *display)
|
||||||
{
|
{
|
||||||
|
@ -842,6 +862,22 @@ test_init_seat (struct test_display *display)
|
||||||
if (!display->seat->controller)
|
if (!display->seat->controller)
|
||||||
report_test_failure ("failed to obtain seat controller");
|
report_test_failure ("failed to obtain seat controller");
|
||||||
|
|
||||||
|
display->seat->device_controller
|
||||||
|
= test_seat_controller_get_device_controller (display->seat->controller);
|
||||||
|
|
||||||
|
if (!display->seat->device_controller)
|
||||||
|
report_test_failure ("failed to obtain device controller");
|
||||||
|
|
||||||
|
/* Fetch the device ID of the seat. */
|
||||||
|
display->seat->device_id = 0;
|
||||||
|
test_seat_controller_add_listener (display->seat->controller,
|
||||||
|
&seat_controller_listener,
|
||||||
|
display);
|
||||||
|
wl_display_roundtrip (display->display);
|
||||||
|
|
||||||
|
if (!display->seat->device_id)
|
||||||
|
report_test_failure ("failed to obtain device ID");
|
||||||
|
|
||||||
/* The protocol translator currently supports version 8 of wl_seat,
|
/* The protocol translator currently supports version 8 of wl_seat,
|
||||||
so bind to that. */
|
so bind to that. */
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,18 @@ struct test_seat
|
||||||
/* The test seat, if any. */
|
/* The test seat, if any. */
|
||||||
struct test_seat_controller *controller;
|
struct test_seat_controller *controller;
|
||||||
|
|
||||||
|
/* The device manager, if any. */
|
||||||
|
struct test_device_controller *device_controller;
|
||||||
|
|
||||||
/* The seat resource itself. */
|
/* The seat resource itself. */
|
||||||
struct wl_seat *seat;
|
struct wl_seat *seat;
|
||||||
|
|
||||||
/* The wl_pointer resource. */
|
/* The wl_pointer resource. */
|
||||||
struct wl_pointer *pointer;
|
struct wl_pointer *pointer;
|
||||||
|
|
||||||
|
/* The device ID of the seat. */
|
||||||
|
uint32_t device_id;
|
||||||
|
|
||||||
/* The buttons currently held down. */
|
/* The buttons currently held down. */
|
||||||
unsigned char buttons;
|
unsigned char buttons;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue