summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-09-17 17:35:05 -0400
committerKristian Høgsberg <krh@redhat.com>2009-09-17 17:51:08 -0400
commit3d4b76fc5e0c0ebde31173973d3efa6c0a1010fa (patch)
tree101c2d2bcfbed5bf3c7fce7c359af12f2cf9c827
parent8902ed4c7975fce8a7e8e6b64ef8623dc0681279 (diff)
Fixes for input redirection - needs SetDeviceRedirectWindow
-rw-r--r--src/wayland.c166
1 files changed, 135 insertions, 31 deletions
diff --git a/src/wayland.c b/src/wayland.c
index e53b06a0..feee7052 100644
--- a/src/wayland.c
+++ b/src/wayland.c
@@ -33,6 +33,8 @@
#include <xkbsrv.h>
#include <xf86Xinput.h>
#include "i830.h"
+#undef ALIGN /* HACK, remove this from wayland header */
+#include <wayland-util.h>
#include <wayland-client.h>
#include <X11/extensions/compositeproto.h>
#include <compositeext.h>
@@ -40,11 +42,13 @@
static int wayland_window_private_key_index;
static DevPrivateKey wayland_window_private_key = &wayland_window_private_key_index;
-struct xwl_window_private {
+struct xwl_window {
struct xwl_context *context;
struct wl_surface *surface;
struct wl_visual *visual;
+ int x, y;
WindowPtr window;
+ struct wl_list link;
};
struct xwl_context {
@@ -59,11 +63,10 @@ struct xwl_context {
/* FIXME: Hack. */
int32_t width, height;
- DeviceIntPtr pointer;
- DeviceIntPtr keyboard;
-
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
+
+ struct wl_list window_list;
};
struct xwl_output {
@@ -74,6 +77,17 @@ struct xwl_output {
xf86Monitor monitor;
};
+struct xwl_input_device {
+ DeviceIntPtr pointer;
+ DeviceIntPtr keyboard;
+ struct xwl_context *context;
+ struct wl_input_device *input_device;
+ int grab;
+ struct xwl_window *focus_window;
+ int32_t grab_x, grab_y;
+ int alt;
+};
+
/* OMG the horror of the xf86 input wrapper... Fortunately, we don't
* have to use that. */
@@ -108,17 +122,18 @@ wayland_input_kbd_ctrl(DeviceIntPtr device, KeybdCtrl *ctrl)
}
static int
-wayland_input_init_pointer(struct xwl_context *context)
+wayland_input_init_pointer(struct xwl_input_device *d, struct xwl_context *context)
{
DeviceIntPtr device;
- int min_x = 0, min_y = 0, max_x = context->width, max_y = context->height;
- static unsigned char map[] = { 1, 2, 3 };
+ int min_x = 0, min_y = 0;
+ int max_x = context->width, max_y = context->height;
+ static unsigned char map[] = { 0, 1, 2, 3 };
CARD32 atom;
char *name = "wayland";
Atom labels[3];
device = AddInputDevice(serverClient, wayland_input_proc, TRUE);
- context->pointer = device;
+ d->pointer = device;
atom = MakeAtom(name, strlen(name), TRUE);
AssignTypeAndName(device, atom, name);
@@ -152,7 +167,7 @@ wayland_input_init_pointer(struct xwl_context *context)
}
static int
-wayland_input_init_keyboard(struct xwl_context *context)
+wayland_input_init_keyboard(struct xwl_input_device *d, struct xwl_context *context)
{
DeviceIntPtr device;
CARD32 atom;
@@ -161,7 +176,7 @@ wayland_input_init_keyboard(struct xwl_context *context)
XkbRMLVOSet rmlvo;
device = AddInputDevice(serverClient, wayland_input_proc, TRUE);
- context->keyboard = device;
+ d->keyboard = device;
atom = MakeAtom(name, strlen(name), TRUE);
AssignTypeAndName(device, atom, name);
@@ -224,13 +239,61 @@ block_handler(pointer data, struct timeval **tv, pointer read_mask)
WL_DISPLAY_WRITABLE);
}
+static struct xwl_window *
+find_window(struct xwl_context *context, struct wl_surface *surface)
+{
+ struct xwl_window *window;
+
+ window = container_of(context->window_list.next, struct xwl_window, link);
+ while (&window->link != &context->window_list) {
+
+ if (window->surface == surface)
+ return window;
+
+ window = container_of(window->link.next,
+ struct xwl_window, link);
+ }
+
+ return NULL;
+}
+
static void
handle_motion(void *data, struct wl_input_device *input_device,
int32_t x, int32_t y, int32_t sx, int32_t sy)
{
- struct xwl_context *context = data;
-
- xf86PostMotionEvent(context->pointer, TRUE, 0, 2, x, y);
+ struct xwl_window *window;
+ struct xwl_input_device *d = data;
+ int32_t dx, dy;
+
+ if (d->focus_window) {
+ dx = d->focus_window->window->drawable.x;
+ dy = d->focus_window->window->drawable.y;
+ } else {
+ dx = 0;
+ dy = 0;
+ }
+
+ if (!d->grab) {
+ xf86PostMotionEvent(d->pointer, TRUE, 0, 2, sx + dx, sy + dy);
+ return;
+ }
+
+ window = d->focus_window;
+ window->x = d->grab_x + x;
+ window->y = d->grab_y + y;
+
+#if 0
+ /* Hmm... */
+ window->window->drawable.x = window->x;
+ window->window->drawable.y = window->y;
+#endif
+
+ wl_surface_map(d->focus_window->surface,
+ window->x,
+ window->y,
+ window->window->drawable.width,
+ window->window->drawable.height);
+ wl_compositor_commit(d->context->compositor, 0);
}
static void
@@ -238,9 +301,18 @@ handle_button(void *data, struct wl_input_device *input_device,
uint32_t button, uint32_t state,
int32_t x, int32_t y, int32_t sx, int32_t sy)
{
- struct xwl_context *context = data;
+ struct xwl_input_device *d = data;
int index;
+ if (button == BTN_LEFT && state == 1 && d->alt) {
+ d->grab_x = d->focus_window->x - x;
+ d->grab_y = d->focus_window->y - y;
+ d->grab = TRUE;
+ return;
+ } else if (button == BTN_LEFT && state == 0 && d->grab) {
+ d->grab = FALSE;
+ }
+
switch (button) {
case BTN_MIDDLE:
index = 2;
@@ -253,16 +325,23 @@ handle_button(void *data, struct wl_input_device *input_device,
break;
}
- xf86PostButtonEvent(context->pointer, TRUE, index, state, 0, 0);
+ xf86PostButtonEvent(d->pointer, TRUE, index, state, 0, 0);
}
static void
handle_key(void *data, struct wl_input_device *input_device,
uint32_t key, uint32_t state)
{
- struct xwl_context *context = data;
+ struct xwl_input_device *d = data;
+
+ switch (key) {
+ case KEY_LEFTALT:
+ case KEY_RIGHTALT:
+ d->alt = state;
+ break;
+ }
- xf86PostKeyboardEvent(context->pointer, key + 8, state);
+ xf86PostKeyboardEvent(d->keyboard, key + 8, state);
}
static void
@@ -270,6 +349,15 @@ handle_pointer_focus(void *data,
struct wl_input_device *input_device,
struct wl_surface *surface)
{
+ struct xwl_input_device *d = data;
+
+ d->focus_window = find_window(d->context, surface);
+ if (d->focus_window)
+ SetDeviceRedirectWindow(d->pointer,
+ d->focus_window->window);
+ else
+ SetDeviceRedirectWindow(d->pointer,
+ PointerRootWin);
}
static void
@@ -492,6 +580,25 @@ create_output(struct xwl_context *context, struct wl_object *object)
}
static void
+create_input_device(struct xwl_context *context, struct wl_object *object)
+{
+ struct xwl_input_device *input_device;
+ struct wl_input_device *device = (struct wl_input_device *) object;
+
+ input_device = malloc(sizeof *input_device);
+ memset(input_device, 0, sizeof input_device);
+
+ input_device->input_device = device;
+ input_device->context = context;
+ wayland_input_init_pointer(input_device, context);
+ wayland_input_init_keyboard(input_device, context);
+ wl_input_device_add_listener(device, &input_device_listener,
+ input_device);
+
+ ErrorF("created input device %p\n", input_device);
+}
+
+static void
global_handler(struct wl_display *display,
struct wl_object *object, void *data)
{
@@ -502,10 +609,7 @@ global_handler(struct wl_display *display,
} else if (wl_object_implements(object, "output", 1)) {
create_output(context, object);
} else if (wl_object_implements(object, "input_device", 1)) {
- struct wl_input_device *device =
- (struct wl_input_device *) object;
- wl_input_device_add_listener(device,
- &input_device_listener, context);
+ create_input_device(context, object);
}
}
@@ -536,7 +640,7 @@ wayland_realize_window (WindowPtr pWin)
struct xwl_context *context = pI830->wayland_data;
Bool ret = TRUE;
PixmapPtr pPixmap;
- struct xwl_window_private *priv;
+ struct xwl_window *priv;
drm_intel_bo *bo;
uint32_t name;
@@ -551,7 +655,7 @@ wayland_realize_window (WindowPtr pWin)
pPixmap = (*pScreen->GetWindowPixmap)(pWin);
if (!context->rootless)
- return;
+ return ret;
/* Redirect child windows of root window. We're better off
* doing this at init time, but need to find the right time
@@ -585,6 +689,8 @@ wayland_realize_window (WindowPtr pWin)
}
priv->window = pWin;
priv->visual = wl_display_get_rgb_visual(context->display);
+ priv->x = pWin->drawable.x;
+ priv->y = pWin->drawable.y;
bo = i830_get_pixmap_bo (pPixmap);
if (drm_intel_bo_flink(bo, &name) != 0) {
@@ -595,7 +701,8 @@ wayland_realize_window (WindowPtr pWin)
pPixmap->drawable.width,
pPixmap->drawable.height,
pPixmap->devKind, priv->visual);
- wl_surface_map(priv->surface, 50, 50,
+ wl_surface_map(priv->surface,
+ priv->x, priv->y,
pPixmap->drawable.width,
pPixmap->drawable.height);
wl_compositor_commit(context->compositor, 0);
@@ -603,9 +710,7 @@ wayland_realize_window (WindowPtr pWin)
/* FIXME: Set private in CreateWindow, probably. */
dixSetPrivate(&pWin->devPrivates, wayland_window_private_key, priv);
- ErrorF("created wayland surface for window %p, pixmap %p, %dx%d, stride %d, name %d\n",
- pWin, pPixmap, pPixmap->drawable.width, pPixmap->drawable.height,
- pPixmap->devKind, name);
+ wl_list_insert(&context->window_list, &priv->link);
return ret;
}
@@ -617,7 +722,7 @@ wayland_unrealize_window (WindowPtr pWin)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
struct xwl_context *context = pI830->wayland_data;
- struct xwl_window_private *priv;
+ struct xwl_window *priv;
Bool ret = TRUE;
pScreen->UnrealizeWindow = context->UnrealizeWindow;
@@ -630,6 +735,7 @@ wayland_unrealize_window (WindowPtr pWin)
priv = dixLookupPrivate(&pWin->devPrivates, wayland_window_private_key);
if (priv) {
wl_surface_destroy(priv->surface);
+ wl_list_remove(&priv->link);
free(priv);
dixSetPrivate(&pWin->devPrivates, wayland_window_private_key, NULL);
}
@@ -669,6 +775,7 @@ wayland_pre_init(ScrnInfoPtr pScrn)
memset(context, 0, sizeof *context);
context->rootless = 1;
context->pScrn = pScrn;
+ wl_list_init(&context->window_list);
context->display = wl_display_create(socket_name, sizeof socket_name);
if (context->display == NULL) {
ErrorF("wl_display_create failed\n");
@@ -695,9 +802,6 @@ wayland_pre_init(ScrnInfoPtr pScrn)
xf86InitialConfiguration(pScrn, TRUE);
- wayland_input_init_pointer(context);
- wayland_input_init_keyboard(context);
-
return TRUE;
}