Whoops, found some compiler warnings with this patch... resending w/fix. U. Artie
>-----Original Message----- >From: Eoff, Ullysses A >Sent: Monday, September 24, 2012 1:16 PM >To: wayland-devel@lists.freedesktop.org >Cc: Eoff, Ullysses A >Subject: [PATCH] event-test: more aggressive event testing > >From: "U. Artie Eoff" <ullysses.a.e...@intel.com> > >Test surface pointer enter/leave/motion and surface leave/enter >events more aggressively. > >Depends on: >http://lists.freedesktop.org/archives/wayland-devel/2012- >September/005224.html > >Signed-off-by: U. Artie Eoff <ullysses.a.e...@intel.com> >--- > tests/event-test.c | 269 >++++++++++++++++++++++++++++++++++++++++++++++++---- > tests/test-client.c | 60 ++++++++++-- > tests/test-runner.c | 8 +- > 3 files changed, 305 insertions(+), 32 deletions(-) > >diff --git a/tests/event-test.c b/tests/event-test.c >index 2cbfc2d..3bcb76d 100644 >--- a/tests/event-test.c >+++ b/tests/event-test.c >@@ -25,50 +25,280 @@ > #include <sys/socket.h> > #include <assert.h> > #include <unistd.h> >- > #include <string.h> > > #include "test-runner.h" > >+struct state { >+ int px; // pointer x >+ int py; // pointer y >+ int sx; // surface x >+ int sy; // surface y >+ int sw; // surface width >+ int sh; // surface height >+}; >+ >+static int state_size = sizeof(struct state); >+ >+struct context { >+ struct weston_layer *layer; >+ struct weston_seat *seat; >+ struct weston_surface *surface; >+ int pointer_x; // server pointer x >+ int pointer_y; // server pointer y >+ int index; >+ struct wl_array states; >+}; >+ >+static void >+resize(struct context *context, int w, int h) >+{ >+ // resize the surface if the width or height is different >+ if (context->surface->geometry.width != w || >+ context->surface->geometry.height != h) { >+ >+ weston_surface_configure(context->surface, >+ context->surface->geometry.x, >+ context->surface->geometry.y, >+ w, h); >+ weston_surface_update_transform(context->surface); >+ weston_surface_damage(context->surface); >+ >+ fprintf(stderr, "resize surface: %d %d\n", >+ context->surface->geometry.width, >+ context->surface->geometry.height); >+ } >+} >+ >+static void >+move(struct context *context, int x, int y) >+{ >+ // move the surface if x or y is different >+ if (context->surface->geometry.x != x || >+ context->surface->geometry.y != y) { >+ >+ weston_surface_configure(context->surface, >+ x, y, >+ context->surface->geometry.width, >+ context->surface->geometry.height); >+ weston_surface_update_transform(context->surface); >+ weston_surface_damage(context->surface); >+ >+ fprintf(stderr, "move surface: %f %f\n", >+ context->surface->geometry.x, >+ context->surface->geometry.y); >+ } >+} >+ >+static int >+contains(struct context *context, int x, int y) >+{ >+ // test whether a global x,y point is contained in the surface >+ int sx = context->surface->geometry.x; >+ int sy = context->surface->geometry.y; >+ int sw = context->surface->geometry.width; >+ int sh = context->surface->geometry.height; >+ return x >= sx && y >= sy && x < sx + sw && y < sy + sh; >+} >+ >+static void >+move_pointer(struct context *context, int x, int y) >+{ >+ // move the pointer position if it is different >+ >+ if (contains(context, context->pointer_x, context->pointer_y)) { >+ // pointer is currently on the surface >+ notify_motion(context->seat, 100, >+ wl_fixed_from_int(x), wl_fixed_from_int(y)); >+ } else { >+ // pointer is not currently on the surface >+ notify_pointer_focus(context->seat, context->surface, >+ wl_fixed_from_int(x), wl_fixed_from_int(y)); >+ } >+ >+ // update server expected pointer location >+ context->pointer_x = x; >+ context->pointer_y = y; >+ >+ fprintf(stderr, "move pointer: %d %d\n", x, y); >+} >+ >+static void >+check_pointer(struct context *context, int cx, int cy) >+{ >+ // Check whether the client reported pointer position matches >+ // the server expected pointer position. The client >+ // reports -1,-1 when the pointer is not on its surface and >+ // a surface relative x,y otherwise. >+ int gx = context->surface->geometry.x + cx; >+ int gy = context->surface->geometry.y + cy; >+ if (!contains(context, gx, gy)) { >+ assert(!contains(context, context->pointer_x, context- >>pointer_y)); >+ } else { >+ assert(gx == context->pointer_x); >+ assert(gy == context->pointer_y); >+ } >+} >+ >+static void >+check_visible(struct context *context, int visible) >+{ >+ // Check whether the client reported surface visibility matches >+ // the servers expected surface visibility >+ int ow = context->surface->output->width; >+ int oh = context->surface->output->height; >+ int sx = context->surface->geometry.x; >+ int sy = context->surface->geometry.y; >+ int sw = context->surface->geometry.width; >+ int sh = context->surface->geometry.height; >+ >+ const int expect = sx < ow && sy < oh && sx + sw > 0 && sy + sh > 0; >+ >+ assert(visible == expect); >+} >+ >+static void >+handle_state(struct test_client *); >+ >+static void >+set_state(struct test_client *client) >+{ >+ struct state* state; >+ struct context *context = client->data; >+ >+ if (context->index < context->states.size) { >+ state = context->states.data + context->index; >+ resize(context, state->sw, state->sh); >+ move(context, state->sx, state->sy); >+ move_pointer(context, state->px, state->py); >+ context->index += state_size; >+ >+ test_client_send(client, "send-state\n"); >+ client->handle = handle_state; >+ } else { >+ test_client_send(client, "bye\n"); >+ client->handle = NULL; >+ } >+} >+ >+static void >+handle_state(struct test_client *client) >+{ >+ struct context *context = client->data; >+ wl_fixed_t x, y; >+ int visible; >+ >+ assert(sscanf(client->buf, "%d %d %d", &x, &y, &visible) == 3); >+ >+ check_pointer(context, wl_fixed_to_int(x), wl_fixed_to_int(y)); >+ check_visible(context, visible); >+ >+ set_state(client); >+} >+ >+static void >+add_state(struct context *context, int px, int py, int sx, int sy, int sw, >int sh) >+{ >+ struct state *state = wl_array_add(&context->states, sizeof(struct >state)); >+ >+ assert(state); >+ >+ state->px = px; >+ state->py = py; >+ state->sx = sx; >+ state->sy = sy; >+ state->sw = sw; >+ state->sh = sh; >+} >+ >+static void >+initialize_states(struct test_client *client) >+{ >+ struct context *context = client->data; >+ struct weston_surface *surface = context->surface; >+ >+ int x = surface->geometry.x; >+ int y = surface->geometry.y; >+ int w = surface->geometry.width; >+ int h = surface->geometry.height; >+ >+ wl_array_init(&context->states); >+ >+ add_state(context, x - 1, y - 1, x, y, w, h); // move pointer outside >top >left >+ add_state(context, x, y, x, y, w, h); // move pointer on top left >+ add_state(context, x - 1, y + h, x, y, w, h); // move pointer outside >bottom left >+ add_state(context, x, y + h - 1, x, y, w, h); // move pointer on bottom >left >+ add_state(context, x + w, y - 1, x, y, w, h); // move pointer outside >top right >+ add_state(context, x + w - 1, y, x, y, w, h); // move pointer on top >right >+ add_state(context, x + w, y + h, x, y, w, h); // move pointer outside >bottom right >+ add_state(context, x + w - 1, y + h - 1, x, y, w, h); // move pointer on >bottom right >+ >+ add_state(context, x + w/2, y - 1, x, y, w, h); // move pointer outside >top center >+ add_state(context, x + w/2, y, x, y, w, h); // move pointer on top >center >+ add_state(context, x + w/2, y + h, x, y, w, h); // move pointer outside >bottom center >+ add_state(context, x + w/2, y + h - 1, x, y, w, h); // move pointer on >bottom center >+ add_state(context, x - 1, y + h/2, x, y, w, h); // move pointer outside >left center >+ add_state(context, x, y + h/2, x, y, w, h); // move pointer on left >center >+ add_state(context, x + w, y + h/2, x, y, w, h); // move pointer outside >right center >+ add_state(context, x + w - 1, y + h/2, x, y, w, h); // move pointer on >right center >+ >+ add_state(context, 50, 50, x, y, w, h); // move pointer outside of >client >+ add_state(context, 50, 50, 0, 0, w, h); // move client center to pointer >+ >+ add_state(context, 0, 0, 0, -h, w, h); // not visible >+ add_state(context, 0, 0, 0, -h+1, w, h); // visible >+ add_state(context, 0, 0, 0, context->surface->output->height, w, h); >// not visible >+ add_state(context, 0, 0, 0, context->surface->output->height - 1, w, >h); // visible >+ >+ add_state(context, 0, 0, -w, 0, w, h); // not visible >+ add_state(context, 0, 0, -w+1, 0, w, h); // visible >+ add_state(context, 0, 0, context->surface->output->width, 0, w, h); // >not visible >+ add_state(context, 0, 0, context->surface->output->width - 1, 0, w, >h); // visible >+ >+ set_state(client); >+} >+ > static void > handle_surface(struct test_client *client) > { > uint32_t id; >+ struct context *context = client->data; > struct wl_resource *resource; >- struct weston_surface *surface; >- struct weston_layer *layer = client->data; > struct wl_list *seat_list; >- struct weston_seat *seat; > > assert(sscanf(client->buf, "surface %u", &id) == 1); >- fprintf(stderr, "got surface id %u\n", id); >+ fprintf(stderr, "server: got surface id %u\n", id); > resource = wl_client_get_object(client->client, id); > assert(resource); > assert(strcmp(resource->object.interface->name, "wl_surface") == >0); > >- surface = (struct weston_surface *) resource; >+ context->surface = (struct weston_surface *) resource; >+ weston_surface_set_color(context->surface, 0.0, 0.0, 0.0, 1.0); > >- weston_surface_configure(surface, 100, 100, 200, 200); >- weston_surface_update_transform(surface); >- weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0); >- wl_list_insert(&layer->surface_list, &surface->layer_link); >- weston_surface_damage(surface); >+ context->layer = malloc(sizeof *context->layer); >+ assert(context->layer); >+ weston_layer_init(context->layer, &client->compositor- >>cursor_layer.link); >+ wl_list_insert(&context->layer->surface_list, &context->surface- >>layer_link); > > seat_list = &client->compositor->seat_list; > assert(wl_list_length(seat_list) == 1); >- seat = container_of(seat_list->next, struct weston_seat, link); >+ context->seat = container_of(seat_list->next, struct weston_seat, >link); >+ > client->compositor->focus = 1; /* Make it work even if pointer is > * outside X window. */ >- notify_motion(seat, 100, >- wl_fixed_from_int(150), wl_fixed_from_int(150)); > >- test_client_send(client, "bye\n"); >+ resize(context, 100, 100); >+ move(context, 100, 100); >+ move_pointer(context, 150, 150); >+ >+ test_client_send(client, "send-state\n"); >+ client->handle = initialize_states; > } > > TEST(event_test) > { >+ struct context *context; > struct test_client *client; >- struct weston_layer *layer; > > client = test_client_launch(compositor, "test-client"); > client->terminate = 1; >@@ -76,8 +306,7 @@ TEST(event_test) > test_client_send(client, "create-surface\n"); > client->handle = handle_surface; > >- layer = malloc(sizeof *layer); >- assert(layer); >- weston_layer_init(layer, &compositor->cursor_layer.link); >- client->data = layer; >+ context = calloc(1, sizeof *context); >+ assert(context); >+ client->data = context; > } >diff --git a/tests/test-client.c b/tests/test-client.c >index 0009a8e..f8a1a7b 100644 >--- a/tests/test-client.c >+++ b/tests/test-client.c >@@ -35,6 +35,7 @@ struct display { > struct wl_compositor *compositor; > struct input *input; > struct output *output; >+ struct surface *surface; > }; > > struct input { >@@ -68,6 +69,7 @@ pointer_handle_enter(void *data, struct wl_pointer >*pointer, > input->pointer_focus = wl_surface_get_user_data(surface); > input->x = wl_fixed_to_double(x); > input->y = wl_fixed_to_double(y); >+ fprintf(stderr, "test-client: got pointer enter %f %f, surface %p\n", >input->x, input->y, surface); > } > > static void >@@ -77,6 +79,8 @@ pointer_handle_leave(void *data, struct wl_pointer >*pointer, > struct input *input = data; > > input->pointer_focus = NULL; >+ >+ fprintf(stderr, "test-client: got pointer leave, surface %p\n", >surface); > } > > static void >@@ -87,6 +91,8 @@ pointer_handle_motion(void *data, struct wl_pointer >*pointer, > > input->x = wl_fixed_to_double(x); > input->y = wl_fixed_to_double(y); >+ >+ fprintf(stderr, "test-client: got pointer motion %f %f\n", input->x, >input->y); > } > > static void >@@ -103,12 +109,14 @@ pointer_handle_button(void *data, struct >wl_pointer *pointer, > input->button_mask |= bit; > else > input->button_mask &= ~bit; >+ fprintf(stderr, "test-client: got pointer button %u %u\n", button, >state_w); > } > > static void > pointer_handle_axis(void *data, struct wl_pointer *pointer, > uint32_t time, uint32_t axis, wl_fixed_t value) > { >+ fprintf(stderr, "test-client: got pointer axis %u %d\n", axis, value); > } > > static void >@@ -116,6 +124,7 @@ keyboard_handle_keymap(void *data, struct >wl_keyboard *keyboard, > uint32_t format, int fd, uint32_t size) > { > close(fd); >+ fprintf(stderr, "test-client: got keyboard keymap\n"); > } > > static void >@@ -126,6 +135,7 @@ keyboard_handle_enter(void *data, struct >wl_keyboard *keyboard, > struct input *input = data; > > input->keyboard_focus = wl_surface_get_user_data(surface); >+ fprintf(stderr, "test-client: got keyboard enter, surface %p\n", >surface); > } > > static void >@@ -135,6 +145,7 @@ keyboard_handle_leave(void *data, struct >wl_keyboard *keyboard, > struct input *input = data; > > input->keyboard_focus = NULL; >+ fprintf(stderr, "test-client: got keyboard leave, surface %p\n", >surface); > } > > static void >@@ -142,6 +153,7 @@ keyboard_handle_key(void *data, struct wl_keyboard >*keyboard, > uint32_t serial, uint32_t time, uint32_t key, > uint32_t state) > { >+ fprintf(stderr, "test-client: got keyboard key %u %u\n", key, state); > } > > static void >@@ -150,6 +162,7 @@ keyboard_handle_modifiers(void *data, struct >wl_keyboard *keyboard, > uint32_t mods_latched, uint32_t mods_locked, > uint32_t group) > { >+ fprintf(stderr, "test-client: got keyboard modifier\n"); > } > > static const struct wl_pointer_listener pointer_listener = { >@@ -266,7 +279,7 @@ handle_global(struct wl_display *_display, uint32_t id, > &output_listener, output); > display->output = output; > >- fprintf(stderr, "created output global %p\n", display->output); >+ fprintf(stderr, "test-client: created output global %p\n", >display->output); > } > } > >@@ -278,7 +291,7 @@ surface_enter(void *data, > > surface->output = wl_output_get_user_data(output); > >- fprintf(stderr, "got surface enter, output %p\n", surface->output); >+ fprintf(stderr, "test-client: got surface enter, output %p\n", surface- >>output); > } > > static void >@@ -288,6 +301,8 @@ surface_leave(void *data, > struct surface *surface = data; > > surface->output = NULL; >+ >+ fprintf(stderr, "test-client: got surface leave, output %p\n", >wl_output_get_user_data(output)); > } > > static const struct wl_surface_listener surface_listener = { >@@ -296,6 +311,33 @@ static const struct wl_surface_listener >surface_listener = { > }; > > static void >+send_state(int fd, struct display* display) >+{ >+ char buf[64]; >+ int len; >+ int visible = display->surface->output != NULL; >+ wl_fixed_t x = wl_fixed_from_int(-1); >+ wl_fixed_t y = wl_fixed_from_int(-1); >+ >+ if (display->input->pointer_focus == display->surface) { >+ x = wl_fixed_from_double(display->input->x); >+ y = wl_fixed_from_double(display->input->y); >+ } >+ >+ if (visible) { >+ ///FIXME: this fails on multi-display setup >+// assert(display->surface->output == display->output); >+ } >+ >+ wl_display_flush(display->display); >+ >+ len = snprintf(buf, sizeof buf, "%d %d %d\n", x, y, visible); >+ assert(write(fd, buf, len) == len); >+ >+ wl_display_roundtrip(display->display); >+} >+ >+static void > create_surface(int fd, struct display *display) > { > struct surface *surface; >@@ -304,8 +346,10 @@ create_surface(int fd, struct display *display) > > surface = malloc(sizeof *surface); > assert(surface); >+ display->surface = surface; > surface->surface = wl_compositor_create_surface(display- >>compositor); > wl_surface_add_listener(surface->surface, &surface_listener, >surface); >+ > wl_display_flush(display->display); > > len = snprintf(buf, sizeof buf, "surface %d\n", >@@ -313,12 +357,8 @@ create_surface(int fd, struct display *display) > assert(write(fd, buf, len) == len); > > poll(NULL, 0, 100); /* Wait for next frame where we'll get events. */ >- wl_display_roundtrip(display->display); > >- assert(surface->output == display->output); >- assert(display->input->pointer_focus == surface); >- assert(display->input->x == 50); >- assert(display->input->y == 50); >+ wl_display_roundtrip(display->display); > } > > int main(int argc, char *argv[]) >@@ -346,7 +386,7 @@ int main(int argc, char *argv[]) > while (1) { > ret = read(fd, buf, sizeof buf); > if (ret == -1) { >- fprintf(stderr, "read error: fd %d, %m\n", fd); >+ fprintf(stderr, "test-client: read error: fd %d, %m\n", >fd); > return -1; > } > >@@ -356,8 +396,10 @@ int main(int argc, char *argv[]) > return 0; > } else if (strncmp(buf, "create-surface\n", ret) == 0) { > create_surface(fd, display); >+ } else if (strncmp(buf, "send-state\n", ret) == 0) { >+ send_state(fd, display); > } else { >- fprintf(stderr, "unknown command %.*s\n", ret, buf); >+ fprintf(stderr, "test-client: unknown command >%.*s\n", ret, buf); > return -1; > } > } >diff --git a/tests/test-runner.c b/tests/test-runner.c >index 09c2b1f..6ca087d 100644 >--- a/tests/test-runner.c >+++ b/tests/test-runner.c >@@ -40,7 +40,7 @@ test_client_cleanup(struct weston_process *proc, int >status) > struct test_client *client = > container_of(proc, struct test_client, proc); > >- fprintf(stderr, "test client exited, status %d\n", status); >+ fprintf(stderr, "server: test client exited, status %d\n", status); > > client->status = status; > client->done = 1; >@@ -60,7 +60,7 @@ test_client_data(int fd, uint32_t mask, void *data) > > len = read(client->fd, client->buf, sizeof client->buf); > assert(len >= 0); >- fprintf(stderr, "got %.*s from client\n", len - 1, client->buf); >+ fprintf(stderr, "server: got %.*s from client\n", len - 1, client->buf); > assert(client->buf[len - 1] == '\n'); > client->buf[len - 1] = '\0'; > >@@ -88,7 +88,7 @@ test_client_launch(struct weston_compositor >*compositor, const char *file_name) > snprintf(buf, sizeof buf, "%d", client_fd); > setenv("TEST_SOCKET", buf, 1); > snprintf(buf, sizeof buf, "%s/%s", getenv("abs_builddir"), file_name); >- fprintf(stderr, "launching %s\n", buf); >+ fprintf(stderr, "server: launching %s\n", buf); > > client->terminate = 0; > client->compositor = compositor; >@@ -117,6 +117,8 @@ test_client_send(struct test_client *client, const char >*fmt, ...) > len = vsnprintf(buf, sizeof buf, fmt, ap); > va_end(ap); > >+ fprintf(stderr, "server: sending %s", buf); >+ > assert(write(client->fd, buf, len) == len); > } > >-- >1.7.11.2 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel