Add seat testing mechanism and tests for seats

* 12to11-test.xml (test_manager): <error>: Add `invalid_button',
`value_exists', `bad_seat_version' and `invalid_valuator'.
(test_manager): <get_test_seat>: New request.
(test_XIButtonState, test_XIModifierState, test_XIValuatorState)
(test_seat_controller): New interfaces.
* Imakefile: (seat.o): Depend on test_seat.c.
* compositor.h: Update prototypes.
* run.c (XLRunCompositor): Get rid of stdbool constant.
* seat.c (HandleBind1): Move binding logic to this new function.
(HandleBind): Call HandleBind1.
(InitSeatCommon): Add list initialization to this function.
(MakeSeatForDevicePair): Call InitSeatCommon instead.
(HandleRawKey, UpdateModifiersForSeats, DispatchFocusIn)
(DispatchMotion, DispatchBarrierHit, DispatchGesturePinch)
(DispatchGestureSwipe): Do not update user time from send_event
events.  Include test_seat.c.
* test.c (GetTestSeat): New function.
(test_manager_impl): Add new proc function.
(XLLookUpTestSurface): New function.
* tests/Imakefile (OBJS8, SRCS8): New program.
(PROGRAMS): Add seat_test.
(seat_test): New function.
* tests/run_tests.sh (standard_tests): Add seat_test.
* tests/svnignore.txt: Add seat_test.
* tests/test_harness.c (report_test_internal_error,
test_init_seat): New functions.
* tests/test_harness.h (struct test_seat): New struct.
(struct test_display): New field `seat'.
This commit is contained in:
hujianwei 2022-11-07 06:21:07 +00:00
parent ef456e4d24
commit 686f71c3b4
11 changed files with 455 additions and 31 deletions

View file

@ -37,6 +37,14 @@
summary="another client has already locked the scale"/> summary="another client has already locked the scale"/>
<entry name="invalid_scale" value="3" <entry name="invalid_scale" value="3"
summary="the specified scale is invalid"/> summary="the specified scale is invalid"/>
<entry name="invalid_button" value="4"
summary="the specified button is invalid"/>
<entry name="value_exists" value="5"
summary="the specified valuator is already included"/>
<entry name="bad_seat_version" value="6"
summary="an invalid version was specified"/>
<entry name="invalid_valuator" value="7"
summary="the specified valuator is invalid"/>
</enum> </enum>
<request name="get_test_surface"> <request name="get_test_surface">
@ -47,7 +55,8 @@
Create the window immediately after get_test_surface is Create the window immediately after get_test_surface is
called; the window is mapped once a commit request with a called; the window is mapped once a commit request with a
non-nil buffer is made. non-nil buffer is made. The window is created as an
override-redirect child of the root window, at 0, 0.
Once the window associated with the test_surface object is Once the window associated with the test_surface object is
mapped, send a mapped event. mapped, send a mapped event.
@ -73,6 +82,18 @@
<arg name="global_scale" type="uint"/> <arg name="global_scale" type="uint"/>
</request> </request>
<request name="get_test_seat">
<description summary="obtain test seat">
Create a new seat controller object and its associated seat.
The seat will not correspond to any real input device, but
will allow artificial events to be constructed and processed.
A test_seat_controller.bind_seat request can be used to bind
to the given seat.
</description>
<arg name="id" type="new_id" interface="test_seat_controller"/>
</request>
<event name="display_string"> <event name="display_string">
<description summary="X server name"> <description summary="X server name">
The display_string event sends the name of the X display to The display_string event sends the name of the X display to
@ -140,4 +161,264 @@
<arg name="scale" type="uint"/> <arg name="scale" type="uint"/>
</request> </request>
</interface> </interface>
<interface name="test_XIButtonState" version="1">
<description summary="XInput 2 button state">
The button state associated with an event.
</description>
<request name="destroy" type="destructor">
<description summary="destroy this resource">
Destroy the given resource.
</description>
</request>
<request name="add_button">
<description summary="add button">
Add the button with the given number to the button state. If
button is 0 or more than 8, raise an invalid_button error.
</description>
<arg name="button" type="uint"/>
</request>
<request name="remove_button">
<description summary="remove button">
Remove the button with the given number from the button state.
If button is 0 or more than 8, raise an invalid_button error.
If the button was not previously added to the button state, do
nothing.
</description>
<arg name="button" type="uint"/>
</request>
</interface>
<interface name="test_XIModifierState" version="1">
<description summary="XInput 2 modifier state">
The modifier state associated with an event.
</description>
<request name="destroy" type="destructor">
<description summary="destroy this resource">
Destroy the given resource.
</description>
</request>
<request name="set_values">
<description summary="set modifiers">
Set the modifiers in this modifier state.
</description>
<arg name="base" type="int"/>
<arg name="latched" type="int"/>
<arg name="locked" type="int"/>
<arg name="effective" type="int"/>
</request>
</interface>
<interface name="test_XIValuatorState" version="1">
<description summary="XInput 2 valuator state">
The valuator state associated with an event.
</description>
<request name="destroy" type="destructor">
<description summary="destroy this resource">
Destroy the given resource.
</description>
</request>
<request name="add_valuator">
<description summary="add a valuator">
Add a valuator with the given value to the specified valuator
state. If the value already exists, post a value_exists
error. If the valuator is more than 65535 or 0, post an
invalid_valuator error.
</description>
<arg name="valuator" type="uint"/>
<arg name="value" type="fixed"/>
</request>
</interface>
<interface name="test_seat_controller" version="1">
<description summary="test seat">
This object extends a wl_seat created with the
test_manager.get_test_seat request with several requests to
dispatch generated events.
If the seat associated with the test controller is destroyed by
the time a request is made with the test controller, the latter
request is simply ignored.
</description>
<request name="destroy" type="destructor">
<description summary="destroy test seat controller">
Destroy the test seat controller resource.
</description>
</request>
<request name="bind_seat">
<description summary="bind to the seat">
Create a wl_seat resource for this seat controller's
associated seat, with the specified version. If the version
is unsupported, raise a bad_seat_version error.
</description>
<arg name="version" type="uint"/>
<arg name="id" type="new_id" interface="wl_seat"/>
</request>
<request name="get_XIModifierState">
<description summary="obtain a test_XIModifierState">
Create a test_XIModifierState resource with all fields set to
0.
</description>
<arg name="id" type="new_id" interface="test_XIModifierState"/>
</request>
<request name="get_XIButtonState">
<description summary="obtain a test_XIButtonState">
Create a test_XIButtonState resource containing no buttons.
</description>
<arg name="id" type="new_id" interface="test_XIButtonState"/>
</request>
<request name="get_XIValuatorState">
<description summary="obtain a test_XIValuatorState">
Create a test_XIValuatorState resource containing no
valuators.
</description>
<arg name="id" type="new_id" interface="test_XIValuatorState"/>
</request>
<request name="dispatch_XI_Enter">
<description summary="dispatch entry event">
Dispatch an XI_Enter event to the seat. If buttons (or any
following field) is null, use a value comprised of 0s instead.
</description>
<arg name="time" type="uint"/>
<arg name="sourceid" type="int"/>
<arg name="detail" type="int"/>
<arg name="root" type="uint"/>
<arg name="event" type="uint"/>
<arg name="child" type="uint"/>
<arg name="root_x" type="fixed"/>
<arg name="root_y" type="fixed"/>
<arg name="event_x" type="fixed"/>
<arg name="event_y" type="fixed"/>
<arg name="mode" type="int"/>
<arg name="focus" type="int"/>
<arg name="same_screen" type="int"/>
<arg name="buttons" type="object" interface="test_XIButtonState"
allow-null="true"/>
<arg name="mods" type="object" interface="test_XIModifierState"
allow-null="true"/>
<arg name="group" type="object" interface="test_XIModifierState"
allow-null="true"/>
</request>
<request name="dispatch_XI_Leave">
<description summary="dispatch leave event">
Dispatch an XI_Leave event to the seat. If buttons (or any
following field) is null, use a value comprised of 0s instead.
</description>
<arg name="time" type="uint"/>
<arg name="sourceid" type="int"/>
<arg name="detail" type="int"/>
<arg name="root" type="uint"/>
<arg name="event" type="uint"/>
<arg name="child" type="uint"/>
<arg name="root_x" type="fixed"/>
<arg name="root_y" type="fixed"/>
<arg name="event_x" type="fixed"/>
<arg name="event_y" type="fixed"/>
<arg name="mode" type="int"/>
<arg name="focus" type="int"/>
<arg name="same_screen" type="int"/>
<arg name="buttons" type="object" interface="test_XIButtonState"
allow-null="true"/>
<arg name="mods" type="object" interface="test_XIModifierState"
allow-null="true"/>
<arg name="group" type="object" interface="test_XIModifierState"
allow-null="true"/>
</request>
<request name="dispatch_XI_Motion">
<description summary="dispatch motion event">
Dispatch an XI_Motion device event to the seat.
</description>
<arg name="time" type="uint"/>
<arg name="sourceid" type="int"/>
<arg name="detail" type="int"/>
<arg name="root" type="uint"/>
<arg name="event" type="uint"/>
<arg name="child" type="uint"/>
<arg name="root_x" type="fixed"/>
<arg name="root_y" type="fixed"/>
<arg name="event_x" type="fixed"/>
<arg name="event_y" type="fixed"/>
<arg name="flags" type="int"/>
<arg name="buttons" type="object" interface="test_XIButtonState"
allow-null="true"/>
<arg name="valuators" type="object" interface="test_XIValuatorState"
allow-null="true"/>
<arg name="mods" type="object" interface="test_XIModifierState"
allow-null="true"/>
<arg name="group" type="object" interface="test_XIModifierState"
allow-null="true"/>
</request>
<request name="dispatch_XI_ButtonPress">
<description summary="dispatch button press event">
Dispatch an XI_ButtonPress device event to the seat.
</description>
<arg name="time" type="uint"/>
<arg name="sourceid" type="int"/>
<arg name="detail" type="int"/>
<arg name="root" type="uint"/>
<arg name="event" type="uint"/>
<arg name="child" type="uint"/>
<arg name="root_x" type="fixed"/>
<arg name="root_y" type="fixed"/>
<arg name="event_x" type="fixed"/>
<arg name="event_y" type="fixed"/>
<arg name="flags" type="int"/>
<arg name="buttons" type="object" interface="test_XIButtonState"
allow-null="true"/>
<arg name="valuators" type="object" interface="test_XIValuatorState"
allow-null="true"/>
<arg name="mods" type="object" interface="test_XIModifierState"
allow-null="true"/>
<arg name="group" type="object" interface="test_XIModifierState"
allow-null="true"/>
</request>
<request name="dispatch_XI_ButtonRelease">
<description summary="dispatch button release event">
Dispatch an XI_ButtonRelease device event to the seat.
</description>
<arg name="time" type="uint"/>
<arg name="sourceid" type="int"/>
<arg name="detail" type="int"/>
<arg name="root" type="uint"/>
<arg name="event" type="uint"/>
<arg name="child" type="uint"/>
<arg name="root_x" type="fixed"/>
<arg name="root_y" type="fixed"/>
<arg name="event_x" type="fixed"/>
<arg name="event_y" type="fixed"/>
<arg name="flags" type="int"/>
<arg name="buttons" type="object" interface="test_XIButtonState"
allow-null="true"/>
<arg name="valuators" type="object" interface="test_XIValuatorState"
allow-null="true"/>
<arg name="mods" type="object" interface="test_XIModifierState"
allow-null="true"/>
<arg name="group" type="object" interface="test_XIModifierState"
allow-null="true"/>
</request>
</interface>
</protocol> </protocol>

View file

@ -106,7 +106,12 @@ ScannerTarget(idle-inhibit-unstable-v1)
ScannerTarget(pointer-gestures-unstable-v1) ScannerTarget(pointer-gestures-unstable-v1)
ScannerTarget(12to11-test) ScannerTarget(12to11-test)
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */ /* Make seat.o depend on test_seat.c, as it includes that. Both files
are rather special. */
seat.o: test_seat.c
/* Make OBJS depend on scanner headers, and depend on both them and
SRCS. */
$(OBJS): $(GENHEADERS) $(OBJS): $(GENHEADERS)
/* depend somehow does not depend on SRCS, even though some of OBJS /* depend somehow does not depend on SRCS, even though some of OBJS

View file

@ -1803,6 +1803,7 @@ extern int locked_output_scale;
extern void XLInitTest (void); extern void XLInitTest (void);
extern Bool XLHandleOneXEventForTest (XEvent *); extern Bool XLHandleOneXEventForTest (XEvent *);
extern Surface *XLLookUpTestSurface (Window, Subcompositor **);
/* Defined in buffer_release.c. */ /* Defined in buffer_release.c. */
@ -1815,6 +1816,11 @@ extern void FreeBufferReleaseHelper (BufferReleaseHelper *);
extern void ReleaseBufferWithHelper (BufferReleaseHelper *, ExtBuffer *, extern void ReleaseBufferWithHelper (BufferReleaseHelper *, ExtBuffer *,
RenderTarget); RenderTarget);
/* Defined in test_seat.c. */
extern void XLGetTestSeat (struct wl_client *, struct wl_resource *,
uint32_t);
/* Utility functions that don't belong in a specific file. */ /* Utility functions that don't belong in a specific file. */
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0]) #define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])

2
run.c
View file

@ -305,6 +305,6 @@ XLRunCompositor (void)
poll_fds.next = &poll_fds; poll_fds.next = &poll_fds;
poll_fds.last = &poll_fds; poll_fds.last = &poll_fds;
while (true) while (True)
RunStep (); RunStep ();
} }

72
seat.c
View file

@ -94,6 +94,7 @@ enum
IsExternalGrabApplied = (1 << 8), IsExternalGrabApplied = (1 << 8),
IsInPinchGesture = (1 << 9), IsInPinchGesture = (1 << 9),
IsInSwipeGesture = (1 << 10), IsInSwipeGesture = (1 << 10),
IsTestSeat = (1 << 11),
}; };
enum enum
@ -1694,13 +1695,11 @@ HandleResourceDestroy (struct wl_resource *resource)
} }
static void static void
HandleBind (struct wl_client *client, void *data, HandleBind1 (struct wl_client *client, Seat *seat, uint32_t version,
uint32_t version, uint32_t id) uint32_t id)
{ {
struct wl_resource *resource; struct wl_resource *resource;
Seat *seat;
seat = data;
resource = wl_resource_create (client, &wl_seat_interface, resource = wl_resource_create (client, &wl_seat_interface,
version, id); version, id);
@ -1710,7 +1709,7 @@ HandleBind (struct wl_client *client, void *data,
return; return;
} }
wl_resource_set_implementation (resource, &wl_seat_impl, data, wl_resource_set_implementation (resource, &wl_seat_impl, seat,
HandleResourceDestroy); HandleResourceDestroy);
wl_seat_send_capabilities (resource, (WL_SEAT_CAPABILITY_POINTER wl_seat_send_capabilities (resource, (WL_SEAT_CAPABILITY_POINTER
@ -1719,7 +1718,14 @@ HandleBind (struct wl_client *client, void *data,
if (wl_resource_get_version (resource) > 2) if (wl_resource_get_version (resource) > 2)
wl_seat_send_name (resource, seat->name); wl_seat_send_name (resource, seat->name);
RetainSeat (data); RetainSeat (seat);
}
static void
HandleBind (struct wl_client *client, void *data, uint32_t version,
uint32_t id)
{
HandleBind1 (client, data, version, id);
} }
static void static void
@ -1757,19 +1763,8 @@ UpdateValuators (Seat *seat, XIDeviceInfo *device)
} }
static void static void
MakeSeatForDevicePair (int master_keyboard, int master_pointer, InitSeatCommon (Seat *seat)
XIDeviceInfo *pointer_info)
{ {
Seat *seat;
XkbStateRec state;
seat = XLCalloc (1, sizeof *seat);
seat->master_keyboard = master_keyboard;
seat->master_pointer = master_pointer;
seat->name = XLStrdup (pointer_info->name);
seat->global = wl_global_create (compositor.wl_display,
&wl_seat_interface, 8,
seat, HandleBind);
seat->client_info.next = &seat->client_info; seat->client_info.next = &seat->client_info;
seat->client_info.last = &seat->client_info; seat->client_info.last = &seat->client_info;
@ -1786,6 +1781,24 @@ MakeSeatForDevicePair (int master_keyboard, int master_pointer,
seat->modifier_callbacks.last = &seat->modifier_callbacks; seat->modifier_callbacks.last = &seat->modifier_callbacks;
wl_array_init (&seat->keys); wl_array_init (&seat->keys);
}
static void
MakeSeatForDevicePair (int master_keyboard, int master_pointer,
XIDeviceInfo *pointer_info)
{
Seat *seat;
XkbStateRec state;
seat = XLCalloc (1, sizeof *seat);
seat->master_keyboard = master_keyboard;
seat->master_pointer = master_pointer;
seat->name = XLStrdup (pointer_info->name);
seat->global = wl_global_create (compositor.wl_display,
&wl_seat_interface, 8,
seat, HandleBind);
InitSeatCommon (seat);
XLMakeAssoc (seats, master_keyboard, seat); XLMakeAssoc (seats, master_keyboard, seat);
XLMakeAssoc (seats, master_pointer, seat); XLMakeAssoc (seats, master_pointer, seat);
@ -2423,7 +2436,9 @@ HandleRawKey (XIRawEvent *event)
/* This is used for tracking grabs. */ /* This is used for tracking grabs. */
seat->its_depress_time = event->time; seat->its_depress_time = event->time;
/* Update the last user time. */ /* Update the last user time. send_event events can have a
different timestamp not synchronized with that of the server. */
if (!event->send_event)
seat->last_user_time = TimestampFromServerTime (event->time); seat->last_user_time = TimestampFromServerTime (event->time);
} }
@ -2867,6 +2882,10 @@ UpdateModifiersForSeats (unsigned int base, unsigned int locked,
{ {
seat = tem->data; seat = tem->data;
/* If the seat is a test seat, ignore. */
if (seat->flags & IsTestSeat)
continue;
seat->base = base; seat->base = base;
seat->locked = locked; seat->locked = locked;
seat->latched = latched; seat->latched = latched;
@ -2946,6 +2965,8 @@ DispatchFocusIn (Surface *surface, XIFocusInEvent *event)
return; return;
/* Record the time the focus changed for the external grab. */ /* Record the time the focus changed for the external grab. */
if (!event->send_event)
seat->last_focus_time = TimestampFromServerTime (event->time); seat->last_focus_time = TimestampFromServerTime (event->time);
SetFocusSurface (seat, surface); SetFocusSurface (seat, surface);
@ -3939,6 +3960,8 @@ DispatchMotion (Subcompositor *subcompositor, XIDeviceEvent *xev)
seat->its_press_time = xev->time; seat->its_press_time = xev->time;
/* Update the last user time. */ /* Update the last user time. */
if (!xev->send_event)
seat->last_user_time = TimestampFromServerTime (xev->time); seat->last_user_time = TimestampFromServerTime (xev->time);
actual_dispatch = FindSurfaceUnder (subcompositor, xev->event_x, actual_dispatch = FindSurfaceUnder (subcompositor, xev->event_x,
@ -4381,6 +4404,8 @@ DispatchBarrierHit (XIBarrierEvent *barrier)
barrier->time); barrier->time);
/* Set the last user time. */ /* Set the last user time. */
if (!barrier->send_event)
seat->last_user_time = TimestampFromServerTime (barrier->time); seat->last_user_time = TimestampFromServerTime (barrier->time);
} }
@ -4473,6 +4498,8 @@ DispatchGesturePinch (Subcompositor *subcompositor, XIGesturePinchEvent *pinch)
seat->its_press_time = pinch->time; seat->its_press_time = pinch->time;
/* Update the last user time. */ /* Update the last user time. */
if (!pinch->send_event)
seat->last_user_time = TimestampFromServerTime (pinch->time); seat->last_user_time = TimestampFromServerTime (pinch->time);
/* Now find the dispatch surface so we can enter it if required. /* Now find the dispatch surface so we can enter it if required.
@ -4641,6 +4668,8 @@ DispatchGestureSwipe (Subcompositor *subcompositor, XIGestureSwipeEvent *swipe)
seat->its_press_time = swipe->time; seat->its_press_time = swipe->time;
/* Update the last user time. */ /* Update the last user time. */
if (!swipe->send_event)
seat->last_user_time = TimestampFromServerTime (swipe->time); seat->last_user_time = TimestampFromServerTime (swipe->time);
/* Now find the dispatch surface so we can enter it if required. /* Now find the dispatch surface so we can enter it if required.
@ -6396,3 +6425,8 @@ XLSeatCancelExternalGrab (Seat *seat)
XIUngrabDevice (compositor.display, seat->master_keyboard, XIUngrabDevice (compositor.display, seat->master_keyboard,
seat->external_grab_time); seat->external_grab_time);
} }
/* This is a particularly ugly hack, but there is no other way to
expose all the internals needed by test_seat.c. */
#include "test_seat.c"

25
test.c
View file

@ -542,10 +542,18 @@ GetScaleLock (struct wl_client *client, struct wl_resource *resource,
NULL, HandleScaleLockResourceDestroy); NULL, HandleScaleLockResourceDestroy);
} }
static void
GetTestSeat (struct wl_client *client, struct wl_resource *resource,
uint32_t id)
{
XLGetTestSeat (client, resource, id);
}
static const struct test_manager_interface test_manager_impl = static const struct test_manager_interface test_manager_impl =
{ {
.get_test_surface = GetTestSurface, .get_test_surface = GetTestSurface,
.get_scale_lock = GetScaleLock, .get_scale_lock = GetScaleLock,
.get_test_seat = GetTestSeat,
}; };
@ -634,3 +642,20 @@ XLHandleOneXEventForTest (XEvent *event)
return False; return False;
} }
Surface *
XLLookUpTestSurface (Window window, Subcompositor **subcompositor)
{
TestSurface *test;
if (!surfaces)
return NULL;
test = XLLookUpAssoc (surfaces, window);
if (!test)
return NULL;
*subcompositor = test->subcompositor;
return test->role.surface;
}

View file

@ -40,7 +40,9 @@ ScannerTarget(viewporter)
OBJS6 = $(COMMONSRCS) subsurface_test.o OBJS6 = $(COMMONSRCS) subsurface_test.o
SRCS7 = $(COMMONSRCS) scale_test.c SRCS7 = $(COMMONSRCS) scale_test.c
OBJS7 = $(COMMONSRCS) scale_test.o OBJS7 = $(COMMONSRCS) scale_test.o
PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test SRCS8 = $(COMMONSRCS) seat_test.c
OBJS8 = $(COMMONSRCS) seat_test.o
PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test seat_test
/* Make all objects depend on HEADER. */ /* Make all objects depend on HEADER. */
$(OBJS1): $(HEADER) $(OBJS1): $(HEADER)
@ -55,9 +57,10 @@ NormalProgramTarget(transform_test,$(OBJS4),NullParameter,$(LOCAL_LIBRARIES),Nul
NormalProgramTarget(viewporter_test,$(OBJS5),NullParameter,$(LOCAL_LIBRARIES),NullParameter) NormalProgramTarget(viewporter_test,$(OBJS5),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
NormalProgramTarget(subsurface_test,$(OBJS6),NullParameter,$(LOCAL_LIBRARIES),NullParameter) NormalProgramTarget(subsurface_test,$(OBJS6),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
NormalProgramTarget(scale_test,$(OBJS7),NullParameter,$(LOCAL_LIBRARIES),NullParameter) NormalProgramTarget(scale_test,$(OBJS7),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
NormalProgramTarget(seat_test,$(OBJS8),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
DependTarget3($(SRCS1),$(SRCS2),$(SRCS3)) DependTarget3($(SRCS1),$(SRCS2),$(SRCS3))
DependTarget3($(SRCS4),$(SRCS5),$(SRCS6)) DependTarget3($(SRCS4),$(SRCS5),$(SRCS6))
DependTarget3($(SRCS7),NullParameter,NullParameter) DependTarget3($(SRCS7),$(SRCS8),NullParameter)
all:: $(PROGRAMS) all:: $(PROGRAMS)

View file

@ -21,7 +21,7 @@
pushd "$(dirname $0)" pushd "$(dirname $0)"
declare -a standard_tests=( declare -a standard_tests=(
simple_test damage_test transform_test viewporter_test simple_test damage_test transform_test viewporter_test
subsurface_test scale_test subsurface_test scale_test seat_test
) )
make -C . "${standard_tests[@]}" make -C . "${standard_tests[@]}"

View file

@ -7,6 +7,7 @@ transform_test
viewporter_test viewporter_test
subsurface_test subsurface_test
scale_test scale_test
seat_test
imgview imgview
reject.dump reject.dump
Makefile Makefile

View file

@ -372,6 +372,20 @@ test_log (const char *format, ...)
va_end (ap); va_end (ap);
} }
static void __attribute__ ((noreturn, format (gnu_printf, 1, 2)))
report_test_internal_error (const char *format, ...)
{
va_list ap;
va_start (ap, format);
fputs ("internal error: ", stderr);
vfprintf (stderr, format, ap);
fputs ("\n", stderr);
va_end (ap);
abort ();
}
bool bool
make_test_surface (struct test_display *display, make_test_surface (struct test_display *display,
struct wl_surface **surface_return, struct wl_surface **surface_return,
@ -811,6 +825,40 @@ test_init (void)
= getenv ("TEST_WRITE_REFERENCE") != NULL; = getenv ("TEST_WRITE_REFERENCE") != NULL;
} }
void
test_init_seat (struct test_display *display)
{
if (display->seat)
report_test_internal_error ("tried to initialize seat twice");
display->seat = malloc (sizeof *display->seat);
if (!display->seat)
report_test_failure ("failed to allocate seat");
display->seat->controller
= test_manager_get_test_seat (display->test_manager);
if (!display->seat->controller)
report_test_failure ("failed to obtain seat controller");
/* The protocol translator currently supports version 8 of wl_seat,
so bind to that. */
display->seat->seat
= test_seat_controller_bind_seat (display->seat->controller,
8);
if (!display->seat->seat)
report_test_failure ("failed to bind to test seat");
display->seat->pointer
= wl_seat_get_pointer (display->seat->seat);
if (!display->seat->pointer)
report_test_failure ("failed to bind to test pointer");
}
void __attribute__ ((noreturn)) void __attribute__ ((noreturn))
test_complete (void) test_complete (void)
{ {

View file

@ -23,6 +23,8 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include <time.h>
#include <string.h>
#include <wayland-client.h> #include <wayland-client.h>
@ -31,6 +33,21 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include "12to11-test.h" #include "12to11-test.h"
struct test_seat
{
/* The test seat, if any. */
struct test_seat_controller *controller;
/* The seat resource itself. */
struct wl_seat *seat;
/* The wl_pointer resource. */
struct wl_pointer *pointer;
/* The buttons currently held down. */
unsigned char buttons;
};
struct test_display struct test_display
{ {
/* The wayland display. */ /* The wayland display. */
@ -57,6 +74,9 @@ struct test_display
/* Test interfaces. */ /* Test interfaces. */
struct test_interface *interfaces; struct test_interface *interfaces;
/* The test seat. */
struct test_seat *seat;
/* The number of such interfaces. */ /* The number of such interfaces. */
int num_test_interfaces; int num_test_interfaces;
}; };
@ -123,6 +143,7 @@ extern void verify_image_data (struct test_display *, Window, const char *);
extern void test_init (void); extern void test_init (void);
extern void test_complete (void) __attribute__ ((noreturn)); extern void test_complete (void) __attribute__ ((noreturn));
extern void test_set_scale (struct test_display *, int); extern void test_set_scale (struct test_display *, int);
extern void test_init_seat (struct test_display *);
#define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0]) #define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0])