diff --git a/12to11-test.xml b/12to11-test.xml
index 3fc6817..30e7bec 100644
--- a/12to11-test.xml
+++ b/12to11-test.xml
@@ -37,6 +37,14 @@
summary="another client has already locked the scale"/>
+
+
+
+
@@ -47,7 +55,8 @@
Create the window immediately after get_test_surface is
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
mapped, send a mapped event.
@@ -73,6 +82,18 @@
+
+
+ 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.
+
+
+
+
The display_string event sends the name of the X display to
@@ -140,4 +161,264 @@
+
+
+
+ The button state associated with an event.
+
+
+
+
+ Destroy the given resource.
+
+
+
+
+
+ Add the button with the given number to the button state. If
+ button is 0 or more than 8, raise an invalid_button error.
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+ The modifier state associated with an event.
+
+
+
+
+ Destroy the given resource.
+
+
+
+
+
+ Set the modifiers in this modifier state.
+
+
+
+
+
+
+
+
+
+
+
+ The valuator state associated with an event.
+
+
+
+
+ Destroy the given resource.
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+
+
+ 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.
+
+
+
+
+ Destroy the test seat controller resource.
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+ Create a test_XIModifierState resource with all fields set to
+ 0.
+
+
+
+
+
+
+ Create a test_XIButtonState resource containing no buttons.
+
+
+
+
+
+
+ Create a test_XIValuatorState resource containing no
+ valuators.
+
+
+
+
+
+
+ Dispatch an XI_Enter event to the seat. If buttons (or any
+ following field) is null, use a value comprised of 0s instead.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dispatch an XI_Leave event to the seat. If buttons (or any
+ following field) is null, use a value comprised of 0s instead.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dispatch an XI_Motion device event to the seat.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dispatch an XI_ButtonPress device event to the seat.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dispatch an XI_ButtonRelease device event to the seat.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Imakefile b/Imakefile
index 9f52a5f..0f7a229 100644
--- a/Imakefile
+++ b/Imakefile
@@ -106,7 +106,12 @@ ScannerTarget(idle-inhibit-unstable-v1)
ScannerTarget(pointer-gestures-unstable-v1)
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)
/* depend somehow does not depend on SRCS, even though some of OBJS
diff --git a/compositor.h b/compositor.h
index fc433ae..7874e3e 100644
--- a/compositor.h
+++ b/compositor.h
@@ -1803,6 +1803,7 @@ extern int locked_output_scale;
extern void XLInitTest (void);
extern Bool XLHandleOneXEventForTest (XEvent *);
+extern Surface *XLLookUpTestSurface (Window, Subcompositor **);
/* Defined in buffer_release.c. */
@@ -1815,6 +1816,11 @@ extern void FreeBufferReleaseHelper (BufferReleaseHelper *);
extern void ReleaseBufferWithHelper (BufferReleaseHelper *, ExtBuffer *,
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. */
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])
diff --git a/run.c b/run.c
index ca9bf03..6b01403 100644
--- a/run.c
+++ b/run.c
@@ -305,6 +305,6 @@ XLRunCompositor (void)
poll_fds.next = &poll_fds;
poll_fds.last = &poll_fds;
- while (true)
+ while (True)
RunStep ();
}
diff --git a/seat.c b/seat.c
index 35fc8f7..f664111 100644
--- a/seat.c
+++ b/seat.c
@@ -94,6 +94,7 @@ enum
IsExternalGrabApplied = (1 << 8),
IsInPinchGesture = (1 << 9),
IsInSwipeGesture = (1 << 10),
+ IsTestSeat = (1 << 11),
};
enum
@@ -1694,13 +1695,11 @@ HandleResourceDestroy (struct wl_resource *resource)
}
static void
-HandleBind (struct wl_client *client, void *data,
- uint32_t version, uint32_t id)
+HandleBind1 (struct wl_client *client, Seat *seat, uint32_t version,
+ uint32_t id)
{
struct wl_resource *resource;
- Seat *seat;
- seat = data;
resource = wl_resource_create (client, &wl_seat_interface,
version, id);
@@ -1710,7 +1709,7 @@ HandleBind (struct wl_client *client, void *data,
return;
}
- wl_resource_set_implementation (resource, &wl_seat_impl, data,
+ wl_resource_set_implementation (resource, &wl_seat_impl, seat,
HandleResourceDestroy);
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)
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
@@ -1757,19 +1763,8 @@ UpdateValuators (Seat *seat, XIDeviceInfo *device)
}
static void
-MakeSeatForDevicePair (int master_keyboard, int master_pointer,
- XIDeviceInfo *pointer_info)
+InitSeatCommon (Seat *seat)
{
- 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.last = &seat->client_info;
@@ -1786,6 +1781,24 @@ MakeSeatForDevicePair (int master_keyboard, int master_pointer,
seat->modifier_callbacks.last = &seat->modifier_callbacks;
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_pointer, seat);
@@ -2423,8 +2436,10 @@ HandleRawKey (XIRawEvent *event)
/* This is used for tracking grabs. */
seat->its_depress_time = event->time;
- /* Update the last user time. */
- seat->last_user_time = TimestampFromServerTime (event->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);
}
static void
@@ -2867,6 +2882,10 @@ UpdateModifiersForSeats (unsigned int base, unsigned int locked,
{
seat = tem->data;
+ /* If the seat is a test seat, ignore. */
+ if (seat->flags & IsTestSeat)
+ continue;
+
seat->base = base;
seat->locked = locked;
seat->latched = latched;
@@ -2946,7 +2965,9 @@ DispatchFocusIn (Surface *surface, XIFocusInEvent *event)
return;
/* Record the time the focus changed for the external grab. */
- seat->last_focus_time = TimestampFromServerTime (event->time);
+
+ if (!event->send_event)
+ seat->last_focus_time = TimestampFromServerTime (event->time);
SetFocusSurface (seat, surface);
}
@@ -3939,7 +3960,9 @@ DispatchMotion (Subcompositor *subcompositor, XIDeviceEvent *xev)
seat->its_press_time = xev->time;
/* Update the last user time. */
- seat->last_user_time = TimestampFromServerTime (xev->time);
+
+ if (!xev->send_event)
+ seat->last_user_time = TimestampFromServerTime (xev->time);
actual_dispatch = FindSurfaceUnder (subcompositor, xev->event_x,
xev->event_y);
@@ -4381,7 +4404,9 @@ DispatchBarrierHit (XIBarrierEvent *barrier)
barrier->time);
/* Set the last user time. */
- seat->last_user_time = TimestampFromServerTime (barrier->time);
+
+ if (!barrier->send_event)
+ seat->last_user_time = TimestampFromServerTime (barrier->time);
}
static void
@@ -4473,7 +4498,9 @@ DispatchGesturePinch (Subcompositor *subcompositor, XIGesturePinchEvent *pinch)
seat->its_press_time = pinch->time;
/* Update the last user time. */
- seat->last_user_time = TimestampFromServerTime (pinch->time);
+
+ if (!pinch->send_event)
+ seat->last_user_time = TimestampFromServerTime (pinch->time);
/* Now find the dispatch surface so we can enter it if required.
Most of this code is copied from DispatchMotion; it should
@@ -4641,7 +4668,9 @@ DispatchGestureSwipe (Subcompositor *subcompositor, XIGestureSwipeEvent *swipe)
seat->its_press_time = swipe->time;
/* Update the last user time. */
- seat->last_user_time = TimestampFromServerTime (swipe->time);
+
+ if (!swipe->send_event)
+ seat->last_user_time = TimestampFromServerTime (swipe->time);
/* Now find the dispatch surface so we can enter it if required.
Most of this code is copied from DispatchMotion; it should
@@ -6396,3 +6425,8 @@ XLSeatCancelExternalGrab (Seat *seat)
XIUngrabDevice (compositor.display, seat->master_keyboard,
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"
diff --git a/test.c b/test.c
index ed78ad3..43f2c5f 100644
--- a/test.c
+++ b/test.c
@@ -542,10 +542,18 @@ GetScaleLock (struct wl_client *client, struct wl_resource *resource,
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 =
{
.get_test_surface = GetTestSurface,
.get_scale_lock = GetScaleLock,
+ .get_test_seat = GetTestSeat,
};
@@ -634,3 +642,20 @@ XLHandleOneXEventForTest (XEvent *event)
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;
+}
diff --git a/tests/Imakefile b/tests/Imakefile
index b020fd9..9bb26bc 100644
--- a/tests/Imakefile
+++ b/tests/Imakefile
@@ -40,7 +40,9 @@ ScannerTarget(viewporter)
OBJS6 = $(COMMONSRCS) subsurface_test.o
SRCS7 = $(COMMONSRCS) scale_test.c
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. */
$(OBJS1): $(HEADER)
@@ -55,9 +57,10 @@ NormalProgramTarget(transform_test,$(OBJS4),NullParameter,$(LOCAL_LIBRARIES),Nul
NormalProgramTarget(viewporter_test,$(OBJS5),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
NormalProgramTarget(subsurface_test,$(OBJS6),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($(SRCS4),$(SRCS5),$(SRCS6))
-DependTarget3($(SRCS7),NullParameter,NullParameter)
+DependTarget3($(SRCS7),$(SRCS8),NullParameter)
all:: $(PROGRAMS)
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 80a79a0..f91eb1d 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -21,7 +21,7 @@
pushd "$(dirname $0)"
declare -a standard_tests=(
simple_test damage_test transform_test viewporter_test
- subsurface_test scale_test
+ subsurface_test scale_test seat_test
)
make -C . "${standard_tests[@]}"
diff --git a/tests/svnignore.txt b/tests/svnignore.txt
index e0d4c69..283d6af 100644
--- a/tests/svnignore.txt
+++ b/tests/svnignore.txt
@@ -7,6 +7,7 @@ transform_test
viewporter_test
subsurface_test
scale_test
+seat_test
imgview
reject.dump
Makefile
diff --git a/tests/test_harness.c b/tests/test_harness.c
index f89ebd3..efb7744 100644
--- a/tests/test_harness.c
+++ b/tests/test_harness.c
@@ -372,6 +372,20 @@ test_log (const char *format, ...)
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
make_test_surface (struct test_display *display,
struct wl_surface **surface_return,
@@ -811,6 +825,40 @@ test_init (void)
= 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))
test_complete (void)
{
diff --git a/tests/test_harness.h b/tests/test_harness.h
index aa54a03..7cbdf3e 100644
--- a/tests/test_harness.h
+++ b/tests/test_harness.h
@@ -23,6 +23,8 @@ along with 12to11. If not, see . */
#include
#include
#include
+#include
+#include
#include
@@ -31,6 +33,21 @@ along with 12to11. If not, see . */
#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
{
/* The wayland display. */
@@ -57,6 +74,9 @@ struct test_display
/* Test interfaces. */
struct test_interface *interfaces;
+ /* The test seat. */
+ struct test_seat *seat;
+
/* The number of such 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_complete (void) __attribute__ ((noreturn));
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])