From 0c14bdb995f5aa9559ca7bf6a03e6ba52854cff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 18 Sep 2009 22:08:16 -0400 Subject: Add xwayland module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed and rebased from the xwayland-1.12 branch. Contributions from Christopher James Halse Rogers Corentin Chary Daniel Stone Kristian Høgsberg Robert Bragg Scott Moreau Tiago Vignatti Giovanni Campagna Jonas Ådahl Ray Strode Trevor McCort Rui Matos --- configure.ac | 15 + hw/xfree86/Makefile.am | 9 +- hw/xfree86/common/xf86AutoConfig.c | 12 +- hw/xfree86/common/xf86Config.c | 44 ++- hw/xfree86/common/xf86Globals.c | 2 + hw/xfree86/common/xf86Init.c | 32 ++ hw/xfree86/common/xf86Priv.h | 2 + hw/xfree86/common/xf86str.h | 1 + hw/xfree86/dri2/dri2.c | 7 +- hw/xfree86/dri2/dri2.h | 2 +- hw/xfree86/xwayland/.gitignore | 4 + hw/xfree86/xwayland/Makefile.am | 46 +++ hw/xfree86/xwayland/drm.xml | 139 +++++++ hw/xfree86/xwayland/xserver.xml | 18 + hw/xfree86/xwayland/xwayland-cursor.c | 250 +++++++++++++ hw/xfree86/xwayland/xwayland-drm.c | 250 +++++++++++++ hw/xfree86/xwayland/xwayland-input.c | 647 +++++++++++++++++++++++++++++++++ hw/xfree86/xwayland/xwayland-output.c | 438 ++++++++++++++++++++++ hw/xfree86/xwayland/xwayland-private.h | 142 ++++++++ hw/xfree86/xwayland/xwayland-window.c | 261 +++++++++++++ hw/xfree86/xwayland/xwayland.c | 393 ++++++++++++++++++++ hw/xfree86/xwayland/xwayland.h | 86 +++++ include/input.h | 2 +- include/os.h | 3 +- include/xorg-config.h.in | 3 + include/xorg-server.h.in | 3 + os/connection.c | 4 - 27 files changed, 2793 insertions(+), 22 deletions(-) create mode 100644 hw/xfree86/xwayland/.gitignore create mode 100644 hw/xfree86/xwayland/Makefile.am create mode 100644 hw/xfree86/xwayland/drm.xml create mode 100644 hw/xfree86/xwayland/xserver.xml create mode 100644 hw/xfree86/xwayland/xwayland-cursor.c create mode 100644 hw/xfree86/xwayland/xwayland-drm.c create mode 100644 hw/xfree86/xwayland/xwayland-input.c create mode 100644 hw/xfree86/xwayland/xwayland-output.c create mode 100644 hw/xfree86/xwayland/xwayland-private.h create mode 100644 hw/xfree86/xwayland/xwayland-window.c create mode 100644 hw/xfree86/xwayland/xwayland.c create mode 100644 hw/xfree86/xwayland/xwayland.h diff --git a/configure.ac b/configure.ac index 74819bf62..6d412f74a 100644 --- a/configure.ac +++ b/configure.ac @@ -626,6 +626,7 @@ AC_ARG_ENABLE(clientids, AS_HELP_STRING([--disable-clientids], [Build Xorg AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes]) AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes]) AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes]) +AC_ARG_ENABLE(wayland, AS_HELP_STRING([--disable-wayland], [Build Wayland extension (default: auto)]), [WAYLAND=$enableval], [WAYLAND=auto]) dnl DDXes. AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) @@ -1019,6 +1020,18 @@ fi if test "x$MITSHM" = xauto; then MITSHM="$ac_cv_sysv_ipc" fi + +WAYLAND_MODULES="wayland-client libdrm" +if test "x$WAYLAND" = xauto; then + PKG_CHECK_MODULES(XWAYLAND, $WAYLAND_MODULES, [WAYLAND=yes], [WAYLAND=no]) +fi +if test "x$WAYLAND" = xyes; then + PKG_CHECK_MODULES(XWAYLAND, $WAYLAND_MODULES) + AC_DEFINE(XORG_WAYLAND, 1, [Support wayland mode]) + WAYLAND_SCANNER_RULES(['$(top_srcdir)/hw/xfree86/xwayland']) +fi +AM_CONDITIONAL(WAYLAND, [test "x$WAYLAND" = xyes]) + AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes]) if test "x$MITSHM" = xyes; then AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension]) @@ -1248,6 +1261,7 @@ if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test " PKG_CHECK_MODULES([LIBDRM], $LIBDRM) fi fi +AM_CONDITIONAL(DRM, test "x$DRM" = xyes) if test "x$DRI2" = xyes; then save_CFLAGS=$CFLAGS @@ -2485,6 +2499,7 @@ hw/xfree86/dixmods/Makefile hw/xfree86/doc/Makefile hw/xfree86/dri/Makefile hw/xfree86/dri2/Makefile +hw/xfree86/xwayland/Makefile hw/xfree86/exa/Makefile hw/xfree86/exa/man/Makefile hw/xfree86/fbdevhw/Makefile diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 73e1b4c1f..9c82ffd70 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -14,10 +14,15 @@ DRI3_BUILDDIR = $(top_builddir)/dri3 DRI3_LIB = $(DRI3_BUILDDIR)/libdri3.la endif + if GLAMOR_EGL GLAMOR_EGL_SUBDIR = glamor_egl endif +if WAYLAND +WAYLAND_SUBDIR = xwayland +endif + if XF86UTILS XF86UTILS_SUBDIR = utils endif @@ -36,13 +41,13 @@ endif SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \ ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \ - $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \ + $(DRI2_SUBDIR) $(WAYLAND_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \ fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \ $(GLAMOR_EGL_SUBDIR) DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ parser ramdac shadowfb vbe vgahw \ - loader dixmods dri dri2 exa modes \ + loader dixmods dri dri2 exa modes xwayland \ utils doc man bin_PROGRAMS = Xorg diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 4eb86de22..47ef68462 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -274,11 +274,17 @@ listPossibleVideoDrivers(char *matches[], int nmatches) #if !defined(sun) /* Fallback to platform default frame buffer driver */ - if (i < (nmatches - 1)) { + if (i < (nmatches - 2)) { +#ifdef XORG_WAYLAND + if (xorgWayland) { + matches[i++] = xnfstrdup("wlglamor"); + matches[i++] = xnfstrdup("wayland"); + } else +#endif #if !defined(__linux__) && defined(__sparc__) - matches[i++] = xnfstrdup("wsfb"); + matches[i++] = xnfstrdup("wsfb"); #else - matches[i++] = xnfstrdup("fbdev"); + matches[i++] = xnfstrdup("fbdev"); #endif } #endif /* !sun */ diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 542d5abf6..7eb8b1b37 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -118,7 +118,8 @@ static ModuleDefault ModuleDefaults[] = { {.name = "fb",.toLoad = TRUE,.load_opt = NULL}, {.name = "shadow",.toLoad = TRUE,.load_opt = NULL}, #endif - {.name = NULL,.toLoad = FALSE,.load_opt = NULL} + {.name = "xwayland",.toLoad = FALSE,.load_opt=NULL}, + {.name = NULL,.toLoad = FALSE,.load_opt=NULL} }; /* Forward declarations */ @@ -260,6 +261,17 @@ xf86ModulelistFromConfig(void ***optlist) return NULL; } + /* + * Set the xwayland module to autoload if requested. + */ + if (xorgWayland) { + for (i=0 ; ModuleDefaults[i].name != NULL ; i++) { + if (strcmp(ModuleDefaults[i].name, "xwayland") == 0) { + ModuleDefaults[i].toLoad = TRUE; + } + } + } + if (xf86configptr->conf_modules) { /* Walk the disable list and let people know what we've parsed to * not be loaded @@ -507,9 +519,13 @@ xf86InputDriverlistFromConfig(void) static void fixup_video_driver_list(const char **drivers) { - static const char *fallback[4] = { "fbdev", "vesa", "wsfb", NULL }; + static const char *fallback_hw[4] = { "fbdev", "vesa", "wsfb", NULL }; const char **end, **drv; const char *x; +#ifdef XORG_WAYLAND + static const char *fallback_wl[2] = { "wayland", NULL }; +#endif + static const char **fallbacks; int i; /* walk to the end of the list */ @@ -520,9 +536,15 @@ fixup_video_driver_list(const char **drivers) * for each of the fallback drivers, if we find it in the list, * swap it with the last available non-fallback driver. */ - for (i = 0; fallback[i]; i++) { +#ifdef XORG_WAYLAND + if (xorgWayland) + fallbacks = fallback_wl; + else +#endif + fallbacks = fallback_hw; + for (i = 0; fallbacks[i]; i++) { for (drv = drivers; drv != end; drv++) { - if (strstr(*drv, fallback[i])) { + if (strstr(*drv, fallbacks[i])) { x = *drv; *drv = *end; *end = x; @@ -859,6 +881,13 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) } xf86Msg(from, "%sutomatically adding GPU devices\n", xf86Info.autoAddGPU ? "A" : "Not a"); + + /* FIXME: Do that at the right place (before xf86Msg). */ + if (xorgWayland) { + xf86Info.autoAddDevices = FALSE; + xf86Info.autoEnableDevices = FALSE; + } + /* * Set things up based on the config file information. Some of these * settings may be overridden later when the command line options are @@ -949,9 +978,10 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) } #endif - /* if we're not hotplugging, force some input devices to exist */ - xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && - xf86Info.autoEnableDevices); + if (xorgWayland) /* Don't force input devices */ + xf86Info.forceInputDevices = FALSE; + else /* if we're not hotplugging, force some input devices to exist */ + xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices); /* when forcing input devices, we use kbd. otherwise evdev, so use the * evdev rules set. */ diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index 7df7a80c4..b41d2cc86 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -204,3 +204,5 @@ Bool xf86VidModeAllowNonLocal = FALSE; #endif RootWinPropPtr *xf86RegisteredPropertiesTable = NULL; Bool xorgHWAccess = FALSE; +Bool xorgWayland = FALSE; +Bool xorgRootless = FALSE; diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index ff4d38f28..919d35f0a 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -550,6 +550,25 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) /* Non-seat0 X servers should not open console */ if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0()) xorgHWOpenConsole = TRUE; + + if (xorgWayland) { + if (flags != HW_WAYLAND) { + xf86DeleteDriver(i); + continue; + } + + want_hw_access = FALSE; + xorgHWOpenConsole = FALSE; + } + } + + for (i = 0; i < xf86NumDrivers; i++) { + if (xf86DriverList[i] == NULL) { + for (j = i; j < xf86NumDrivers; j++) { + xf86DriverList[j] = xf86DriverList[j + 1]; + } + xf86NumDrivers--; + } } if (xorgHWOpenConsole) @@ -963,6 +982,9 @@ InitInput(int argc, char **argv) mieqInit(); + if (xorgWayland) + return; + /* Initialize all configured input devices */ for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) { (*pInfo)->options = @@ -1463,6 +1485,16 @@ ddxProcessArgument(int argc, char **argv, int i) return 1; } + if (!strcmp(argv[i], "-wayland")) { + xorgWayland = TRUE; + return 1; + } + + if (!strcmp(argv[i], "-rootless")) { + xorgRootless = TRUE; + return 1; + } + /* OS-specific processing */ return xf86ProcessArgument(argc, argv, i); } diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 6e374eb7e..f84376575 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -91,6 +91,8 @@ extern _X_EXPORT int xf86NumScreens; extern _X_EXPORT const char *xf86VisualNames[]; extern _X_EXPORT int xf86Verbose; /* verbosity level */ extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */ +extern _X_EXPORT Bool xorgWayland; +extern _X_EXPORT Bool xorgRootless; extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable; diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index b164b7f21..676f9d89b 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -288,6 +288,7 @@ typedef struct { #define HW_MMIO 2 #define HW_SKIP_CONSOLE 4 #define NEED_IO_ENABLED(x) (x & HW_IO) +#define HW_WAYLAND 8 typedef CARD32 xorgHWFlags; diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index c70f72ee8..3d4013809 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -1332,13 +1332,16 @@ DRI2Connect(ClientPtr client, ScreenPtr pScreen, } static int -DRI2AuthMagic (ScreenPtr pScreen, uint32_t magic) +DRI2AuthMagic (ClientPtr client, ScreenPtr pScreen, uint32_t magic) { DRI2ScreenPtr ds = DRI2GetScreen(pScreen); if (ds == NULL) return -EINVAL; - return (*ds->LegacyAuthMagic) (ds->fd, magic); + if (ds->LegacyAuthMagic2) + return (*ds->LegacyAuthMagic2) (pScreen, magic); + else + return (*ds->LegacyAuthMagic) (ds->fd, magic); } Bool diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 38b4f588d..ed67d0148 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -207,7 +207,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client, /** * Version of the DRI2InfoRec structure defined in this header */ -#define DRI2INFOREC_VERSION 9 +#define DRI2INFOREC_VERSION 10 typedef struct { unsigned int version; /**< Version of this struct */ diff --git a/hw/xfree86/xwayland/.gitignore b/hw/xfree86/xwayland/.gitignore new file mode 100644 index 000000000..abedfee1b --- /dev/null +++ b/hw/xfree86/xwayland/.gitignore @@ -0,0 +1,4 @@ +drm-client-protocol.h +drm-protocol.c +xserver-client-protocol.h +xserver-protocol.c diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am new file mode 100644 index 000000000..22ab154af --- /dev/null +++ b/hw/xfree86/xwayland/Makefile.am @@ -0,0 +1,46 @@ +AM_CPPFLAGS = \ + $(XORG_INCS) \ + -I$(srcdir)/../ddc \ + -I$(srcdir)/../ramdac \ + -I$(srcdir)/../i2c \ + -I$(srcdir)/../parser \ + -I$(srcdir)/../modes + +libxwayland_la_LTLIBRARIES = libxwayland.la +AM_CFLAGS = \ + -DHAVE_XORG_CONFIG_H \ + @DIX_CFLAGS@ @XORG_CFLAGS@ @XWAYLAND_CFLAGS@ \ + -I$(top_srcdir)/hw/xfree86/common \ + -I$(top_srcdir)/hw/xfree86/os-support/bus + +libxwayland_la_LDFLAGS = -module -avoid-version @XWAYLAND_LIBS@ +libxwayland_ladir = $(moduledir)/extensions +libxwayland_la_SOURCES = \ + xwayland.c \ + xwayland-input.c \ + xwayland-output.c \ + xwayland-cursor.c \ + xwayland-window.c \ + xwayland-private.h \ + drm-client-protocol.h \ + drm-protocol.c \ + xserver-client-protocol.h \ + xserver-protocol.c + +if DRM +AM_CFLAGS += @LIBDRM_CFLAGS@ +libxwayland_la_LDFLAGS += @LIBDRM_LIBS@ +libxwayland_la_SOURCES += xwayland-drm.c +endif + +sdk_HEADERS = xwayland.h + +BUILT_SOURCES = \ + drm-client-protocol.h \ + drm-protocol.c \ + xserver-client-protocol.h \ + xserver-protocol.c + +CLEANFILES = $(BUILT_SOURCES) + +@wayland_scanner_rules@ diff --git a/hw/xfree86/xwayland/drm.xml b/hw/xfree86/xwayland/drm.xml new file mode 100644 index 000000000..89fd8f088 --- /dev/null +++ b/hw/xfree86/xwayland/drm.xml @@ -0,0 +1,139 @@ + + + + + Copyright © 2008-2011 Kristian Høgsberg + Copyright © 2010-2011 Intel Corporation + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that\n the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hw/xfree86/xwayland/xserver.xml b/hw/xfree86/xwayland/xserver.xml new file mode 100644 index 000000000..9e25f5c0d --- /dev/null +++ b/hw/xfree86/xwayland/xserver.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c new file mode 100644 index 000000000..2b3cb5e63 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-cursor.c @@ -0,0 +1,250 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static void +expand_source_and_mask(CursorPtr cursor, void *data) +{ + CARD32 *argb, *p, d, fg, bg; + CursorBitsPtr bits = cursor->bits; + int size; + int x, y, stride, i, bit; + + size = bits->width * bits->height * 4; + argb = malloc(size); + if (argb == NULL) + return; + + p = argb; + fg = ((cursor->foreRed & 0xff00) << 8) | + (cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8); + bg = ((cursor->backRed & 0xff00) << 8) | + (cursor->backGreen & 0xff00) | (cursor->backGreen >> 8); + stride = (bits->width / 8 + 3) & ~3; + for (y = 0; y < bits->height; y++) + for (x = 0; x < bits->width; x++) { + i = y * stride + x / 8; + bit = 1 << (x & 7); + if (bits->source[i] & bit) + d = fg; + else + d = bg; + if (bits->mask[i] & bit) + d |= 0xff000000; + else + d = 0x00000000; + + *p++ = d; + } + + memcpy(data, argb, size); + free(argb); +} + +static Bool +xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) +{ + struct xwl_screen *xwl_screen; + int size; + char filename[] = "/tmp/wayland-shm-XXXXXX"; + int fd; + struct wl_shm_pool *pool; + struct wl_buffer *buffer; + void *data; + + xwl_screen = xwl_screen_get(screen); + size = cursor->bits->width * cursor->bits->height * 4; + + fd = mkstemp(filename); + if (fd < 0) { + ErrorF("open %s failed: %s", filename, strerror(errno)); + return FALSE; + } + if (ftruncate(fd, size) < 0) { + ErrorF("ftruncate failed: %s", strerror(errno)); + close(fd); + return FALSE; + } + + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + unlink(filename); + + if (data == MAP_FAILED) { + ErrorF("mmap failed: %s", strerror(errno)); + close(fd); + return FALSE; + } + + if (cursor->bits->argb) + memcpy(data, cursor->bits->argb, size); + else + expand_source_and_mask(cursor, data); + munmap(data, size); + + pool = wl_shm_create_pool(xwl_screen->shm, fd, size); + close(fd); + buffer = wl_shm_pool_create_buffer(pool, 0, + cursor->bits->width, cursor->bits->height, + cursor->bits->width * 4, + WL_SHM_FORMAT_ARGB8888); + wl_shm_pool_destroy(pool); + + dixSetPrivate(&cursor->devPrivates, + &xwl_screen->cursor_private_key, buffer); + + return TRUE; +} + +static Bool +xwl_unrealize_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor) +{ + struct wl_buffer *buffer; + struct xwl_screen *xwl_screen; + + xwl_screen = xwl_screen_get(screen); + buffer = dixGetPrivate(&cursor->devPrivates, + &xwl_screen->cursor_private_key); + wl_buffer_destroy(buffer); + + return TRUE; +} + +void +xwl_seat_set_cursor(struct xwl_seat *xwl_seat) +{ + struct wl_buffer *buffer; + + if (!xwl_seat->wl_pointer) + return; + + if (!xwl_seat->x_cursor) { + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, + NULL, 0, 0); + return; + } + + buffer = dixGetPrivate(&xwl_seat->x_cursor->devPrivates, + &xwl_seat->xwl_screen->cursor_private_key); + + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, + xwl_seat->cursor, + xwl_seat->x_cursor->bits->xhot, + xwl_seat->x_cursor->bits->yhot); + wl_surface_attach(xwl_seat->cursor, buffer, 0, 0); + wl_surface_damage(xwl_seat->cursor, 0, 0, + xwl_seat->x_cursor->bits->width, + xwl_seat->x_cursor->bits->height); + wl_surface_commit(xwl_seat->cursor); +} + +static void +xwl_set_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor, int x, int y) +{ + struct xwl_screen *xwl_screen; + struct xwl_seat *xwl_seat; + + xwl_screen = xwl_screen_get(screen); + + if (!xwl_screen || xorg_list_is_empty(&xwl_screen->seat_list)) + return; + + xwl_seat = xorg_list_first_entry(&xwl_screen->seat_list, + struct xwl_seat, link); + + xwl_seat->x_cursor = cursor; + xwl_seat_set_cursor(xwl_seat); +} + +static void +xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y) +{ +} + +static Bool +xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen) +{ + struct xwl_screen *xwl_screen; + + xwl_screen = xwl_screen_get(screen); + + return xwl_screen->sprite_funcs->DeviceCursorInitialize(device, + screen); +} + +static void +xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen) +{ + struct xwl_screen *xwl_screen; + + xwl_screen = xwl_screen_get(screen); + + xwl_screen->sprite_funcs->DeviceCursorCleanup(device, screen); +} + +static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = +{ + xwl_realize_cursor, + xwl_unrealize_cursor, + xwl_set_cursor, + xwl_move_cursor, + xwl_device_cursor_initialize, + xwl_device_cursor_cleanup +}; + +int +xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen) +{ + miPointerScreenPtr pointer_priv; + + if (!dixRegisterPrivateKey(&xwl_screen->cursor_private_key, + PRIVATE_CURSOR, 0)) + return BadAlloc; + + pointer_priv = dixLookupPrivate(&screen->devPrivates, miPointerScreenKey); + xwl_screen->sprite_funcs = pointer_priv->spriteFuncs; + pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs; + + return Success; +} diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c new file mode 100644 index 000000000..52508575f --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-drm.c @@ -0,0 +1,250 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "../dri2/dri2.h" + +struct xwl_auth_req { + struct xorg_list link; + + ClientPtr client; + struct xwl_screen *xwl_screen; + uint32_t magic; +}; + +static void +drm_handle_device (void *data, struct wl_drm *drm, const char *device) +{ + struct xwl_screen *xwl_screen = data; + + xwl_screen->device_name = strdup (device); +} + +static void +drm_handle_format(void *data, struct wl_drm *wl_drm, uint32_t format) +{ +} + +static void +drm_handle_authenticated (void *data, struct wl_drm *drm) +{ + struct xwl_screen *xwl_screen = data; + struct xwl_auth_req *req; + + xwl_screen->authenticated = 1; + + /* it does one authentication transaction at a time, so if there's an + * element in the list, we call DRI2SendAuthReply for that client, remove + * the head and free the struct. If there are still elements in the list, + * it means that we have one or more clients waiting to be authenticated + * and we send out a wl_drm authenticate request for the first client in + * the list */ + if (xorg_list_is_empty(&xwl_screen->authenticate_client_list)) + return; + + req = xorg_list_first_entry(&xwl_screen->authenticate_client_list, + struct xwl_auth_req, link); + DRI2SendAuthReply(req->client, TRUE); + AttendClient(req->client); + xorg_list_del(&req->link); + free(req); + + xorg_list_for_each_entry(req, &xwl_screen->authenticate_client_list, + link) { + wl_drm_authenticate (xwl_screen->drm, req->magic); + return; + } +} + +static const struct wl_drm_listener xwl_drm_listener = +{ + drm_handle_device, + drm_handle_format, + drm_handle_authenticated +}; + +static void +drm_handler(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + struct xwl_screen *xwl_screen = data; + + if (strcmp (interface, "wl_drm") == 0) { + xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id, + &wl_drm_interface, 1); + wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen); + } +} + +static void +global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ + /* Nothing to do here, wl_drm should not be removed */ +} + +static const struct wl_registry_listener drm_listener = { + drm_handler, + global_remove +}; + +int +xwl_drm_pre_init(struct xwl_screen *xwl_screen) +{ + uint32_t magic; + + xwl_screen->drm_registry = wl_display_get_registry(xwl_screen->display); + wl_registry_add_listener(xwl_screen->drm_registry, &drm_listener, + xwl_screen); + + /* Ensure drm_handler has seen all the interfaces */ + wl_display_roundtrip(xwl_screen->display); + /* Ensure the xwl_drm_listener has seen the drm device, if any */ + wl_display_roundtrip(xwl_screen->display); + + ErrorF("wayland_drm_screen_init, device name %s\n", + xwl_screen->device_name); + + xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR); + if (xwl_screen->drm_fd < 0) { + ErrorF("failed to open the drm fd\n"); + return BadAccess; + } + + if (drmGetMagic(xwl_screen->drm_fd, &magic)) { + ErrorF("failed to get drm magic"); + return BadAccess; + } + + wl_drm_authenticate(xwl_screen->drm, magic); + + wl_display_roundtrip(xwl_screen->display); + + ErrorF("opened drm fd: %d\n", xwl_screen->drm_fd); + + if (!xwl_screen->authenticated) { + ErrorF("Failed to auth drm fd\n"); + return BadAccess; + } + + return Success; +} + +Bool xwl_drm_initialised(struct xwl_screen *xwl_screen) +{ + return xwl_screen->authenticated; +} + +int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen) +{ + return xwl_screen->drm_fd; +} + +int xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen, + uint32_t magic) +{ + struct xwl_auth_req *req; + + if (!xwl_screen->drm) + return BadAccess; + + req = malloc (sizeof *req); + if (req == NULL) + return BadAlloc; + + req->client = client; + req->xwl_screen = xwl_screen; + req->magic = magic; + + if (xorg_list_is_empty(&xwl_screen->authenticate_client_list)) + wl_drm_authenticate (xwl_screen->drm, magic); + + xorg_list_append(&req->link, &xwl_screen->authenticate_client_list); + + IgnoreClient(req->client); + xwl_screen->authenticated = 0; + + return Success; +} + + +int +xwl_create_window_buffer_drm(struct xwl_window *xwl_window, + PixmapPtr pixmap, uint32_t name) +{ + VisualID visual; + WindowPtr window = xwl_window->window; + ScreenPtr screen = window->drawable.pScreen; + uint32_t format; + int i; + + visual = wVisual(window); + for (i = 0; i < screen->numVisuals; i++) + if (screen->visuals[i].vid == visual) + break; + + switch (screen->visuals[i].nplanes) { + case 32: + format = WL_DRM_FORMAT_ARGB8888; + break; + case 24: + default: + format = WL_DRM_FORMAT_XRGB8888; + break; + case 16: + format = WL_DRM_FORMAT_RGB565; + break; + } + + xwl_window->buffer = + wl_drm_create_buffer(xwl_window->xwl_screen->drm, + name, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->devKind, + format); + + return xwl_window->buffer ? Success : BadDrawable; +} diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c new file mode 100644 index 000000000..9adc6159b --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-input.c @@ -0,0 +1,647 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static void +xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl) +{ + /* Nothing to do, dix handles all settings */ +} + +static int +xwl_pointer_proc(DeviceIntPtr device, int what) +{ +#define NBUTTONS 10 +#define NAXES 2 + BYTE map[NBUTTONS + 1]; + int i = 0; + Atom btn_labels[NBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + + for (i = 1; i <= NBUTTONS; i++) + map[i] = i; + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + /* don't know about the rest */ + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); + + if (!InitValuatorClassDeviceStruct(device, 2, btn_labels, + GetMotionHistorySize(), Absolute)) + return BadValue; + + /* Valuators */ + InitValuatorAxisStruct(device, 0, axes_labels[0], + 0, 0xFFFF, 10000, 0, 10000, Absolute); + InitValuatorAxisStruct(device, 1, axes_labels[1], + 0, 0xFFFF, 10000, 0, 10000, Absolute); + + if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control)) + return BadValue; + + if (!InitButtonClassDeviceStruct(device, 3, btn_labels, map)) + return BadValue; + + return Success; + + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + } + + return BadMatch; + +#undef NBUTTONS +#undef NAXES +} + +static void +xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl) +{ + /* FIXME: Set keyboard leds based on CAPSFLAG etc being set in + * ctrl->leds - needs private protocol. */ +} + +static int +xwl_keyboard_proc(DeviceIntPtr device, int what) +{ + struct xwl_seat *xwl_seat = device->public.devicePrivate; + int len; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + if (xwl_seat->keymap) + len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size); + else + len = 0; + if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap, + len, + NULL, xwl_keyboard_control)) + return BadValue; + + return Success; + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + } + + return BadMatch; +} + +static DeviceIntPtr +device_added(struct xwl_seat *xwl_seat, const char *driver) +{ + DeviceIntPtr dev = NULL; + Atom type_atom; + char *name; + int rc; + Bool (*device_control) (DeviceIntPtr device, int what); + + if (strcmp(driver, "xwayland-keyboard") == 0) { + name = xwl_seat->keyboard_name; + device_control = xwl_keyboard_proc; + } else { + name = xwl_seat->pointer_name; + device_control = xwl_pointer_proc; + } + + snprintf(name, sizeof xwl_seat->keyboard_name, + "%s:%d", driver, xwl_seat->id); + + dev = AddInputDevice(serverClient, device_control, TRUE); + if (dev == NULL) + return NULL; + + type_atom = MakeAtom(driver, strlen(driver), TRUE); + AssignTypeAndName(dev, type_atom, name); + dev->public.devicePrivate = xwl_seat; + dev->type = SLAVE; + dev->spriteInfo->spriteOwner = FALSE; + + rc = ActivateDevice(dev, TRUE); + if (rc != Success) { + RemoveDevice(dev, TRUE); + xf86Msg(X_ERROR, "xwayland: Couldn't init device \"%s\"\n", name); + return NULL; + } + + EnableDevice(dev, TRUE); + if (!dev->enabled) { + RemoveDevice(dev, TRUE); + xf86Msg(X_ERROR, "xwayland: Couldn't enable device \"%s\"\n", name); + return NULL; + } + + LogMessage(X_INFO, "xwayland: Adding input device %s\n", name); + + return dev; +} + +static void +pointer_handle_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx_w, wl_fixed_t sy_w) + +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr dev = xwl_seat->pointer; + int i; + int sx = wl_fixed_to_int(sx_w); + int sy = wl_fixed_to_int(sy_w); + ScreenPtr pScreen = xwl_seat->xwl_screen->screen; + ValuatorMask mask; + + xwl_seat->xwl_screen->serial = serial; + xwl_seat->pointer_enter_serial = serial; + + xwl_seat->focus_window = wl_surface_get_user_data(surface); + + (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE); + + SetDeviceRedirectWindow(xwl_seat->pointer, xwl_seat->focus_window->window); + + /* Ideally, X clients shouldn't see these button releases. When + * the pointer leaves a window with buttons down, it means that + * the wayland compositor has grabbed the pointer. The button + * release event is consumed by whatever grab in the compositor + * and won't be sent to clients (the X server is a client). + * However, we need to reset X's idea of which buttons are up and + * down, and they're all up (by definition) when the pointer + * enters a window. We should figure out a way to swallow these + * events, perhaps using an X grab whenever the pointer is not in + * any X window, but for now just send the events. */ + valuator_mask_zero(&mask); + for (i = 0; i < dev->button->numButtons; i++) + if (BitIsOn(dev->button->down, i)) + QueuePointerEvents(xwl_seat->pointer, ButtonRelease, i, 0, &mask); + + (*pScreen->DisplayCursor)(dev, pScreen, dev->spriteInfo->sprite->current); +} + +static void +pointer_handle_leave(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr dev = xwl_seat->pointer; + ScreenPtr pScreen = xwl_seat->xwl_screen->screen; + + xwl_seat->xwl_screen->serial = serial; + + xwl_seat->focus_window = NULL; + SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin); + (*pScreen->DisplayCursor)(dev, pScreen, NullCursor); +} + +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 xwl_seat *xwl_seat = data; + int32_t dx, dy; + int sx = wl_fixed_to_int(sx_w); + int sy = wl_fixed_to_int(sy_w); + ValuatorMask mask; + + if (!xwl_seat->focus_window) + return ; + + dx = xwl_seat->focus_window->window->drawable.x; + dy = xwl_seat->focus_window->window->drawable.y; + + valuator_mask_zero(&mask); + valuator_mask_set(&mask, 0, dx + sx); + valuator_mask_set(&mask, 1, dy + sy); + + QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); +} + +static void +pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state) +{ + struct xwl_seat *xwl_seat = data; + int index; + ValuatorMask mask; + + xwl_seat->xwl_screen->serial = serial; + + switch (button) { + case BTN_MIDDLE: + index = 2; + break; + case BTN_RIGHT: + index = 3; + break; + default: + index = button - BTN_LEFT + 1; + break; + } + + valuator_mask_zero(&mask); + QueuePointerEvents(xwl_seat->pointer, + state ? ButtonPress : ButtonRelease, index, 0, &mask); +} + +static void +pointer_handle_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ + struct xwl_seat *xwl_seat = data; + int index, count; + int i, val; + const int divisor = 10; + ValuatorMask mask; + + if (time - xwl_seat->scroll_time > 2000) { + xwl_seat->vertical_scroll = 0; + xwl_seat->horizontal_scroll = 0; + } + xwl_seat->scroll_time = time; + + /* FIXME: Need to do proper smooth scrolling here! */ + switch (axis) { + case WL_POINTER_AXIS_VERTICAL_SCROLL: + xwl_seat->vertical_scroll += value / divisor; + val = wl_fixed_to_int(xwl_seat->vertical_scroll); + xwl_seat->vertical_scroll -= wl_fixed_from_int(val); + + if (val <= -1) + index = 4; + else if (val >= 1) + index = 5; + else + return; + break; + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + xwl_seat->horizontal_scroll += value / divisor; + val = wl_fixed_to_int(xwl_seat->horizontal_scroll); + xwl_seat->horizontal_scroll -= wl_fixed_from_int(val); + + if (val <= -1) + index = 6; + else if (val >= 1) + index = 7; + else + return; + break; + default: + return; + } + + valuator_mask_zero(&mask); + + count = abs(val); + for (i = 0; i < count; i++) { + QueuePointerEvents(xwl_seat->pointer, ButtonPress, index, 0, &mask); + QueuePointerEvents(xwl_seat->pointer, ButtonRelease, index, 0, &mask); + } +} + +static const struct wl_pointer_listener pointer_listener = { + pointer_handle_enter, + pointer_handle_leave, + pointer_handle_motion, + pointer_handle_button, + pointer_handle_axis, +}; + +static void +keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, + uint32_t time, uint32_t key, uint32_t state) +{ + struct xwl_seat *xwl_seat = data; + uint32_t *k, *end; + ValuatorMask mask; + + xwl_seat->xwl_screen->serial = serial; + + end = (uint32_t *) ((char *) xwl_seat->keys.data + xwl_seat->keys.size); + for (k = xwl_seat->keys.data; k < end; k++) { + if (*k == key) + *k = *--end; + } + xwl_seat->keys.size = (char *) end - (char *) xwl_seat->keys.data; + if (state) { + k = wl_array_add(&xwl_seat->keys, sizeof *k); + *k = key; + } + + valuator_mask_zero(&mask); + QueueKeyboardEvents(xwl_seat->keyboard, + state ? KeyPress : KeyRelease, key + 8, &mask); +} + +static void +keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, + uint32_t format, int fd, uint32_t size) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr master; + XkbDescPtr xkb; + XkbChangesRec changes = { 0 }; + + if (xwl_seat->keymap) + munmap(xwl_seat->keymap, xwl_seat->keymap_size); + + xwl_seat->keymap_size = size; + xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (xwl_seat->keymap == MAP_FAILED) { + xwl_seat->keymap_size = 0; + xwl_seat->keymap = NULL; + goto out; + } + + if (!xwl_seat->keyboard) + goto out; + + xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap, + strnlen(xwl_seat->keymap, xwl_seat->keymap_size)); + if (!xkb) + goto out; + + XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes); + /* Keep the current controls */ + XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc); + + XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb); + + master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD); + if (master && master->lastSlave == xwl_seat->keyboard) + XkbDeviceApplyKeymap(master, xkb); + + XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE); + + out: + close(fd); +} + +static void +keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, + uint32_t serial, + struct wl_surface *surface, struct wl_array *keys) +{ + struct xwl_seat *xwl_seat = data; + ValuatorMask mask; + uint32_t *k; + + xwl_seat->xwl_screen->serial = serial; + xwl_seat->keyboard_focus = surface; + + wl_array_copy(&xwl_seat->keys, keys); + valuator_mask_zero(&mask); + wl_array_for_each(k, &xwl_seat->keys) + QueueKeyboardEvents(xwl_seat->keyboard, KeyPress, *k + 8, &mask); +} + +static void +keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface) +{ + struct xwl_seat *xwl_seat = data; + ValuatorMask mask; + uint32_t *k; + + xwl_seat->xwl_screen->serial = serial; + + valuator_mask_zero(&mask); + wl_array_for_each(k, &xwl_seat->keys) + QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8, &mask); + + xwl_seat->keyboard_focus = NULL; +} + +static void +keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr dev; + XkbStateRec old_state, *new_state; + xkbStateNotify sn; + CARD16 changed; + + /* We don't need any of this while we have keyboard focus since + the regular key event processing already takes care of setting + our internal state correctly. */ + if (xwl_seat->keyboard_focus) + return; + + for (dev = inputInfo.devices; dev; dev = dev->next) { + if (dev != xwl_seat->keyboard && dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD)) + continue; + + old_state = dev->key->xkbInfo->state; + new_state = &dev->key->xkbInfo->state; + + new_state->locked_group = group & XkbAllGroupsMask; + new_state->locked_mods = mods_locked & XkbAllModifiersMask; + XkbLatchModifiers(dev, XkbAllModifiersMask, mods_latched & XkbAllModifiersMask); + + XkbComputeDerivedState(dev->key->xkbInfo); + + changed = XkbStateChangedFlags(&old_state, new_state); + if (!changed) + continue; + + sn.keycode = 0; + sn.eventType = 0; + sn.requestMajor = XkbReqCode; + sn.requestMinor = X_kbLatchLockState; /* close enough */ + sn.changed = changed; + XkbSendStateNotify(dev, &sn); + } +} + +static const struct wl_keyboard_listener keyboard_listener = { + keyboard_handle_keymap, + keyboard_handle_enter, + keyboard_handle_leave, + keyboard_handle_key, + keyboard_handle_modifiers, +}; + +static void +add_devices(void *data, struct wl_callback *callback, uint32_t time) +{ + struct xwl_seat *xwl_seat = data; + + wl_callback_destroy(callback); + + if (xwl_seat->wl_pointer) + xwl_seat->pointer = device_added(xwl_seat, "xwayland-pointer"); + if (xwl_seat->wl_keyboard) + xwl_seat->keyboard = device_added(xwl_seat, "xwayland-keyboard"); +} + +static const struct wl_callback_listener add_devices_listener = { + add_devices +}; + +static void +seat_handle_capabilities(void *data, struct wl_seat *seat, + enum wl_seat_capability caps) +{ + struct xwl_seat *xwl_seat = data; + struct wl_callback *callback; + + if (caps & WL_SEAT_CAPABILITY_POINTER) { + xwl_seat->wl_pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(xwl_seat->wl_pointer, + &pointer_listener, xwl_seat); + xwl_seat_set_cursor(xwl_seat); + } + + if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { + xwl_seat->wl_keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(xwl_seat->wl_keyboard, + &keyboard_listener, xwl_seat); + + } + /* FIXME: Touch ... */ + + /* Add devices after we've received keymaps. */ + if (caps) { + callback = wl_display_sync(xwl_seat->xwl_screen->display); + wl_callback_add_listener(callback, + &add_devices_listener, xwl_seat); + } +} + +static const struct wl_seat_listener seat_listener = { + seat_handle_capabilities, +}; + +static void +create_input_device(struct xwl_screen *xwl_screen, uint32_t id) +{ + struct xwl_seat *xwl_seat; + + xwl_seat = calloc(sizeof *xwl_seat, 1); + if (xwl_seat == NULL) { + ErrorF("create_input ENOMEM"); + return ; + } + + xwl_seat->xwl_screen = xwl_screen; + xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list); + + xwl_seat->seat = + wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1); + xwl_seat->id = id; + + xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor); + wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat); + wl_array_init(&xwl_seat->keys); +} + +static void +input_handler(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + struct xwl_screen *xwl_screen = data; + + if (strcmp (interface, "wl_seat") == 0) { + create_input_device(xwl_screen, id); + } else if (strcmp(interface, "xserver") == 0) { + xwl_screen->xorg_server = + wl_registry_bind(registry, id, &xserver_interface, 1); + xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener, + xwl_screen); + } +} + +static void +global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ + /* FIXME */ +} + +static const struct wl_registry_listener input_listener = { + input_handler, + global_remove, +}; + +void +xwl_input_init(struct xwl_screen *xwl_screen) +{ + xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display); + wl_registry_add_listener(xwl_screen->input_registry, &input_listener, + xwl_screen); +} diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c new file mode 100644 index 000000000..a45e21311 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-output.c @@ -0,0 +1,438 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static void +crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) +{ +} + +static Bool +crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + return TRUE; +} + +static void +crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) +{ +} + +static void +crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +{ +} + +static void +crtc_show_cursor (xf86CrtcPtr crtc) +{ +} + +static void +crtc_hide_cursor (xf86CrtcPtr crtc) +{ +} + +static void +crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) +{ +} + +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + return NULL; +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + return NULL; +} + +static void +crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + /* Nothing to do here, we only destroy CRTCs when instructed to do + so by wl_output changes + */ +} + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .set_mode_major = crtc_set_mode_major, + .set_cursor_colors = crtc_set_cursor_colors, + .set_cursor_position = crtc_set_cursor_position, + .show_cursor = crtc_show_cursor, + .hide_cursor = crtc_hide_cursor, + .load_cursor_argb = crtc_load_cursor_argb, + .shadow_create = crtc_shadow_create, + .shadow_allocate = crtc_shadow_allocate, + .shadow_destroy = crtc_shadow_destroy, + .destroy = crtc_destroy, +}; + +static void +output_dpms(xf86OutputPtr output, int mode) +{ + return; +} + +static xf86OutputStatus +output_detect(xf86OutputPtr output) +{ + return XF86OutputStatusConnected; +} + +static Bool +output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) +{ + return MODE_OK; +} + +static DisplayModePtr +output_get_modes(xf86OutputPtr xf86output) +{ + struct xwl_output *output = xf86output->driver_private; + struct monitor_ranges *ranges; + DisplayModePtr modes; + + modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE); + output->xf86monitor.det_mon[0].type = DS_RANGES; + ranges = &output->xf86monitor.det_mon[0].section.ranges; + ranges->min_h = modes->HSync - 10; + ranges->max_h = modes->HSync + 10; + ranges->min_v = modes->VRefresh - 10; + ranges->max_v = modes->VRefresh + 10; + ranges->max_clock = modes->Clock + 100; + output->xf86monitor.det_mon[1].type = DT; + output->xf86monitor.det_mon[2].type = DT; + output->xf86monitor.det_mon[3].type = DT; + output->xf86monitor.no_sections = 0; + + xf86output->MonInfo = &output->xf86monitor; + + return modes; +} + +static void +output_destroy(xf86OutputPtr xf86output) +{ + struct xwl_output *output = xf86output->driver_private; + + free(output); +} + +static const xf86OutputFuncsRec output_funcs = { + .dpms = output_dpms, + .detect = output_detect, + .mode_valid = output_mode_valid, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +struct xwl_output * +xwl_output_create(struct xwl_screen *xwl_screen) +{ + struct xwl_output *xwl_output; + xf86OutputPtr xf86output; + xf86CrtcPtr xf86crtc; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(xwl_screen->scrninfo); + int crtcId, outputId; + static int nameId; + char *name; + + xwl_output = calloc(sizeof *xwl_output, 1); + if (xwl_output == NULL) { + ErrorF("create_output ENOMEM"); + return NULL; + } + + nameId++; + if (asprintf(&name, "XWAYLAND-%d", nameId) < 0) { + ErrorF("create_output ENOMEM"); + free(xwl_output); + return NULL; + } + + xwl_output->xwl_screen = xwl_screen; + + xf86crtc = xf86CrtcCreate(xwl_screen->scrninfo, &crtc_funcs); + xf86crtc->enabled = TRUE; + xf86crtc->driver_private = xwl_output; + + for (crtcId = 0; crtcId < xf86_config->num_crtc; crtcId++) { + if (xf86_config->crtc[crtcId] == xf86crtc) + break; + } + + xf86output = xf86OutputCreate(xwl_screen->scrninfo, + &output_funcs, name); + xf86output->driver_private = xwl_output; + xf86output->possible_crtcs = 1 << crtcId; + + for (outputId = 0; outputId < xf86_config->num_output; outputId++) { + if (xf86_config->output[outputId] == xf86output) + break; + } + + xf86output->possible_clones = 1 << outputId; + + xwl_output->xf86output = xf86output; + xwl_output->xf86crtc = xf86crtc; + xwl_output->xf86output->crtc = xf86crtc; + + free(name); + + return xwl_output; +} + +static Bool +resize(ScrnInfoPtr scrn, int width, int height) +{ + if (scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + /* We don't handle resize at all, we must match the compositor size */ + return FALSE; +} + +static const xf86CrtcConfigFuncsRec config_funcs = { + resize +}; + +static Rotation +wl_transform_to_xrandr (enum wl_output_transform transform) +{ + switch (transform) + { + case WL_OUTPUT_TRANSFORM_NORMAL: + return RR_Rotate_0; + case WL_OUTPUT_TRANSFORM_90: + return RR_Rotate_90; + case WL_OUTPUT_TRANSFORM_180: + return RR_Rotate_180; + case WL_OUTPUT_TRANSFORM_270: + return RR_Rotate_270; + case WL_OUTPUT_TRANSFORM_FLIPPED: + return RR_Reflect_X | RR_Rotate_0; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + return RR_Reflect_X | RR_Rotate_90; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + return RR_Reflect_X | RR_Rotate_180; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + return RR_Reflect_X | RR_Rotate_270; + } + + return RR_Rotate_0; +} + +static void +display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, + int physical_width, int physical_height, int subpixel, + const char *make, const char *model, int transform) +{ + struct xwl_output *xwl_output = data; + struct xwl_screen *xwl_screen = xwl_output->xwl_screen; + + xwl_output->xf86output->mm_width = physical_width; + xwl_output->xf86output->mm_height = physical_height; + + switch (subpixel) { + case WL_OUTPUT_SUBPIXEL_UNKNOWN: + xwl_output->xf86output->subpixel_order = SubPixelUnknown; + break; + case WL_OUTPUT_SUBPIXEL_NONE: + xwl_output->xf86output->subpixel_order = SubPixelNone; + break; + case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB: + xwl_output->xf86output->subpixel_order = SubPixelHorizontalRGB; + break; + case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR: + xwl_output->xf86output->subpixel_order = SubPixelHorizontalBGR; + break; + case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB: + xwl_output->xf86output->subpixel_order = SubPixelVerticalRGB; + break; + case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR: + xwl_output->xf86output->subpixel_order = SubPixelVerticalBGR; + break; + } + + xwl_output->x = x; + xwl_output->y = y; + xwl_output->rotation = wl_transform_to_xrandr (transform); + + xorg_list_append (&xwl_output->link, &xwl_screen->output_list); +} + +static void +display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, + int width, int height, int refresh) +{ + struct xwl_output *xwl_output = data; + struct xwl_screen *xwl_screen = xwl_output->xwl_screen; + ScreenPtr pScreen = xwl_screen->screen; + ScrnInfoPtr scrn = xwl_screen->scrninfo; + CARD16 width_mm, height_mm; + DisplayModePtr mode; + rrScrPrivPtr rp; + + if (!(flags & WL_OUTPUT_MODE_CURRENT)) + return; + + xwl_output->width = width; + xwl_output->height = height; + + if (xwl_output->x + xwl_output->width > scrn->virtualX || + xwl_output->y + xwl_output->height > scrn->virtualY) { + /* Fake a RandR request to resize the screen. It will bounce + back to our crtc_resize, which does nothing. + */ + /* Preupdate virtualX / virtualY, so that crtc_resize returns TRUE */ + scrn->virtualX = xwl_output->x + xwl_output->width; + scrn->virtualY = xwl_output->y + xwl_output->height; + + /* Ignore the compositor provided values for mm_width/mm_height, + as it doesn't make sense to sum the values of different outputs. + Just make the DPI 96 */ + width_mm = (scrn->virtualX / 96.0) * 25.4 + 0.5; + height_mm = (scrn->virtualY / 96.0) * 25.4 + 0.5; + + /* But! When the server starts, the RandR stuff is not initialized, + so we can't call rrGetScrPriv. We updated virtualX/Y anyway, let's + hope it's enough. + */ + if (xwl_screen->outputs_initialized) { + rp = rrGetScrPriv(pScreen); + if (rp->rrScreenSetSize) + rp->rrScreenSetSize(pScreen, scrn->virtualX, scrn->virtualY, width_mm, height_mm); + } + } + + xwl_output->xf86crtc->enabled = TRUE; + mode = xf86CVTMode(width, height, (float) refresh / 1000, TRUE, FALSE); + xf86CrtcSetModeTransform(xwl_output->xf86crtc, mode, xwl_output->rotation, + NULL, xwl_output->x, xwl_output->y); +} + +static const struct wl_output_listener output_listener = { + display_handle_geometry, + display_handle_mode +}; + +static void +global_handler(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + struct xwl_screen *xwl_screen = data; + struct xwl_output *xwl_output; + + if (strcmp (interface, "wl_output") == 0) { + xwl_output = xwl_output_create(xwl_screen); + xwl_output->output = wl_registry_bind(registry, id, + &wl_output_interface, 1); + xwl_output->name = id; + wl_output_add_listener(xwl_output->output, + &output_listener, xwl_output); + } +} + +void +xwl_output_remove(struct xwl_output *xwl_output) +{ + xorg_list_del (&xwl_output->link); + xf86OutputDestroy (xwl_output->xf86output); + xf86CrtcDestroy (xwl_output->xf86crtc); + + wl_output_destroy (xwl_output->output); +} + +static void +global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ + struct xwl_screen *xwl_screen = data; + struct xwl_output *xwl_output, *tmp; + + xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) { + if (xwl_output->name == name) { + xwl_output_remove(xwl_output); + break; + } + } +} + +static const struct wl_registry_listener global_listener = { + global_handler, + global_remove +}; + +void +xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo) +{ + int ret; + + xf86CrtcConfigInit(scrninfo, &config_funcs); + + xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192); + + xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display); + wl_registry_add_listener(xwl_screen->output_registry, &global_listener, + xwl_screen); + + while (xwl_screen->output_list.next == &xwl_screen->output_list) { + ret = wl_display_roundtrip(xwl_screen->display); + if (ret == -1) + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno)); + } + + xf86ProbeOutputModes(scrninfo, 0, 0); + + xwl_screen->outputs_initialized = TRUE; + + xf86SetScrnInfoModes(scrninfo); +} diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h new file mode 100644 index 000000000..27d68d150 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-private.h @@ -0,0 +1,142 @@ +/* + * Copyright © 2010 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef _XWAYLAND_PRIVATE_H_ +#define _XWAYLAND_PRIVATE_H_ + +#include + +struct xwl_window { + struct xwl_screen *xwl_screen; + struct wl_surface *surface; + struct wl_buffer *buffer; + WindowPtr window; + DamagePtr damage; + struct xorg_list link; + struct xorg_list link_damage; +}; + +struct xwl_output; + +struct xwl_screen { + struct xwl_driver *driver; + ScreenPtr screen; + ScrnInfoPtr scrninfo; + int drm_fd; + int wayland_fd; + struct wl_display *display; + struct wl_registry *registry; + struct wl_registry *drm_registry; + struct wl_registry *input_registry; + struct wl_registry *output_registry; + struct wl_compositor *compositor; + struct wl_drm *drm; + struct wl_shm *shm; + struct xserver *xorg_server; + uint32_t mask; + uint32_t flags; + char *device_name; + uint32_t authenticated; + struct xorg_list output_list; + struct xorg_list seat_list; + struct xorg_list damage_window_list; + struct xorg_list window_list; + struct xorg_list authenticate_client_list; + uint32_t serial; + Bool outputs_initialized; + + DevPrivateKeyRec cursor_private_key; + + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + SetWindowPixmapProcPtr SetWindowPixmap; + MoveWindowProcPtr MoveWindow; + miPointerSpriteFuncPtr sprite_funcs; +}; + +struct xwl_output { + struct xorg_list link; + struct wl_output *output; + struct xwl_screen *xwl_screen; + int32_t x, y, width, height; + xf86Monitor xf86monitor; + xf86OutputPtr xf86output; + xf86CrtcPtr xf86crtc; + int32_t name; + Rotation rotation; +}; + + +#define MODIFIER_META 0x01 + +struct xwl_seat { + DeviceIntPtr pointer; + char pointer_name[32]; + DeviceIntPtr keyboard; + char keyboard_name[32]; + struct xwl_screen *xwl_screen; + struct wl_seat *seat; + struct wl_pointer *wl_pointer; + struct wl_keyboard *wl_keyboard; + struct wl_array keys; + struct wl_surface *cursor; + struct xwl_window *focus_window; + uint32_t id; + uint32_t pointer_enter_serial; + struct xorg_list link; + CursorPtr x_cursor; + + wl_fixed_t horizontal_scroll; + wl_fixed_t vertical_scroll; + uint32_t scroll_time; + + size_t keymap_size; + char *keymap; + struct wl_surface *keyboard_focus; +}; + + +struct xwl_screen *xwl_screen_get(ScreenPtr screen); + +void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo); + +int xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen); +int xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen); + +struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen); + +void xwl_input_init(struct xwl_screen *screen); + +Bool xwl_drm_initialised(struct xwl_screen *screen); + +void xwl_seat_set_cursor(struct xwl_seat *xwl_seat); + +void xwl_output_remove(struct xwl_output *output); + +extern const struct xserver_listener xwl_server_listener; + +#endif /* _XWAYLAND_PRIVATE_H_ */ diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c new file mode 100644 index 000000000..a2a820624 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-window.c @@ -0,0 +1,261 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static DevPrivateKeyRec xwl_window_private_key; + +static void +free_pixmap(void *data, struct wl_callback *callback, uint32_t time) +{ + PixmapPtr pixmap = data; + ScreenPtr screen = pixmap->drawable.pScreen; + + (*screen->DestroyPixmap)(pixmap); + wl_callback_destroy(callback); +} + +static const struct wl_callback_listener free_pixmap_listener = { + free_pixmap, +}; + +static void +xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap) +{ + struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + struct wl_callback *callback; + + /* We can safely destroy the buffer because we only use one buffer + * per surface in xwayland model */ + if (xwl_window->buffer) + wl_buffer_destroy(xwl_window->buffer); + + xwl_screen->driver->create_window_buffer(xwl_window, pixmap); + + if (!xwl_window->buffer) { + ErrorF("failed to create buffer\n"); + return; + } + + wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0); + wl_surface_damage(xwl_window->surface, 0, 0, + pixmap->drawable.width, + pixmap->drawable.height); + + callback = wl_display_sync(xwl_screen->display); + wl_callback_add_listener(callback, &free_pixmap_listener, pixmap); + pixmap->refcnt++; +} + +static void +damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) +{ + struct xwl_window *xwl_window = data; + struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + + xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list); +} + +static void +damage_destroy(DamagePtr pDamage, void *data) +{ +} + +static Bool +xwl_realize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + screen->RealizeWindow = xwl_screen->RealizeWindow; + ret = (*screen->RealizeWindow)(window); + xwl_screen->RealizeWindow = screen->RealizeWindow; + screen->RealizeWindow = xwl_realize_window; + + if (xwl_screen->flags & XWL_FLAGS_ROOTLESS) { + if (window->redirectDraw != RedirectDrawManual) + return ret; + } else { + if (window->parent) + return ret; + } + + xwl_window = calloc(sizeof *xwl_window, 1); + xwl_window->xwl_screen = xwl_screen; + xwl_window->window = window; + xwl_window->surface = + wl_compositor_create_surface(xwl_screen->compositor); + if (xwl_window->surface == NULL) { + ErrorF("wl_display_create_surface failed\n"); + return FALSE; + } + + if (xwl_screen->xorg_server) + xserver_set_window_id(xwl_screen->xorg_server, + xwl_window->surface, window->drawable.id); + + wl_surface_set_user_data(xwl_window->surface, xwl_window); + xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(window)); + + dixSetPrivate(&window->devPrivates, + &xwl_window_private_key, xwl_window); + + xwl_window->damage = + DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, + FALSE, screen, xwl_window); + DamageRegister(&window->drawable, xwl_window->damage); + DamageSetReportAfterOp(xwl_window->damage, TRUE); + + xorg_list_add(&xwl_window->link, &xwl_screen->window_list); + xorg_list_init(&xwl_window->link_damage); + + return ret; +} + +static Bool +xwl_unrealize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + struct xwl_seat *xwl_seat; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + xorg_list_for_each_entry(xwl_seat, + &xwl_screen->seat_list, link) { + if (!xwl_seat->focus_window) + continue ; + if (xwl_seat->focus_window->window == window) { + xwl_seat->focus_window = NULL; + SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin); + } + } + + screen->UnrealizeWindow = xwl_screen->UnrealizeWindow; + ret = (*screen->UnrealizeWindow)(window); + xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; + screen->UnrealizeWindow = xwl_unrealize_window; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (!xwl_window) + return ret; + + if (xwl_window->buffer) + wl_buffer_destroy(xwl_window->buffer); + wl_surface_destroy(xwl_window->surface); + xorg_list_del(&xwl_window->link); + if (RegionNotEmpty(DamageRegion(xwl_window->damage))) + xorg_list_del(&xwl_window->link_damage); + DamageUnregister(xwl_window->damage); + DamageDestroy(xwl_window->damage); + free(xwl_window); + dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); + + return ret; +} + +static void +xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + + xwl_screen = xwl_screen_get(screen); + + screen->SetWindowPixmap = xwl_screen->SetWindowPixmap; + (*screen->SetWindowPixmap)(window, pixmap); + xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = xwl_set_window_pixmap; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (xwl_window) + xwl_window_attach(xwl_window, pixmap); +} + +static void +xwl_move_window(WindowPtr window, int x, int y, + WindowPtr sibling, VTKind kind) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + + xwl_screen = xwl_screen_get(screen); + + screen->MoveWindow = xwl_screen->MoveWindow; + (*screen->MoveWindow)(window, x, y, sibling, kind); + xwl_screen->MoveWindow = screen->MoveWindow; + screen->MoveWindow = xwl_move_window; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (xwl_window == NULL) + return; +} + +int +xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen) +{ + if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) + return BadAlloc; + + xwl_screen->RealizeWindow = screen->RealizeWindow; + screen->RealizeWindow = xwl_realize_window; + + xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; + screen->UnrealizeWindow = xwl_unrealize_window; + + xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = xwl_set_window_pixmap; + + xwl_screen->MoveWindow = screen->MoveWindow; + screen->MoveWindow = xwl_move_window; + + return Success; +} diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c new file mode 100644 index 000000000..122346ced --- /dev/null +++ b/hw/xfree86/xwayland/xwayland.c @@ -0,0 +1,393 @@ +/* + * Copyright © 2008-2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +/* + * TODO: + * - lose X kb focus when wayland surface loses it + * - active grabs, grab owner crack + */ + +static DevPrivateKeyRec xwl_screen_private_key; + +static void +xserver_client(void *data, struct xserver *xserver, int fd) +{ + AddClientOnOpenFD(fd); +} + +static void +xserver_listen_socket(void *data, struct xserver *xserver, int fd) +{ + ListenOnOpenFD(fd, TRUE); +} + +const struct xserver_listener xwl_server_listener = { + xserver_client, + xserver_listen_socket +}; + +static void +xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time) +{ + struct xwl_screen *xwl_screen = data; + + ErrorF("xwl_input_delayed_init\n"); + + wl_callback_destroy(callback); + xwl_input_init(xwl_screen); +} + +static const struct wl_callback_listener delayed_init_listner = { + xwl_input_delayed_init +}; + +static void +registry_global(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + struct xwl_screen *xwl_screen = data; + + if (strcmp (interface, "wl_compositor") == 0) { + xwl_screen->compositor = + wl_registry_bind(registry, id, &wl_compositor_interface, 1); + } else if (strcmp(interface, "wl_shm") == 0) { + xwl_screen->shm = + wl_registry_bind(registry, id, &wl_shm_interface, 1); + } +} + +static void +global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ + /* Nothing to do here, wl_compositor and wl_shm should not be removed */ +} + +static const struct wl_registry_listener registry_listener = { + registry_global, + global_remove +}; + +static void +wakeup_handler(void *data, int err, void *read_mask) +{ + struct xwl_screen *xwl_screen = data; + int ret; + + if (err < 0) + return; + + if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask)) + return; + + ret = wl_display_dispatch(xwl_screen->display); + if (ret == -1) + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno)); +} + +static void +block_handler(void *data, struct timeval **tv, void *read_mask) +{ + struct xwl_screen *xwl_screen = data; + int ret; + + ret = wl_display_dispatch_pending(xwl_screen->display); + if (ret == -1) + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno)); + + ret = wl_display_flush(xwl_screen->display); + if (ret == -1) + FatalError("failed to write to XWayland fd: %s\n", strerror(errno)); +} + +int +xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen) +{ + struct wl_callback *callback; + + xwl_screen->screen = screen; + + if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0)) + return BadAlloc; + + dixSetPrivate(&screen->devPrivates, + &xwl_screen_private_key, xwl_screen); + + xwl_screen_init_window(xwl_screen, screen); + + xwl_screen_init_cursor(xwl_screen, screen); + + AddGeneralSocket(xwl_screen->wayland_fd); + RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen); + + callback = wl_display_sync(xwl_screen->display); + wl_callback_add_listener(callback, &delayed_init_listner, xwl_screen); + + return Success; +} + +struct xwl_screen * +xwl_screen_get(ScreenPtr screen) +{ + return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key); +} + +struct xwl_screen * +xwl_screen_create(void) +{ + struct xwl_screen *xwl_screen; + + xwl_screen = calloc(sizeof *xwl_screen, 1); + if (xwl_screen == NULL) { + ErrorF("calloc failed\n"); + return NULL; + } + + xwl_screen->display = wl_display_connect(NULL); + if (xwl_screen->display == NULL) { + ErrorF("wl_display_create failed\n"); + return NULL; + } + + return xwl_screen; +} + +Bool +xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen, + uint32_t flags, struct xwl_driver *driver) +{ + int ret; + + noScreenSaverExtension = TRUE; + + xorg_list_init(&xwl_screen->output_list); + xorg_list_init(&xwl_screen->seat_list); + xorg_list_init(&xwl_screen->damage_window_list); + xorg_list_init(&xwl_screen->window_list); + xorg_list_init(&xwl_screen->authenticate_client_list); + xwl_screen->scrninfo = scrninfo; + xwl_screen->driver = driver; + xwl_screen->flags = flags; + xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display); + + if (xorgRootless) + xwl_screen->flags |= XWL_FLAGS_ROOTLESS; + + /* Set up listener so we'll catch all events. */ + xwl_screen->registry = wl_display_get_registry(xwl_screen->display); + wl_registry_add_listener(xwl_screen->registry, ®istry_listener, + xwl_screen); + ret = wl_display_roundtrip(xwl_screen->display); + if (ret == -1) { + xf86DrvMsg(scrninfo->scrnIndex, X_ERROR, + "failed to dispatch Wayland events: %s\n", strerror(errno)); + return FALSE; + } + +#ifdef WITH_LIBDRM + if (xwl_screen->driver->use_drm && !xwl_drm_initialised(xwl_screen)) + if (xwl_drm_pre_init(xwl_screen) != Success) + return FALSE; +#endif + + xwayland_screen_preinit_output(xwl_screen, scrninfo); + + return TRUE; +} + +int +xwl_create_window_buffer_shm(struct xwl_window *xwl_window, + PixmapPtr pixmap, int fd) +{ + struct wl_shm_pool *pool; + WindowPtr window = xwl_window->window; + ScreenPtr screen = window->drawable.pScreen; + VisualID visual = wVisual(window); + uint32_t format; + int size, stride, bpp, i; + + for (i = 0; i < screen->numVisuals; i++) + if (screen->visuals[i].vid == visual) + break; + + switch (screen->visuals[i].nplanes) { + case 32: + format = WL_SHM_FORMAT_ARGB8888; + bpp = 4; + break; + case 24: + default: + format = WL_SHM_FORMAT_XRGB8888; + bpp = 4; + break; +#ifdef WL_SHM_FORMAT_RGB565 + case 16: + /* XXX: Check run-time protocol version too */ + format = WL_SHM_FORMAT_RGB565; + bpp = 2; + break; +#endif + } + + stride = pixmap->drawable.width * bpp; + size = stride * pixmap->drawable.height; + + pool = wl_shm_create_pool(xwl_window->xwl_screen->shm, fd, size); + xwl_window->buffer = wl_shm_pool_create_buffer(pool, 0, + pixmap->drawable.width, + pixmap->drawable.height, + stride, format); + wl_shm_pool_destroy(pool); + + return xwl_window->buffer ? Success : BadDrawable; +} + +void xwl_screen_close(struct xwl_screen *xwl_screen) +{ + struct xwl_seat *xwl_seat, *itmp; + struct xwl_window *xwl_window, *wtmp; + + if (xwl_screen->registry) + wl_registry_destroy(xwl_screen->registry); + xwl_screen->registry = NULL; + + xorg_list_for_each_entry_safe(xwl_seat, itmp, + &xwl_screen->seat_list, link) { + wl_seat_destroy(xwl_seat->seat); + free(xwl_seat); + } + xorg_list_for_each_entry_safe(xwl_window, wtmp, + &xwl_screen->window_list, link) { + wl_buffer_destroy(xwl_window->buffer); + wl_surface_destroy(xwl_window->surface); + free(xwl_window); + } + + xorg_list_init(&xwl_screen->seat_list); + xorg_list_init(&xwl_screen->damage_window_list); + xorg_list_init(&xwl_screen->window_list); + xorg_list_init(&xwl_screen->authenticate_client_list); + + wl_display_roundtrip(xwl_screen->display); +} + +void xwl_screen_destroy(struct xwl_screen *xwl_screen) +{ + struct xwl_output *xwl_output, *tmp; + + xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) { + xwl_output_remove(xwl_output); + break; + } + + free(xwl_screen); +} + +/* DDX driver must call this after submitting the rendering */ +void xwl_screen_post_damage(struct xwl_screen *xwl_screen) +{ + struct xwl_window *xwl_window; + RegionPtr region; + BoxPtr box; + int count, i; + + xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list, + link_damage) { + region = DamageRegion(xwl_window->damage); + count = RegionNumRects(region); + for (i = 0; i < count; i++) { + box = &RegionRects(region)[i]; + wl_surface_damage(xwl_window->surface, + box->x1, box->y1, + box->x2 - box->x1, + box->y2 - box->y1); + } + wl_surface_attach(xwl_window->surface, + xwl_window->buffer, + 0, 0); + wl_surface_commit(xwl_window->surface); + DamageEmpty(xwl_window->damage); + } + + xorg_list_init(&xwl_screen->damage_window_list); +} + +static void * +xwl_setup(void *module, void *opts, int *errmaj, int *errmin) +{ + return module; +} + +static void +xwl_teardown(void *p) +{ +} + +static XF86ModuleVersionInfo xwl_version_info = { + "xwayland", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_EXTENSION, + ABI_EXTENSION_VERSION, + MOD_CLASS_NONE, + { 0, 0, 0, 0 } +}; + +_X_EXPORT const XF86ModuleData xwaylandModuleData = { + &xwl_version_info, + &xwl_setup, + &xwl_teardown +}; + +int +xwl_version(void) +{ + return xwl_version_info.minorversion; +} diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h new file mode 100644 index 000000000..7f81e2cfc --- /dev/null +++ b/hw/xfree86/xwayland/xwayland.h @@ -0,0 +1,86 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef _XWAYLAND_H_ +#define _XWAYLAND_H_ + +#include + + +#define XWL_VERSION 2 + +struct xwl_window; +struct xwl_screen; + +struct xwl_driver { + int version; + int use_drm; + int (*create_window_buffer)(struct xwl_window *xwl_window, + PixmapPtr pixmap); +}; + +#define XWL_FLAGS_ROOTLESS 0x01 + +extern _X_EXPORT int +xwl_version(void); + +extern _X_EXPORT struct xwl_screen * +xwl_screen_create(void); + +extern _X_EXPORT Bool +xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen, + uint32_t flags, struct xwl_driver *driver); + +extern _X_EXPORT int +xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen); + +extern _X_EXPORT int +xwl_drm_pre_init(struct xwl_screen *xwl_screen); + +extern _X_EXPORT int +xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen); + +extern _X_EXPORT void +xwl_screen_close(struct xwl_screen *xwl_screen); + +extern _X_EXPORT void +xwl_screen_destroy(struct xwl_screen *xwl_screen); + +extern _X_EXPORT void +xwl_screen_post_damage(struct xwl_screen *xwl_screen); + +extern _X_EXPORT int +xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen, + uint32_t magic); + +extern _X_EXPORT int +xwl_create_window_buffer_drm(struct xwl_window *xwl_window, + PixmapPtr pixmap, uint32_t name); + +extern _X_EXPORT int +xwl_create_window_buffer_shm(struct xwl_window *xwl_window, + PixmapPtr pixmap, int fd); + +#endif /* _XWAYLAND_H_ */ diff --git a/include/input.h b/include/input.h index 36463f2d1..afbb37026 100644 --- a/include/input.h +++ b/include/input.h @@ -508,7 +508,7 @@ extern int AttachDevice(ClientPtr client, DeviceIntPtr slave, DeviceIntPtr master); extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd); -extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type); +extern _X_EXPORT DeviceIntPtr GetMaster(DeviceIntPtr dev, int type); extern _X_EXPORT int AllocDevicePair(ClientPtr client, const char *name, diff --git a/include/os.h b/include/os.h index 3b4e8f341..5be3bcc49 100644 --- a/include/os.h +++ b/include/os.h @@ -166,10 +166,9 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr /*client */ ); extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ ); -#if defined(XQUARTZ) || defined(XORG_WAYLAND) extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ ); + extern _X_EXPORT void AddClientOnOpenFD(int /* fd */ ); -#endif extern _X_EXPORT CARD32 GetTimeInMillis(void); extern _X_EXPORT CARD64 GetTimeInMicros(void); diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index 487d7addb..b5b0ed499 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -145,4 +145,7 @@ /* Support APM/ACPI power management in the server */ #undef XF86PM +/* Building Xorg server. */ +#undef XORG_WAYLAND + #endif /* _XORG_CONFIG_H_ */ diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in index 8bf9d38f2..b4180f4a6 100644 --- a/include/xorg-server.h.in +++ b/include/xorg-server.h.in @@ -227,4 +227,7 @@ /* Ask fontsproto to make font path element names const */ #define FONT_PATH_ELEMENT_NAME_CONST 1 +/* Building Xorg server. */ +#undef XORG_WAYLAND + #endif /* _XORG_SERVER_H_ */ diff --git a/os/connection.c b/os/connection.c index b0e999e33..848e72316 100644 --- a/os/connection.c +++ b/os/connection.c @@ -64,7 +64,6 @@ SOFTWARE. #include #endif -#include #ifdef WIN32 #include #endif @@ -1259,7 +1258,6 @@ MakeClientGrabPervious(ClientPtr client) } } -#if defined(XQUARTZ) || defined(XORG_WAYLAND) /* Add a fd (from launchd) to our listeners */ void ListenOnOpenFD(int fd, int noxauth) @@ -1334,5 +1332,3 @@ AddClientOnOpenFD(int fd) return; } } - -#endif -- cgit v1.2.1