diff options
author | Kristian Høgsberg <krh@redhat.com> | 2009-09-13 21:21:34 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2009-09-13 21:21:34 -0400 |
commit | 8902ed4c7975fce8a7e8e6b64ef8623dc0681279 (patch) | |
tree | be4aa644d021879c6eed9e18830777fcab80407e | |
parent | dd5ba49e035f68439a9c15a3e591d1bf30ecf4d9 (diff) |
First step towards rootless X
-rw-r--r-- | src/i830.h | 1 | ||||
-rw-r--r-- | src/i830_driver.c | 3 | ||||
-rw-r--r-- | src/wayland.c | 197 |
3 files changed, 164 insertions, 37 deletions
@@ -625,6 +625,7 @@ typedef struct _I830Rec { #ifdef WAYLAND extern Bool wayland_pre_init(ScrnInfoPtr pScrn); extern void wayland_post_damage(I830Ptr pI830); +extern void wayland_init_rootless(ScrnInfoPtr pScrn); #endif #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) diff --git a/src/i830_driver.c b/src/i830_driver.c index 1d900e39..9d13fad9 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2792,6 +2792,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = i830CreateScreenResources; + wayland_init_rootless (pScrn); + if (!xf86CrtcScreenInit (pScreen)) return FALSE; @@ -2840,7 +2842,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); #endif - /* Wrap pointer motion to flip touch screen around */ pI830->PointerMoved = pScrn->PointerMoved; pScrn->PointerMoved = I830PointerMoved; diff --git a/src/wayland.c b/src/wayland.c index fd0edda3..e53b06a0 100644 --- a/src/wayland.c +++ b/src/wayland.c @@ -34,6 +34,18 @@ #include <xf86Xinput.h> #include "i830.h" #include <wayland-client.h> +#include <X11/extensions/compositeproto.h> +#include <compositeext.h> + +static int wayland_window_private_key_index; +static DevPrivateKey wayland_window_private_key = &wayland_window_private_key_index; + +struct xwl_window_private { + struct xwl_context *context; + struct wl_surface *surface; + struct wl_visual *visual; + WindowPtr window; +}; struct xwl_context { ScrnInfoPtr pScrn; @@ -42,12 +54,16 @@ struct xwl_context { struct wl_compositor *compositor; struct wl_surface *surface; uint32_t mask; + int rootless; /* FIXME: Hack. */ int32_t width, height; DeviceIntPtr pointer; DeviceIntPtr keyboard; + + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; }; struct xwl_output { @@ -85,38 +101,6 @@ wayland_input_ptr_ctrl_proc(DeviceIntPtr device, PtrCtrl *ctrl) } static void -wayland_input_post_motion_event(struct xwl_context *context, int x, int y) -{ - xf86PostMotionEvent(context->pointer, TRUE, 0, 2, x, y); -} - -static void -wayland_input_post_button_event(struct xwl_context *context, int button, int state) -{ - int index; - - switch (button) { - case BTN_MIDDLE: - index = 2; - break; - case BTN_RIGHT: - index = 3; - break; - default: - index = button - BTN_LEFT + 1; - break; - } - - xf86PostButtonEvent(context->pointer, TRUE, index, state, 0, 0); -} - -static void -wayland_input_post_key_event(struct xwl_context *context, int key, int state) -{ - xf86PostKeyboardEvent(context->pointer, key + 8, state); -} - -static void wayland_input_kbd_ctrl(DeviceIntPtr device, KeybdCtrl *ctrl) { /* FIXME: Set keyboard leds based on CAPSFLAG etc being set in @@ -246,7 +230,7 @@ handle_motion(void *data, struct wl_input_device *input_device, { struct xwl_context *context = data; - wayland_input_post_motion_event(context, sx, sy); + xf86PostMotionEvent(context->pointer, TRUE, 0, 2, x, y); } static void @@ -255,8 +239,21 @@ handle_button(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; + int index; + + switch (button) { + case BTN_MIDDLE: + index = 2; + break; + case BTN_RIGHT: + index = 3; + break; + default: + index = button - BTN_LEFT + 1; + break; + } - wayland_input_post_button_event(context, button, state); + xf86PostButtonEvent(context->pointer, TRUE, index, state, 0, 0); } static void @@ -265,10 +262,9 @@ handle_key(void *data, struct wl_input_device *input_device, { struct xwl_context *context = data; - wayland_input_post_key_event(context, key, state); + xf86PostKeyboardEvent(context->pointer, key + 8, state); } - static void handle_pointer_focus(void *data, struct wl_input_device *input_device, @@ -328,6 +324,9 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t name; struct wl_visual *visual; + if (context->rootless) + return TRUE; + visual = wl_display_get_rgb_visual(context->display); if (dri_bo_flink(pI830->front_buffer->bo, &name) != 0) @@ -528,6 +527,130 @@ static const xf86CrtcConfigFuncsRec config_funcs = { static const char socket_name[] = "\0wayland"; +static Bool +wayland_realize_window (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + struct xwl_context *context = pI830->wayland_data; + Bool ret = TRUE; + PixmapPtr pPixmap; + struct xwl_window_private *priv; + drm_intel_bo *bo; + uint32_t name; + + pScreen->RealizeWindow = context->RealizeWindow; + + if (!(*pScreen->RealizeWindow) (pWin)) + ret = FALSE; + + context->RealizeWindow = pScreen->RealizeWindow; + pScreen->RealizeWindow = wayland_realize_window; + + pPixmap = (*pScreen->GetWindowPixmap)(pWin); + + if (!context->rootless) + return; + + /* Redirect child windows of root window. We're better off + * doing this at init time, but need to find the right time + * after the root window has been created. */ + if (pWin->parent == NULL) { + CompositeRedirectSubwindows(pWin, CompositeRedirectManual); + return ret; + } + + if (dixLookupPrivate(&pWin->devPrivates, wayland_window_private_key)) { + ErrorF("already realized window %p\n", pWin); + return ret; + } + + /* FIXME: This doesn't deal with reparenting. Reparenting a + * toplevel window into another will have to destroy a wayland + * surface. */ + + if ((*pScreen->GetWindowPixmap)(pWin->parent) == pPixmap) + return ret; + + /* If not the root window, create a wayland surface using the + * backing pixmap. */ + + priv = malloc(sizeof *priv); + priv->context = context; + priv->surface = wl_compositor_create_surface(context->compositor); + if (priv->surface == NULL) { + ErrorF("wl_display_create_surface failed\n"); + return ret; + } + priv->window = pWin; + priv->visual = wl_display_get_rgb_visual(context->display); + + bo = i830_get_pixmap_bo (pPixmap); + if (drm_intel_bo_flink(bo, &name) != 0) { + ErrorF("failed to name buffer\n"); + } + + wl_surface_attach(priv->surface, name, + pPixmap->drawable.width, + pPixmap->drawable.height, + pPixmap->devKind, priv->visual); + wl_surface_map(priv->surface, 50, 50, + pPixmap->drawable.width, + pPixmap->drawable.height); + wl_compositor_commit(context->compositor, 0); + + /* 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); + + return ret; +} + +static Bool +wayland_unrealize_window (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + struct xwl_context *context = pI830->wayland_data; + struct xwl_window_private *priv; + Bool ret = TRUE; + + pScreen->UnrealizeWindow = context->UnrealizeWindow; + if (!(*pScreen->UnrealizeWindow)(pWin)) + ret = FALSE; + + context->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreen->UnrealizeWindow = wayland_unrealize_window; + + priv = dixLookupPrivate(&pWin->devPrivates, wayland_window_private_key); + if (priv) { + wl_surface_destroy(priv->surface); + free(priv); + dixSetPrivate(&pWin->devPrivates, wayland_window_private_key, NULL); + } + + return ret; +} + +void +wayland_init_rootless(ScrnInfoPtr pScrn) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + I830Ptr pI830 = I830PTR(pScrn); + struct xwl_context *context = pI830->wayland_data; + + context->RealizeWindow = pScreen->RealizeWindow; + pScreen->RealizeWindow = wayland_realize_window; + + context->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreen->UnrealizeWindow = wayland_unrealize_window; +} + Bool wayland_pre_init(ScrnInfoPtr pScrn) { @@ -544,6 +667,7 @@ wayland_pre_init(ScrnInfoPtr pScrn) } memset(context, 0, sizeof *context); + context->rootless = 1; context->pScrn = pScrn; context->display = wl_display_create(socket_name, sizeof socket_name); if (context->display == NULL) { @@ -581,6 +705,7 @@ void wayland_post_damage(I830Ptr pI830) { struct xwl_context *context = pI830->wayland_data; + /* FIXME: Need a list of surfaces with damage. */ wl_surface_damage(context->surface, 0, 0, 10, 10); wl_compositor_commit(context->compositor, 0); |