summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-09-13 21:21:34 -0400
committerKristian Høgsberg <krh@redhat.com>2009-09-13 21:21:34 -0400
commit8902ed4c7975fce8a7e8e6b64ef8623dc0681279 (patch)
treebe4aa644d021879c6eed9e18830777fcab80407e
parentdd5ba49e035f68439a9c15a3e591d1bf30ecf4d9 (diff)
First step towards rootless X
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_driver.c3
-rw-r--r--src/wayland.c197
3 files changed, 164 insertions, 37 deletions
diff --git a/src/i830.h b/src/i830.h
index 912a77dc..5375a57d 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -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);