diff options
author | Kristian Høgsberg <krh@redhat.com> | 2009-09-17 17:35:05 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2009-09-17 17:51:08 -0400 |
commit | 3d4b76fc5e0c0ebde31173973d3efa6c0a1010fa (patch) | |
tree | 101c2d2bcfbed5bf3c7fce7c359af12f2cf9c827 | |
parent | 8902ed4c7975fce8a7e8e6b64ef8623dc0681279 (diff) |
Fixes for input redirection - needs SetDeviceRedirectWindow
-rw-r--r-- | src/wayland.c | 166 |
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; } |