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])