summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/surface/wld.c172
1 files changed, 106 insertions, 66 deletions
diff --git a/src/surface/wld.c b/src/surface/wld.c
index 3780431..198c15f 100644
--- a/src/surface/wld.c
+++ b/src/surface/wld.c
@@ -32,6 +32,12 @@
#include "plot.h"
#include "cursor.h"
+struct wld_event {
+ struct wld_event *next;
+
+ nsfb_event_t event;
+};
+
/** structure for display, registry and other global objects that
* should be cached when connecting to a wayland instance
*/
@@ -59,6 +65,10 @@ struct wld_connection {
/** list of input seats */
struct wl_list input_list;
+
+ /** event queue */
+ struct wld_event *event_head;
+ struct wld_event *event_tail;
};
/** wayland input seat */
@@ -908,41 +918,50 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
}
static void
-pointer_handle_motion(void *data, struct wl_pointer *pointer,
- uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
+enqueue_wld_event(struct wld_connection *connection, struct wld_event* event)
{
-#if 0
- struct input *input = data;
- struct window *window = input->pointer_focus;
- struct widget *widget;
- int cursor;
- float sx = wl_fixed_to_double(sx_w);
- float sy = wl_fixed_to_double(sy_w);
-
- input->sx = sx;
- input->sy = sy;
+ event->next = NULL;
+ if (connection->event_tail == NULL) {
+ connection->event_head = event;
+ connection->event_tail = event;
+ } else {
+ connection->event_tail->next = event;
+ connection->event_tail = event;
+ }
+}
- if (!window)
- return;
+static struct wld_event*
+dequeue_wld_event(struct wld_connection *connection)
+{
+ struct wld_event* event = connection->event_head;
- if (!(input->grab && input->grab_button)) {
- widget = window_find_widget(window, sx, sy);
- input_set_focus_widget(input, widget, sx, sy);
+ if (event != NULL) {
+ connection->event_head = event->next;
+ if (connection->event_head == NULL) {
+ connection->event_tail = connection->event_head;
}
+ }
+ return event;
+}
- if (input->grab)
- widget = input->grab;
- else
- widget = input->focus_widget;
- if (widget && widget->motion_handler)
- cursor = widget->motion_handler(input->focus_widget,
- input, time, sx, sy,
- widget->user_data);
- else
- cursor = input->focus_widget->default_cursor;
-
- input_set_pointer_image(input, cursor);
-#endif
+static void
+pointer_handle_motion(void *data,
+ struct wl_pointer *pointer,
+ uint32_t time,
+ wl_fixed_t sx_w,
+ wl_fixed_t sy_w)
+{
+ struct wld_input *input = data;
+ struct wld_event *event;
+
+ event = calloc(1, sizeof(struct wld_event));
+
+ event->event.type = NSFB_EVENT_MOVE_ABSOLUTE;
+ event->event.value.vector.x = wl_fixed_to_int(sx_w);
+ event->event.value.vector.y = wl_fixed_to_int(sy_w);
+ event->event.value.vector.z = 0;
+
+ enqueue_wld_event(input->connection, event);
}
static void
@@ -1000,12 +1019,12 @@ static const struct wl_pointer_listener pointer_listener = {
};
static void
-seat_handle_capabilities(void *data,
+seat_handle_capabilities(void *data,
struct wl_seat *seat,
enum wl_seat_capability caps)
{
struct wld_input *input = data;
-#if 0
+
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
input->pointer = wl_seat_get_pointer(seat);
@@ -1016,7 +1035,7 @@ seat_handle_capabilities(void *data,
wl_pointer_destroy(input->pointer);
input->pointer = NULL;
}
-#endif
+
#if 0
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
input->keyboard = wl_seat_get_keyboard(seat);
@@ -1039,7 +1058,7 @@ static const struct wl_seat_listener seat_listener = {
* new seat added
*/
static struct wld_input *
-new_input_seat(struct wld_connection *connection,
+new_input_seat(struct wld_connection *connection,
struct wl_registry *registry,
uint32_t id)
{
@@ -1058,7 +1077,7 @@ new_input_seat(struct wld_connection *connection,
return NULL;
}
- //wl_seat_add_listener(input->seat, &seat_listener, input);
+ wl_seat_add_listener(input->seat, &seat_listener, input);
return input;
}
@@ -1106,7 +1125,7 @@ registry_handle_global(void *ctx,
}
} else if (strcmp(interface, "wl_seat") == 0) {
- struct wld_input *input;
+ struct wld_input *input;
input = new_input_seat(connection, registry, id);
if (input != NULL) {
@@ -1669,6 +1688,7 @@ static bool wld_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
{
wldstate_t *wldstate = nsfb->surface_priv;
int ret = 0; /* number of events dispatched */
+ struct wld_event* wldevent; /* input event off queue */
if (wldstate == NULL) {
return false;
@@ -1677,30 +1697,38 @@ static bool wld_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
/* flush any pending outgoing messages to server */
wl_display_flush(wldstate->connection->display);
+ /* if there are queued input events, return them first */
+ wldevent = dequeue_wld_event(wldstate->connection);
+ if (wldevent != NULL) {
+ *event = wldevent->event;
+ free(wldevent);
+ return true;
+ }
+
if (timeout < 0) {
/* caller wants to wait forever for an event */
ret = wl_display_dispatch(wldstate->connection->display);
} else {
- int confd;
- fd_set rfds;
- struct timeval tv;
- int retval;
+ int confd;
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
- confd = wl_display_get_fd(wldstate->connection->display);
+ confd = wl_display_get_fd(wldstate->connection->display);
- FD_ZERO(&rfds);
- FD_SET(confd, &rfds);
+ FD_ZERO(&rfds);
+ FD_SET(confd, &rfds);
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = timeout % 1000;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = timeout % 1000;
- retval = select(confd + 1, &rfds, NULL, NULL, &tv);
- if (retval == 0) {
- /* timeout, nothing ready to read */
- ret = wl_display_dispatch_pending(wldstate->connection->display);
- } else {
- ret = wl_display_dispatch(wldstate->connection->display);
- }
+ retval = select(confd + 1, &rfds, NULL, NULL, &tv);
+ if (retval == 0) {
+ /* timeout, nothing ready to read */
+ ret = wl_display_dispatch_pending(wldstate->connection->display);
+ } else {
+ ret = wl_display_dispatch(wldstate->connection->display);
+ }
}
/* check for connection error */
@@ -1709,11 +1737,29 @@ static bool wld_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
event->type = NSFB_EVENT_CONTROL;
event->value.controlcode = NSFB_CONTROL_QUIT;
return true;
+
+ } else if (ret == 0) {
+ /* timeout and no messages were processed and the input queue was
+ * empty on entry
+ */
+ event->type = NSFB_EVENT_CONTROL;
+ event->value.controlcode = NSFB_CONTROL_TIMEOUT;
+ return true;
}
- event->type = NSFB_EVENT_NONE;
+ /* messages were processed, they might have been input events */
- return false;
+ wldevent = dequeue_wld_event(wldstate->connection);
+ if (wldevent == NULL) {
+ /* messages were not input events so signal no event */
+ return false;
+ }
+
+ *event = wldevent->event;
+
+ free(wldevent);
+
+ return true;
}
#if 0
@@ -1887,13 +1933,7 @@ static int wld_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
static int
wld_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
{
-}
-
-#if 0
-static int
-x_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
-{
- xstate_t *xstate = nsfb->surface_priv;
+ wldstate_t *wldstate = nsfb->surface_priv;
nsfb_bbox_t redraw;
nsfb_bbox_t fbarea;
@@ -1914,22 +1954,22 @@ x_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
nsfb_cursor_plot(nsfb, cursor);
/* TODO: This is hediously ineficient - should keep the pointer image
- * as a pixmap and plot server side
+ * as a surface and composite server side
*/
- update_and_redraw_pixmap(xstate, redraw.x0, redraw.y0, redraw.x1 - redraw.x0, redraw.y1 - redraw.y0);
+ update_and_redraw(wldstate, redraw.x0, redraw.y0, redraw.x1 - redraw.x0, redraw.y1 - redraw.y0);
}
return true;
+
}
-#endif
+
static int wld_update(nsfb_t *nsfb, nsfb_bbox_t *box)
{
wldstate_t *wldstate = nsfb->surface_priv;
struct nsfb_cursor_s *cursor = nsfb->cursor;
- if ((cursor != NULL) &&
- (cursor->plotted == false)) {
+ if ((cursor != NULL) && (cursor->plotted == false)) {
nsfb_cursor_plot(nsfb, cursor);
}