aboutsummaryrefslogtreecommitdiff
path: root/xorg-server
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-04-13 14:24:56 +0200
committermarha <marha@users.sourceforge.net>2014-04-13 14:24:56 +0200
commitd2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed (patch)
tree2a860c9d687826b3cb48facfa21c616e14e69347 /xorg-server
parentedb5b380994125bf33929ef7dc5a3c456dfbe93b (diff)
downloadvcxsrv-d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed.tar.gz
vcxsrv-d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed.tar.bz2
vcxsrv-d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed.zip
fontconfig libxcb mesa xserver xcb-proto git update 13 Apr 2014
xserver commit 3028ae6c9aa37168e249e0d847b29f8e3efb05b2 libxcb commit 29e419c5840a1eeda3336a0802686ee723dcaab3 libxcb/xcb-proto commit 70fea02b7d90d86e9d3b0dc5b61406bf4c910999 pixman commit 4b76bbfda670f9ede67d0449f3640605e1fc4df0 fontconfig commit f44157c809d280e2a0ce87fb078fc4b278d24a67 mesa commit 936dda08ee6d7b2be2b016bc06780e401088ec13
Diffstat (limited to 'xorg-server')
-rw-r--r--xorg-server/Xext/Makefile.am4
-rw-r--r--xorg-server/Xi/Makefile.am5
-rw-r--r--xorg-server/composite/compext.c13
-rw-r--r--xorg-server/composite/compinit.c24
-rw-r--r--xorg-server/composite/compint.h7
-rw-r--r--xorg-server/composite/compositeext.h4
-rw-r--r--xorg-server/composite/compwindow.c18
-rw-r--r--xorg-server/configure.ac48
-rw-r--r--xorg-server/dix/events.c46
-rw-r--r--xorg-server/dix/globals.c3
-rw-r--r--xorg-server/dri3/dri3.h14
-rw-r--r--xorg-server/dri3/dri3_request.c38
-rw-r--r--xorg-server/dri3/dri3_screen.c16
-rw-r--r--xorg-server/fb/Makefile.am3
-rw-r--r--xorg-server/fb/fbpict.c4
-rw-r--r--xorg-server/fb/fbpict.h15
-rw-r--r--xorg-server/glamor/Makefile.am10
-rw-r--r--xorg-server/glamor/glamor.c34
-rw-r--r--xorg-server/glamor/glamor.h21
-rw-r--r--xorg-server/glamor/glamor_core.c14
-rw-r--r--xorg-server/glamor/glamor_egl.c11
-rw-r--r--xorg-server/glamor/glamor_egl_stubs.c4
-rw-r--r--xorg-server/glamor/glamor_fillspans.c107
-rw-r--r--xorg-server/glamor/glamor_font.c186
-rw-r--r--xorg-server/glamor/glamor_font.h49
-rw-r--r--xorg-server/glamor/glamor_getspans.c92
-rw-r--r--xorg-server/glamor/glamor_glyphblt.c261
-rw-r--r--xorg-server/glamor/glamor_pixmap.c4
-rw-r--r--xorg-server/glamor/glamor_points.c21
-rw-r--r--xorg-server/glamor/glamor_polyfillrect.c123
-rw-r--r--xorg-server/glamor/glamor_priv.h73
-rw-r--r--xorg-server/glamor/glamor_program.c18
-rw-r--r--xorg-server/glamor/glamor_rects.c189
-rw-r--r--xorg-server/glamor/glamor_setspans.c118
-rw-r--r--xorg-server/glamor/glamor_spans.c438
-rw-r--r--xorg-server/glamor/glamor_text.c526
-rw-r--r--xorg-server/glamor/glamor_transfer.c264
-rw-r--r--xorg-server/glamor/glamor_transfer.h55
-rw-r--r--xorg-server/glamor/glamor_xv.c14
-rw-r--r--xorg-server/hw/Makefile.am9
-rw-r--r--xorg-server/hw/dmx/Makefile.am1
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c1
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c5
-rw-r--r--xorg-server/hw/kdrive/src/Makefile.am5
-rw-r--r--xorg-server/hw/vfb/Makefile.am11
-rw-r--r--xorg-server/hw/xfree86/.gitignore1
-rw-r--r--xorg-server/hw/xfree86/Makefile.am3
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c28
-rw-r--r--xorg-server/hw/xfree86/common/xf86Globals.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Helper.c31
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c16
-rw-r--r--xorg-server/hw/xfree86/common/xf86Module.h2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Privstr.h4
-rw-r--r--xorg-server/hw/xfree86/dixmods/Makefile.am4
-rw-r--r--xorg-server/hw/xfree86/man/Xorg.man6
-rw-r--r--xorg-server/hw/xfree86/man/xorg.conf.man6
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.h4
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Cursors.c35
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/systemd-logind.c34
-rw-r--r--xorg-server/hw/xfree86/parser/DRI.c1
-rw-r--r--xorg-server/hw/xfree86/parser/Extensions.c1
-rw-r--r--xorg-server/hw/xfree86/ramdac/IBM.c6
-rw-r--r--xorg-server/hw/xfree86/ramdac/TI.c3
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.c11
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.h4
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h2
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86HWCurs.c15
-rw-r--r--xorg-server/hw/xnest/Makefile.am9
-rw-r--r--xorg-server/hw/xquartz/Makefile.am1
-rw-r--r--xorg-server/hw/xquartz/X11Controller.m5
-rw-r--r--xorg-server/hw/xwayland/.gitignore3
-rw-r--r--xorg-server/hw/xwayland/Makefile.am30
-rw-r--r--xorg-server/hw/xwayland/xwayland-cursor.c193
-rw-r--r--xorg-server/hw/xwayland/xwayland-cvt.c304
-rw-r--r--xorg-server/hw/xwayland/xwayland-input.c666
-rw-r--r--xorg-server/hw/xwayland/xwayland-output.c226
-rw-r--r--xorg-server/hw/xwayland/xwayland-shm.c292
-rw-r--r--xorg-server/hw/xwayland/xwayland.c652
-rw-r--r--xorg-server/hw/xwayland/xwayland.h164
-rw-r--r--xorg-server/hw/xwin/Makefile.am9
-rw-r--r--xorg-server/include/input.h1
-rw-r--r--xorg-server/include/opaque.h1
-rw-r--r--xorg-server/include/scrnintstr.h7
-rw-r--r--xorg-server/include/xorg-config.h.in11
-rw-r--r--xorg-server/include/xwin-config.h.in3
-rw-r--r--xorg-server/mi/mi.h4
-rw-r--r--xorg-server/mi/miscrinit.c1
-rw-r--r--xorg-server/mi/miwindow.c66
-rw-r--r--xorg-server/os/connection.c12
-rw-r--r--xorg-server/os/utils.c2
-rw-r--r--xorg-server/test/Makefile.am6
-rw-r--r--xorg-server/xkb/xkbAccessX.c2
92 files changed, 4966 insertions, 849 deletions
diff --git a/xorg-server/Xext/Makefile.am b/xorg-server/Xext/Makefile.am
index 8e31f1367..a9a446820 100644
--- a/xorg-server/Xext/Makefile.am
+++ b/xorg-server/Xext/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES = libXext.la
+noinst_LTLIBRARIES = libXext.la libXextdpmsstubs.la
AM_CFLAGS = $(DIX_CFLAGS)
@@ -96,6 +96,8 @@ endif
libXext_la_SOURCES = $(BUILTIN_SRCS)
libXext_la_LIBADD = $(BUILTIN_LIBS)
+libXextdpmsstubs_la_SOURCES = dpmsstubs.c
+
EXTRA_DIST = \
$(MITSHM_SRCS) \
$(XV_SRCS) \
diff --git a/xorg-server/Xi/Makefile.am b/xorg-server/Xi/Makefile.am
index af85bd049..6c456c4ac 100644
--- a/xorg-server/Xi/Makefile.am
+++ b/xorg-server/Xi/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES = libXi.la
+noinst_LTLIBRARIES = libXi.la libXistubs.la
AM_CFLAGS = $(DIX_CFLAGS)
@@ -107,4 +107,5 @@ libXi_la_SOURCES = \
xiwarppointer.c \
xiwarppointer.h
-EXTRA_DIST = stubs.c
+libXistubs_la_SOURCES = \
+ stubs.c
diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c
index a945f721f..cadedbd37 100644
--- a/xorg-server/composite/compext.c
+++ b/xorg-server/composite/compext.c
@@ -239,6 +239,7 @@ ProcCompositeNameWindowPixmap(ClientPtr client)
WindowPtr pWin;
CompWindowPtr cw;
PixmapPtr pPixmap;
+ ScreenPtr pScreen;
int rc;
REQUEST(xCompositeNameWindowPixmapReq);
@@ -246,6 +247,8 @@ ProcCompositeNameWindowPixmap(ClientPtr client)
REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ pScreen = pWin->drawable.pScreen;
+
if (!pWin->viewable)
return BadMatch;
@@ -255,7 +258,7 @@ ProcCompositeNameWindowPixmap(ClientPtr client)
if (!cw)
return BadMatch;
- pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+ pPixmap = (*pScreen->GetWindowPixmap) (pWin);
if (!pPixmap)
return BadMatch;
@@ -270,6 +273,14 @@ ProcCompositeNameWindowPixmap(ClientPtr client)
if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap))
return BadAlloc;
+ if (pScreen->NameWindowPixmap) {
+ rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap);
+ if (rc != Success) {
+ FreeResource(stuff->pixmap, RT_NONE);
+ return rc;
+ }
+ }
+
return Success;
}
diff --git a/xorg-server/composite/compinit.c b/xorg-server/composite/compinit.c
index 1db9e0bf5..48e938fac 100644
--- a/xorg-server/composite/compinit.c
+++ b/xorg-server/composite/compinit.c
@@ -229,6 +229,28 @@ CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids,
return compRegisterAlternateVisuals(cs, vids, nVisuals);
}
+Bool
+CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
+ VisualID parentVisual,
+ VisualID winVisual)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompImplicitRedirectException *p;
+
+ p = realloc(cs->implicitRedirectExceptions,
+ sizeof(p[0]) * (cs->numImplicitRedirectExceptions + 1));
+ if (p == NULL)
+ return FALSE;
+
+ p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual;
+ p[cs->numImplicitRedirectExceptions].winVisual = winVisual;
+
+ cs->implicitRedirectExceptions = p;
+ cs->numImplicitRedirectExceptions++;
+
+ return TRUE;
+}
+
typedef struct _alternateVisual {
int depth;
CARD32 format;
@@ -349,6 +371,8 @@ compScreenInit(ScreenPtr pScreen)
cs->numAlternateVisuals = 0;
cs->alternateVisuals = NULL;
+ cs->numImplicitRedirectExceptions = 0;
+ cs->implicitRedirectExceptions = NULL;
if (!compAddAlternateVisuals(pScreen, cs)) {
free(cs);
diff --git a/xorg-server/composite/compint.h b/xorg-server/composite/compint.h
index 12dc8b3f7..56b76c540 100644
--- a/xorg-server/composite/compint.h
+++ b/xorg-server/composite/compint.h
@@ -119,6 +119,11 @@ typedef struct _CompOverlayClientRec {
XID resource;
} CompOverlayClientRec;
+typedef struct _CompImplicitRedirectException {
+ XID parentVisual;
+ XID winVisual;
+} CompImplicitRedirectException;
+
typedef struct _CompScreen {
PositionWindowProcPtr PositionWindow;
CopyWindowProcPtr CopyWindow;
@@ -155,6 +160,8 @@ typedef struct _CompScreen {
CloseScreenProcPtr CloseScreen;
int numAlternateVisuals;
VisualID *alternateVisuals;
+ int numImplicitRedirectExceptions;
+ CompImplicitRedirectException *implicitRedirectExceptions;
WindowPtr pOverlayWin;
Window overlayWid;
diff --git a/xorg-server/composite/compositeext.h b/xorg-server/composite/compositeext.h
index 0b148f029..b96cb1d68 100644
--- a/xorg-server/composite/compositeext.h
+++ b/xorg-server/composite/compositeext.h
@@ -35,6 +35,10 @@ extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen,
VisualID * vids,
int nVisuals);
+extern _X_EXPORT Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
+ VisualID parentVisual,
+ VisualID winVisual);
+
extern _X_EXPORT RESTYPE CompositeClientWindowType;
#endif /* _COMPOSITEEXT_H_ */
diff --git a/xorg-server/composite/compwindow.c b/xorg-server/composite/compwindow.c
index 6c2434959..882429414 100644
--- a/xorg-server/composite/compwindow.c
+++ b/xorg-server/composite/compwindow.c
@@ -336,6 +336,21 @@ compIsAlternateVisual(ScreenPtr pScreen, XID visual)
}
static Bool
+compIsImplicitRedirectException(ScreenPtr pScreen,
+ XID parentVisual, XID winVisual)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ int i;
+
+ for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
+ if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
+ cs->implicitRedirectExceptions[i].winVisual == winVisual)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
compImplicitRedirect(WindowPtr pWin, WindowPtr pParent)
{
if (pParent) {
@@ -343,6 +358,9 @@ compImplicitRedirect(WindowPtr pWin, WindowPtr pParent)
XID winVisual = wVisual(pWin);
XID parentVisual = wVisual(pParent);
+ if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
+ return FALSE;
+
if (winVisual != parentVisual &&
(compIsAlternateVisual(pScreen, winVisual) ||
compIsAlternateVisual(pScreen, parentVisual)))
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index a75ba8f69..695a4819a 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -26,9 +26,9 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.15.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2014-02-24"
-RELEASE_NAME="Szechuan Hot Pot"
+AC_INIT([xorg-server], 1.15.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2014-04-08"
+RELEASE_NAME="Glacier Blue"
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
@@ -624,8 +624,8 @@ 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(systemd-logind, AC_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto])
-AC_ARG_ENABLE(suid-wrapper, AC_HELP_STRING([--enable-suid-wrapper], [Build suid-root wrapper for legacy driver support on rootless xserver systems (default: no)]), [SUID_WRAPPER=$enableval], [SUID_WRAPPER=no])
+AC_ARG_ENABLE(systemd-logind, AS_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto])
+AC_ARG_ENABLE(suid-wrapper, AS_HELP_STRING([--enable-suid-wrapper], [Build suid-root wrapper for legacy driver support on rootless xserver systems (default: no)]), [SUID_WRAPPER=$enableval], [SUID_WRAPPER=no])
dnl DDXes.
AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
@@ -633,6 +633,7 @@ AC_ARG_ENABLE(dmx, AS_HELP_STRING([--enable-dmx], [Build DMX server (d
AC_ARG_ENABLE(xvfb, AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
AC_ARG_ENABLE(xnest, AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
+AC_ARG_ENABLE(xwayland, AS_HELP_STRING([--enable-xwayland], [Build Xwayland server (default: auto)]), [XWAYLAND=$enableval], [XWAYLAND=auto])
AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
AC_ARG_ENABLE(glamor, AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
@@ -751,6 +752,7 @@ case $host_os in
XQUARTZ=yes
XVFB=no
XNEST=no
+ XWAYLAND=no
COMPOSITE=no
DGA=no
@@ -2042,7 +2044,9 @@ if test "x$XORG" = xyes; then
XF86CONFIGDIR="xorg.conf.d"
AC_SUBST(XF86CONFIGDIR)
CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
- LOGPREFIX="$logdir/Xorg."
+ LOGPREFIX="Xorg."
+ XDG_DATA_HOME=".local/share"
+ XDG_DATA_HOME_LOGDIR="xorg"
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
@@ -2055,7 +2059,10 @@ if test "x$XORG" = xyes; then
AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory])
AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
- AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
+ AC_DEFINE_DIR(DEFAULT_LOGDIR, logdir, [Default log location])
+ AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default logfile prefix])
+ AC_DEFINE_DIR(DEFAULT_XDG_DATA_HOME, XDG_DATA_HOME, [Default XDG_DATA dir under HOME])
+ AC_DEFINE_DIR(DEFAULT_XDG_DATA_HOME_LOGDIR, XDG_DATA_HOME_LOGDIR, [Default log dir under XDG_DATA_HOME])
AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
if test "x$VGAHW" = xyes; then
AC_DEFINE(WITH_VGAHW, 1, [Building vgahw module])
@@ -2408,8 +2415,7 @@ if test "$KDRIVE" = yes; then
fi
;;
esac
- KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.la'
- KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB"
+ KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB"
KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB"
KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS $TSLIB_LIBS"
@@ -2433,6 +2439,29 @@ AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes])
AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
+dnl Xwayland DDX
+
+PKG_CHECK_MODULES(XWAYLANDMODULES, [wayland-client libdrm epoxy], [have_xwayland=yes], [have_xwayland=no])
+AC_MSG_CHECKING([whether to build Xwayland DDX])
+if test "x$XWAYLAND" = xauto; then
+ XWAYLAND="$have_xwayland"
+fi
+AC_MSG_RESULT([$XWAYLAND])
+AM_CONDITIONAL(XWAYLAND, [test "x$XWAYLAND" = xyes])
+
+if test "x$XWAYLAND" = xyes; then
+ if test "x$have_xwayland" = xno; then
+ AC_MSG_ERROR([Xwayland build explicitly requested, but required modules not found.])
+ fi
+
+ XWAYLAND_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
+ XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS"
+ AC_SUBST([XWAYLAND_LIBS])
+ AC_SUBST([XWAYLAND_SYS_LIBS])
+ WAYLAND_SCANNER_RULES(['$(top_srcdir)/hw/xwayland'])
+fi
+
+
dnl and the rest of these are generic, so they're in config.h
dnl
dnl though, thanks to the passing of some significant amount of time, the
@@ -2575,6 +2604,7 @@ hw/kdrive/fake/Makefile
hw/kdrive/fbdev/Makefile
hw/kdrive/linux/Makefile
hw/kdrive/src/Makefile
+hw/xwayland/Makefile
test/Makefile
test/xi2/Makefile
xserver.ent
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index f05dada3d..125a0ee29 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -2835,7 +2835,7 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent)
return deliveries;
}
-static Bool
+Bool
PointInBorderSize(WindowPtr pWin, int x, int y)
{
BoxRec box;
@@ -2876,49 +2876,9 @@ PointInBorderSize(WindowPtr pWin, int x, int y)
WindowPtr
XYToWindow(SpritePtr pSprite, int x, int y)
{
- WindowPtr pWin;
- BoxRec box;
+ ScreenPtr pScreen = RootWindow(pSprite)->drawable.pScreen;
- pSprite->spriteTraceGood = 1; /* root window still there */
- pWin = RootWindow(pSprite)->firstChild;
- while (pWin) {
- if ((pWin->mapped) &&
- (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
- (x < pWin->drawable.x + (int) pWin->drawable.width +
- wBorderWidth(pWin)) &&
- (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
- (y < pWin->drawable.y + (int) pWin->drawable.height +
- wBorderWidth(pWin))
- /* When a window is shaped, a further check
- * is made to see if the point is inside
- * borderSize
- */
- && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
- && (!wInputShape(pWin) ||
- RegionContainsPoint(wInputShape(pWin),
- x - pWin->drawable.x,
- y - pWin->drawable.y, &box))
-#ifdef ROOTLESS
- /* In rootless mode windows may be offscreen, even when
- * they're in X's stack. (E.g. if the native window system
- * implements some form of virtual desktop system).
- */
- && !pWin->rootlessUnhittable
-#endif
- ) {
- if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
- pSprite->spriteTraceSize += 10;
- pSprite->spriteTrace = realloc(pSprite->spriteTrace,
- pSprite->spriteTraceSize *
- sizeof(WindowPtr));
- }
- pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
- pWin = pWin->firstChild;
- }
- else
- pWin = pWin->nextSib;
- }
- return DeepestSpriteWin(pSprite);
+ return (*pScreen->XYToWindow)(pScreen, pSprite, x, y);
}
/**
diff --git a/xorg-server/dix/globals.c b/xorg-server/dix/globals.c
index 9738e9cdf..eaa2afe24 100644
--- a/xorg-server/dix/globals.c
+++ b/xorg-server/dix/globals.c
@@ -127,7 +127,8 @@ int defaultColorVisualClass = -1;
int monitorResolution = 0;
const char *display;
-int displayfd;
+int displayfd = -1;
+Bool explicit_display = FALSE;
char *ConnectionInfo;
CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
diff --git a/xorg-server/dri3/dri3.h b/xorg-server/dri3/dri3.h
index 7c0c33018..edc7fa267 100644
--- a/xorg-server/dri3/dri3.h
+++ b/xorg-server/dri3/dri3.h
@@ -30,12 +30,17 @@
#include <X11/extensions/dri3proto.h>
#include <randrstr.h>
-#define DRI3_SCREEN_INFO_VERSION 0
+#define DRI3_SCREEN_INFO_VERSION 1
typedef int (*dri3_open_proc)(ScreenPtr screen,
RRProviderPtr provider,
int *fd);
+typedef int (*dri3_open_client_proc)(ClientPtr client,
+ ScreenPtr screen,
+ RRProviderPtr provider,
+ int *fd);
+
typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen,
int fd,
CARD16 width,
@@ -55,11 +60,18 @@ typedef struct dri3_screen_info {
dri3_open_proc open;
dri3_pixmap_from_fd_proc pixmap_from_fd;
dri3_fd_from_pixmap_proc fd_from_pixmap;
+
+ /* Version 1 */
+ dri3_open_client_proc open_client;
+
} dri3_screen_info_rec, *dri3_screen_info_ptr;
extern _X_EXPORT Bool
dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info);
+extern _X_EXPORT int
+dri3_send_open_reply(ClientPtr client, int fd);
+
#endif
#endif /* _DRI3_H_ */
diff --git a/xorg-server/dri3/dri3_request.c b/xorg-server/dri3/dri3_request.c
index 31dce83f6..fe45620c9 100644
--- a/xorg-server/dri3/dri3_request.c
+++ b/xorg-server/dri3/dri3_request.c
@@ -55,16 +55,35 @@ proc_dri3_query_version(ClientPtr client)
return Success;
}
-static int
-proc_dri3_open(ClientPtr client)
+int
+dri3_send_open_reply(ClientPtr client, int fd)
{
- REQUEST(xDRI3OpenReq);
xDRI3OpenReply rep = {
.type = X_Reply,
.nfd = 1,
.sequenceNumber = client->sequence,
.length = 0,
};
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+
+ if (WriteFdToClient(client, fd, TRUE) < 0) {
+ close(fd);
+ return BadAlloc;
+ }
+
+ WriteToClient(client, sizeof (rep), &rep);
+
+ return Success;
+}
+
+static int
+proc_dri3_open(ClientPtr client)
+{
+ REQUEST(xDRI3OpenReq);
RRProviderPtr provider;
DrawablePtr drawable;
ScreenPtr screen;
@@ -92,17 +111,8 @@ proc_dri3_open(ClientPtr client)
if (status != Success)
return status;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- }
-
- if (WriteFdToClient(client, fd, TRUE) < 0) {
- close(fd);
- return BadAlloc;
- }
-
- WriteToClient(client, sizeof (rep), &rep);
+ if (client->ignoreCount == 0)
+ return dri3_send_open_reply(client, fd);
return Success;
}
diff --git a/xorg-server/dri3/dri3_screen.c b/xorg-server/dri3/dri3_screen.c
index c88029612..6c0c60cbf 100644
--- a/xorg-server/dri3/dri3_screen.c
+++ b/xorg-server/dri3/dri3_screen.c
@@ -30,6 +30,14 @@
#include <misyncshm.h>
#include <randrstr.h>
+static inline Bool has_open(dri3_screen_info_ptr info) {
+ if (info == NULL)
+ return FALSE;
+
+ return info->open != NULL ||
+ (info->version >= 1 && info->open_client != NULL);
+}
+
int
dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd)
{
@@ -37,10 +45,14 @@ dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd)
dri3_screen_info_ptr info = ds->info;
int rc;
- if (!info || !info->open)
+ if (!has_open(info))
return BadMatch;
- rc = (*info->open) (screen, provider, fd);
+ if (info->version >= 1 && info->open_client != NULL)
+ rc = (*info->open_client) (client, screen, provider, fd);
+ else
+ rc = (*info->open) (screen, provider, fd);
+
if (rc != Success)
return rc;
diff --git a/xorg-server/fb/Makefile.am b/xorg-server/fb/Makefile.am
index 89f3babb1..752eabeb7 100644
--- a/xorg-server/fb/Makefile.am
+++ b/xorg-server/fb/Makefile.am
@@ -22,6 +22,7 @@ libfb_la_SOURCES = \
fbbits.h \
fbblt.c \
fbbltone.c \
+ fbcmap_mi.c \
fbcopy.c \
fbfill.c \
fbfillrect.c \
@@ -50,5 +51,3 @@ libfb_la_SOURCES = \
fbwindow.c
libwfb_la_SOURCES = $(libfb_la_SOURCES)
-
-EXTRA_DIST = fbcmap_mi.c
diff --git a/xorg-server/fb/fbpict.c b/xorg-server/fb/fbpict.c
index b50385805..c2ee8a552 100644
--- a/xorg-server/fb/fbpict.c
+++ b/xorg-server/fb/fbpict.c
@@ -82,7 +82,7 @@ fbDestroyGlyphCache(void)
}
}
-static void
+void
fbUnrealizeGlyph(ScreenPtr pScreen,
GlyphPtr pGlyph)
{
@@ -90,7 +90,7 @@ fbUnrealizeGlyph(ScreenPtr pScreen,
pixman_glyph_cache_remove (glyphCache, pGlyph, NULL);
}
-static void
+void
fbGlyphs(CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
diff --git a/xorg-server/fb/fbpict.h b/xorg-server/fb/fbpict.h
index 110f32dfe..8b0f59f7a 100644
--- a/xorg-server/fb/fbpict.h
+++ b/xorg-server/fb/fbpict.h
@@ -65,11 +65,24 @@ fbTrapezoids(CARD8 op,
INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps);
extern _X_EXPORT void
-
fbTriangles(CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
+extern _X_EXPORT void
+fbUnrealizeGlyph(ScreenPtr pScreen,
+ GlyphPtr pGlyph);
+
+extern _X_EXPORT void
+fbGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
#endif /* _FBPICT_H_ */
diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am
index 8555e4087..4d0cc8138 100644
--- a/xorg-server/glamor/Makefile.am
+++ b/xorg-server/glamor/Makefile.am
@@ -12,18 +12,20 @@ libglamor_la_SOURCES = \
glamor_core.c \
glamor_debug.h \
glamor_fill.c \
- glamor_fillspans.c \
- glamor_getspans.c \
+ glamor_font.c \
glamor_glx.c \
glamor_glyphs.c \
- glamor_polyfillrect.c \
glamor_polylines.c \
glamor_putimage.c \
- glamor_setspans.c \
glamor_segment.c \
glamor_render.c \
glamor_gradient.c \
glamor_program.c \
+ glamor_rects.c \
+ glamor_spans.c \
+ glamor_text.c \
+ glamor_transfer.c \
+ glamor_transfer.h \
glamor_transform.c \
glamor_trapezoid.c \
glamor_tile.c \
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index 30944326b..2c2d9760c 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.c
@@ -182,7 +182,15 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
- if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
+ if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
+ pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
+ pixmap_priv->base.box.x1 = 0;
+ pixmap_priv->base.box.y1 = 0;
+ pixmap_priv->base.box.x2 = w;
+ pixmap_priv->base.box.y2 = h;
+ return pixmap;
+ }
+ else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
glamor_check_fbo_size(glamor_priv, w, h))
{
pixmap_priv->type = type;
@@ -353,6 +361,15 @@ glamor_init(ScreenPtr screen, unsigned int flags)
gl_version = epoxy_gl_version();
+ /* Would be nice to have a cleaner test for GLSL 1.30 support,
+ * but for now this should suffice
+ */
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && gl_version >= 30)
+ glamor_priv->glsl_version = 130;
+ else
+ glamor_priv->glsl_version = 120;
+
+
/* We'd like to require GL_ARB_map_buffer_range or
* GL_OES_map_buffer_range, since it offers more information to
* the driver than plain old glMapBuffer() or glBufferSubData().
@@ -415,6 +432,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
screen->CreateScreenResources;
screen->CreateScreenResources = glamor_create_screen_resources;
+ if (!glamor_font_init(screen))
+ goto fail;
+
if (flags & GLAMOR_USE_SCREEN) {
if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
_glamor_wakeup_handler,
@@ -475,13 +495,13 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->saved_procs.create_picture = ps->CreatePicture;
ps->CreatePicture = glamor_create_picture;
- glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
- screen->SetWindowPixmap = glamor_set_window_pixmap;
-
glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
ps->DestroyPicture = glamor_destroy_picture;
glamor_init_composite_shaders(screen);
#endif
+ glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
+ screen->SetWindowPixmap = glamor_set_window_pixmap;
+
glamor_init_vbo(screen);
glamor_init_pixmap_fbo(screen);
glamor_init_solid_shader(screen);
@@ -494,9 +514,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
#ifdef GLAMOR_GRADIENT_SHADER
glamor_init_gradient_shader(screen);
#endif
-#ifdef GLAMOR_XV
- glamor_init_xv_shader(screen);
-#endif
glamor_pixmap_init(screen);
glamor_glyphs_init(screen);
@@ -516,9 +533,6 @@ glamor_release_screen_priv(ScreenPtr screen)
glamor_screen_private *glamor_priv;
glamor_priv = glamor_get_screen_private(screen);
-#ifdef GLAMOR_XV
- glamor_fini_xv_shader(screen);
-#endif
#ifdef RENDER
glamor_fini_composite_shaders(screen);
#endif
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index 11ec49361..e63762b44 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -143,12 +143,14 @@ extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
int depth, unsigned int usage);
+extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap);
#define GLAMOR_CREATE_PIXMAP_CPU 0x100
#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
#define GLAMOR_CREATE_FBO_NO_FBO 0x103
#define GLAMOR_CREATE_PIXMAP_MAP 0x104
#define GLAMOR_CREATE_NO_LARGE 0x105
+#define GLAMOR_CREATE_PIXMAP_NO_TEXTURE 0x106
/* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
*
@@ -310,6 +312,8 @@ extern _X_EXPORT Bool
#endif
+extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
+ struct glamor_context *glamor_ctx);
extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
extern _X_EXPORT int glamor_create_gc(GCPtr gc);
@@ -431,12 +435,23 @@ extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC,
extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC,
int nseg, xSegment *pSeg);
-extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt);
-
extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
int mode, int n, DDXPointPtr points);
+extern _X_EXPORT Bool glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars, int *final_pos);
+
+extern _X_EXPORT Bool glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, unsigned short *chars, int *final_pos);
+
+extern _X_EXPORT Bool glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars);
+
+extern _X_EXPORT Bool glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, unsigned short *chars);
+
+#define HAS_GLAMOR_TEXT 1
+
#ifdef GLAMOR_FOR_XORG
extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen,
int num_texture_ports);
diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c
index 5711be72f..7b1615d2d 100644
--- a/xorg-server/glamor/glamor_core.c
+++ b/xorg-server/glamor/glamor_core.c
@@ -426,13 +426,13 @@ GCOps glamor_gc_ops = {
.FillPolygon = miFillPolygon,
.PolyFillRect = glamor_poly_fill_rect,
.PolyFillArc = miPolyFillArc,
- .PolyText8 = miPolyText8,
- .PolyText16 = miPolyText16,
- .ImageText8 = miImageText8,
- .ImageText16 = miImageText16,
- .ImageGlyphBlt = glamor_image_glyph_blt, //miImageGlyphBlt,
- .PolyGlyphBlt = glamor_poly_glyph_blt, //miPolyGlyphBlt,
- .PushPixels = glamor_push_pixels, //miPushPixels,
+ .PolyText8 = glamor_poly_text8,
+ .PolyText16 = glamor_poly_text16,
+ .ImageText8 = glamor_image_text8,
+ .ImageText16 = glamor_image_text16,
+ .ImageGlyphBlt = miImageGlyphBlt,
+ .PolyGlyphBlt = glamor_poly_glyph_blt,
+ .PushPixels = glamor_push_pixels,
};
/**
diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c
index 812342129..d37de9b95 100644
--- a/xorg-server/glamor/glamor_egl.c
+++ b/xorg-server/glamor/glamor_egl.c
@@ -608,9 +608,10 @@ glamor_egl_close_screen(ScreenPtr screen)
}
static int
-glamor_dri3_open(ScreenPtr screen,
- RRProviderPtr provider,
- int *fdp)
+glamor_dri3_open_client(ClientPtr client,
+ ScreenPtr screen,
+ RRProviderPtr provider,
+ int *fdp)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl =
@@ -657,8 +658,8 @@ glamor_dri3_open(ScreenPtr screen,
}
static dri3_screen_info_rec glamor_dri3_info = {
- .version = 0,
- .open = glamor_dri3_open,
+ .version = 1,
+ .open_client = glamor_dri3_open_client,
.pixmap_from_fd = glamor_pixmap_from_fd,
.fd_from_pixmap = glamor_fd_from_pixmap,
};
diff --git a/xorg-server/glamor/glamor_egl_stubs.c b/xorg-server/glamor/glamor_egl_stubs.c
index 4fd9e8016..028d1cc05 100644
--- a/xorg-server/glamor/glamor_egl_stubs.c
+++ b/xorg-server/glamor/glamor_egl_stubs.c
@@ -26,7 +26,9 @@
* Stubbed out glamor_egl.c functions for servers other than Xorg.
*/
-#include "glamor_priv.h"
+#include "dix-config.h"
+
+#include "glamor.h"
void
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
diff --git a/xorg-server/glamor/glamor_fillspans.c b/xorg-server/glamor/glamor_fillspans.c
deleted file mode 100644
index 8cbd79f6d..000000000
--- a/xorg-server/glamor/glamor_fillspans.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright © 1998 Keith Packard
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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.
- */
-
-/** @file glamor_fillspans.c
- *
- * FillSpans implementation, taken from fb_fillsp.c
- */
-#include "glamor_priv.h"
-
-static Bool
-_glamor_fill_spans(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points, int *widths, int sorted,
- Bool fallback)
-{
- DDXPointPtr ppt;
- int nbox;
- BoxPtr pbox;
- int x1, x2, y;
- RegionPtr pClip = fbGetCompositeClip(gc);
- Bool ret = FALSE;
-
- if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
- goto fail;
-
- ppt = points;
- while (n--) {
- x1 = ppt->x;
- y = ppt->y;
- x2 = x1 + (int) *widths;
- ppt++;
- widths++;
-
- nbox = REGION_NUM_RECTS(pClip);
- pbox = REGION_RECTS(pClip);
- while (nbox--) {
- int real_x1 = x1, real_x2 = x2;
-
- if (real_x1 < pbox->x1)
- real_x1 = pbox->x1;
-
- if (real_x2 > pbox->x2)
- real_x2 = pbox->x2;
-
- if (real_x2 > real_x1 && pbox->y1 <= y && pbox->y2 > y) {
- if (!glamor_fill(drawable, gc, real_x1, y,
- real_x2 - real_x1, 1, fallback))
- goto fail;
- }
- pbox++;
- }
- }
- ret = TRUE;
- goto done;
-
- fail:
- if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
- && glamor_ddx_fallback_check_gc(gc)) {
- goto done;
- }
- glamor_fallback("to %p (%c)\n", drawable,
- glamor_get_drawable_location(drawable));
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
- glamor_prepare_access_gc(gc)) {
- fbFillSpans(drawable, gc, n, points, widths, sorted);
- }
- glamor_finish_access_gc(gc);
- glamor_finish_access(drawable);
- ret = TRUE;
-
- done:
- return ret;
-}
-
-void
-glamor_fill_spans(DrawablePtr drawable,
- GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted)
-{
- _glamor_fill_spans(drawable, gc, n, points, widths, sorted, TRUE);
-}
-
-Bool
-glamor_fill_spans_nf(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points, int *widths, int sorted)
-{
- return _glamor_fill_spans(drawable, gc, n, points, widths, sorted, FALSE);
-}
diff --git a/xorg-server/glamor/glamor_font.c b/xorg-server/glamor/glamor_font.c
new file mode 100644
index 000000000..47dfe2a69
--- /dev/null
+++ b/xorg-server/glamor/glamor_font.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_font.h"
+#include <dixfontstr.h>
+
+static int glamor_font_generation;
+static int glamor_font_private_index;
+static int glamor_font_screen_count;
+
+glamor_font_t *
+glamor_font_get(ScreenPtr screen, FontPtr font)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_font_t *privates;
+ glamor_font_t *glamor_font;
+ int overall_width, overall_height;
+ int num_rows;
+ int num_cols;
+ int glyph_width_pixels;
+ int glyph_width_bytes;
+ int glyph_height;
+ int row, col;
+ unsigned char c[2];
+ CharInfoPtr glyph;
+ unsigned long count;
+
+
+ privates = FontGetPrivate(font, glamor_font_private_index);
+ if (!privates) {
+ privates = calloc(glamor_font_screen_count, sizeof (glamor_font_t));
+ if (!privates)
+ return NULL;
+ FontSetPrivate(font, glamor_font_private_index, privates);
+ }
+
+ glamor_font = &privates[screen->myNum];
+
+ if (glamor_font->realized)
+ return glamor_font;
+
+ glamor_font->realized = TRUE;
+
+ /* Figure out how many glyphs are in the font */
+ num_cols = font->info.lastCol - font->info.firstCol + 1;
+ num_rows = font->info.lastRow - font->info.firstRow + 1;
+
+ /* Figure out the size of each glyph */
+ glyph_width_pixels = font->info.maxbounds.rightSideBearing - font->info.minbounds.leftSideBearing;
+ glyph_height = font->info.maxbounds.ascent + font->info.maxbounds.descent;
+
+ glyph_width_bytes = (glyph_width_pixels + 7) >> 3;
+
+ glamor_font->glyph_width_pixels = glyph_width_pixels;
+ glamor_font->glyph_width_bytes = glyph_width_bytes;
+ glamor_font->glyph_height = glyph_height;
+
+ overall_width = glyph_width_bytes * num_cols;
+ overall_height = glyph_height * num_rows;
+
+ /* Check whether the font has a default character */
+ c[0] = font->info.lastRow + 1;
+ c[1] = font->info.lastCol + 1;
+ (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph);
+
+ glamor_font->default_char = count ? glyph : NULL;
+ glamor_font->default_row = font->info.defaultCh >> 8;
+ glamor_font->default_col = font->info.defaultCh;
+
+ glamor_priv = glamor_get_screen_private(screen);
+ glamor_get_context(glamor_priv);
+
+ glGenTextures(1, &glamor_font->texture_id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ /* Allocate storage */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height,
+ 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ /* Paint all of the glyphs */
+ for (row = 0; row < num_rows; row++) {
+ for (col = 0; col < num_cols; col++) {
+ c[0] = row + font->info.firstRow;
+ c[1] = col + font->info.firstCol;
+
+ (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph);
+
+ if (count)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, col * glyph_width_bytes, row * glyph_height,
+ GLYPHWIDTHBYTES(glyph), GLYPHHEIGHTPIXELS(glyph),
+ GL_RED_INTEGER, GL_UNSIGNED_BYTE, glyph->bits);
+ }
+ }
+
+ glamor_put_context(glamor_priv);
+
+ return glamor_font;
+}
+
+static Bool
+glamor_realize_font(ScreenPtr screen, FontPtr font)
+{
+ return TRUE;
+}
+
+static Bool
+glamor_unrealize_font(ScreenPtr screen, FontPtr font)
+{
+ glamor_screen_private *glamor_priv;
+ glamor_font_t *privates = FontGetPrivate(font, glamor_font_private_index);
+ glamor_font_t *glamor_font;
+ int s;
+
+ if (!privates)
+ return TRUE;
+
+ glamor_font = &privates[screen->myNum];
+
+ if (!glamor_font->realized)
+ return TRUE;
+
+ /* Unrealize the font, freeing the allocated texture */
+ glamor_font->realized = FALSE;
+
+ glamor_priv = glamor_get_screen_private(screen);
+ glamor_get_context(glamor_priv);
+ glDeleteTextures(1, &glamor_font->texture_id);
+ glamor_put_context(glamor_priv);
+
+ /* Check to see if all of the screens are done with this font
+ * and free the private when that happens
+ */
+ for (s = 0; s < glamor_font_screen_count; s++)
+ if (privates[s].realized)
+ return TRUE;
+
+ free(privates);
+ FontSetPrivate(font, glamor_font_private_index, NULL);
+ return TRUE;
+}
+
+Bool
+glamor_font_init(ScreenPtr screen)
+{
+ if (glamor_font_generation != serverGeneration) {
+ glamor_font_private_index = AllocateFontPrivateIndex();
+ if (glamor_font_private_index == -1)
+ return FALSE;
+ glamor_font_screen_count = 0;
+ glamor_font_generation = serverGeneration;
+ }
+
+ if (screen->myNum >= glamor_font_screen_count)
+ glamor_font_screen_count = screen->myNum + 1;
+
+ screen->RealizeFont = glamor_realize_font;
+ screen->UnrealizeFont = glamor_unrealize_font;
+ return TRUE;
+}
diff --git a/xorg-server/glamor/glamor_font.h b/xorg-server/glamor/glamor_font.h
new file mode 100644
index 000000000..36d20624d
--- /dev/null
+++ b/xorg-server/glamor/glamor_font.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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 _GLAMOR_FONT_H_
+#define _GLAMOR_FONT_H_
+
+typedef struct {
+ Bool realized;
+ CharInfoPtr default_char;
+ CARD8 default_row;
+ CARD8 default_col;
+
+ GLuint texture_id;
+
+ CARD16 glyph_width_bytes;
+ CARD16 glyph_width_pixels;
+ CARD16 glyph_height;
+
+} glamor_font_t;
+
+glamor_font_t *
+glamor_font_get(ScreenPtr screen, FontPtr font);
+
+Bool
+glamor_font_init(ScreenPtr screen);
+
+void
+glamor_fini_glyph_shader(ScreenPtr screen);
+
+#endif /* _GLAMOR_FONT_H_ */
diff --git a/xorg-server/glamor/glamor_getspans.c b/xorg-server/glamor/glamor_getspans.c
deleted file mode 100644
index 42df87f3d..000000000
--- a/xorg-server/glamor/glamor_getspans.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- * Zhigang Gong <zhigang.gong@linux.intel.com>
- *
- */
-
-#include "glamor_priv.h"
-
-static Bool
-_glamor_get_spans(DrawablePtr drawable,
- int wmax,
- DDXPointPtr points, int *widths, int count, char *dst,
- Bool fallback)
-{
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- int i;
- uint8_t *readpixels_dst = (uint8_t *) dst;
- void *data;
- int x_off, y_off;
- Bool ret = FALSE;
-
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- goto fail;
-
- glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
- for (i = 0; i < count; i++) {
- data = glamor_download_sub_pixmap_to_cpu(pixmap, points[i].x + x_off,
- points[i].y + y_off, widths[i],
- 1, PixmapBytePad(widths[i],
- drawable->
- depth),
- readpixels_dst, 0,
- GLAMOR_ACCESS_RO);
- (void)data;
- assert(data == readpixels_dst);
- readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
- }
-
- ret = TRUE;
- goto done;
- fail:
-
- if (!fallback && glamor_ddx_fallback_check_pixmap(drawable))
- goto done;
-
- ret = TRUE;
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
- fbGetSpans(drawable, wmax, points, widths, count, dst);
- }
- glamor_finish_access(drawable);
- done:
- return ret;
-}
-
-void
-glamor_get_spans(DrawablePtr drawable,
- int wmax,
- DDXPointPtr points, int *widths, int count, char *dst)
-{
- _glamor_get_spans(drawable, wmax, points, widths, count, dst, TRUE);
-}
-
-Bool
-glamor_get_spans_nf(DrawablePtr drawable,
- int wmax,
- DDXPointPtr points, int *widths, int count, char *dst)
-{
- return _glamor_get_spans(drawable, wmax, points, widths, count, dst, FALSE);
-}
diff --git a/xorg-server/glamor/glamor_glyphblt.c b/xorg-server/glamor/glamor_glyphblt.c
index a58cef907..c031747f7 100644
--- a/xorg-server/glamor/glamor_glyphblt.c
+++ b/xorg-server/glamor/glamor_glyphblt.c
@@ -28,203 +28,156 @@
#include "glamor_priv.h"
#include <dixfontstr.h>
+#include "glamor_transform.h"
+
+static const glamor_facet glamor_facet_poly_glyph_blt = {
+ .name = "poly_glyph_blt",
+ .vs_vars = "attribute vec2 primitive;\n",
+ .vs_exec = (" vec2 pos = vec2(0,0);\n"
+ GLAMOR_POS(gl_Position, primitive)),
+};
static Bool
-glamor_poly_glyph_blt_pixels(DrawablePtr drawable, GCPtr gc,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci)
+glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
+ int start_x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void *pglyph_base)
{
ScreenPtr screen = drawable->pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv;
- int off_x, off_y;
- GLfloat xscale, yscale;
- float color[4];
- unsigned long fg_pixel = gc->fgPixel;
- char *vbo_offset;
- RegionPtr clip;
- int num_points, max_points;
- float *points = NULL;
-
- x += drawable->x;
- y += drawable->y;
-
- if (gc->fillStyle != FillSolid) {
- glamor_fallback("gc fillstyle not solid\n");
- return FALSE;
- }
+ glamor_program *prog;
+ RegionPtr clip = gc->pCompositeClip;
+ int box_x, box_y;
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- return FALSE;
+ goto bail;
glamor_get_context(glamor_priv);
- if (!glamor_set_alu(screen, gc->alu)) {
- if (gc->alu == GXclear)
- fg_pixel = 0;
- else {
- glamor_fallback("unsupported alu %x\n", gc->alu);
- glamor_put_context(glamor_priv);
- return FALSE;
- }
- }
-
- if (!glamor_set_planemask(pixmap, gc->planemask)) {
- glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
- glamor_put_context(glamor_priv);
- return FALSE;
- }
-
- glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
-
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
-
- glUseProgram(glamor_priv->solid_prog);
- glamor_get_rgba_from_pixel(fg_pixel,
- &color[0], &color[1], &color[2], &color[3],
- format_for_pixmap(pixmap));
- glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
-
- clip = fbGetCompositeClip(gc);
+ prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs,
+ &glamor_facet_poly_glyph_blt);
+ if (!prog)
+ goto bail_ctx;
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- max_points = 500;
- num_points = 0;
- while (nglyph--) {
- CharInfoPtr charinfo = *ppci++;
- int w = GLYPHWIDTHPIXELS(charinfo);
- int h = GLYPHHEIGHTPIXELS(charinfo);
- uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);
-
- if (w && h) {
- int glyph_x = x + charinfo->metrics.leftSideBearing;
- int glyph_y = y - charinfo->metrics.ascent;
- int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
- int xx, yy;
-
- for (yy = 0; yy < h; yy++) {
- uint8_t *glyph_row = glyphbits + glyph_stride * yy;
- for (xx = 0; xx < w; xx++) {
- int pt_x_i = glyph_x + xx;
- int pt_y_i = glyph_y + yy;
- float pt_x_f, pt_y_f;
- if (!(glyph_row[xx / 8] & (1 << xx % 8)))
- continue;
-
- if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL))
- continue;
-
- if (!num_points) {
- points = glamor_get_vbo_space(screen,
- max_points * 2 * sizeof(float),
- &vbo_offset);
-
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float),
- vbo_offset);
- }
-
- pt_x_f = v_from_x_coord_x(xscale, pt_x_i + off_x + 0.5);
- if (glamor_priv->yInverted)
- pt_y_f = v_from_x_coord_y_inverted(yscale, pt_y_i + off_y + 0.5);
- else
- pt_y_f = v_from_x_coord_y(yscale, pt_y_i + off_y + 0.5);
-
- points[num_points * 2 + 0] = pt_x_f;
- points[num_points * 2 + 1] = pt_y_f;
- num_points++;
+ start_x += drawable->x;
+ y += drawable->y;
- if (num_points == max_points) {
- glamor_put_vbo_space(screen);
- glDrawArrays(GL_POINTS, 0, num_points);
- num_points = 0;
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ int x;
+ int n;
+ int num_points, max_points;
+ INT16 *points = NULL;
+ int off_x, off_y;
+ char *vbo_offset;
+
+ glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y);
+
+ max_points = 500;
+ num_points = 0;
+ x = start_x;
+ for (n = 0; n < nglyph; n++) {
+ CharInfoPtr charinfo = ppci[n];
+ int w = GLYPHWIDTHPIXELS(charinfo);
+ int h = GLYPHHEIGHTPIXELS(charinfo);
+ uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);
+
+ if (w && h) {
+ int glyph_x = x + charinfo->metrics.leftSideBearing;
+ int glyph_y = y - charinfo->metrics.ascent;
+ int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
+ int xx, yy;
+
+ for (yy = 0; yy < h; yy++) {
+ uint8_t *glyph = glyphbits;
+ for (xx = 0; xx < w; glyph += ((xx&7) == 7), xx++) {
+ int pt_x_i = glyph_x + xx;
+ int pt_y_i = glyph_y + yy;
+
+ if (!(*glyph & (1 << (xx & 7))))
+ continue;
+
+ if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL))
+ continue;
+
+ if (!num_points) {
+ points = glamor_get_vbo_space(screen,
+ max_points * (2 * sizeof (INT16)),
+ &vbo_offset);
+
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
+ GL_FALSE, 0, vbo_offset);
+ }
+
+ *points++ = pt_x_i;
+ *points++ = pt_y_i;
+ num_points++;
+
+ if (num_points == max_points) {
+ glamor_put_vbo_space(screen);
+ glDrawArrays(GL_POINTS, 0, num_points);
+ num_points = 0;
+ }
}
+ glyphbits += glyph_stride;
}
}
+ x += charinfo->metrics.characterWidth;
}
- x += charinfo->metrics.characterWidth;
- }
-
- if (num_points) {
- glamor_put_vbo_space(screen);
- glDrawArrays(GL_POINTS, 0, num_points);
+ if (num_points) {
+ glamor_put_vbo_space(screen);
+ glDrawArrays(GL_POINTS, 0, num_points);
+ }
}
+ glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glamor_put_context(glamor_priv);
-
- return TRUE;
-}
-
-static Bool
-_glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyphBase, Bool fallback)
-{
- if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
- && glamor_ddx_fallback_check_gc(pGC))
- return FALSE;
-
- miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
return TRUE;
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+ glamor_put_context(glamor_priv);
+bail:
+ return FALSE;
}
void
-glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyphBase)
+glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc,
+ int start_x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void *pglyph_base)
{
- _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
- TRUE);
+ if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base))
+ return;
+ miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
+ ppci, pglyph_base);
}
Bool
-glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyphBase)
-{
- return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
- pglyphBase, FALSE);
-}
-
-static Bool
-_glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyphBase, Bool fallback)
+glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
+ int start_x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void *pglyph_base)
{
- if (glamor_poly_glyph_blt_pixels(pDrawable, pGC, x, y, nglyph, ppci))
+ if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base))
return TRUE;
-
- if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
- && glamor_ddx_fallback_check_gc(pGC))
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
return FALSE;
-
- miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
+ ppci, pglyph_base);
return TRUE;
}
-void
-glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyphBase)
-{
- _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
- TRUE);
-}
-
Bool
-glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyphBase)
+glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
+ int start_x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void *pglyph_base)
{
- return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
- pglyphBase, FALSE);
+ miImageGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base);
+ return TRUE;
}
static Bool
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 891ecdd37..a811f6015 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -283,8 +283,6 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format,
break;
default:
- LogMessageVerb(X_INFO, 0,
- "fail to get matched format for %x \n", format);
return -1;
}
return 0;
@@ -980,7 +978,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
&no_alpha,
&revert, &swap_rb, 1)) {
glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
- return TRUE;
+ return FALSE;
}
if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
return FALSE;
diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c
index 5399f96e8..0d58e555f 100644
--- a/xorg-server/glamor/glamor_points.c
+++ b/xorg-server/glamor/glamor_points.c
@@ -35,8 +35,8 @@ static const glamor_facet glamor_facet_point = {
.vs_exec = GLAMOR_POS(gl_Position, primitive),
};
-Bool
-glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt)
+static Bool
+glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt)
{
ScreenPtr screen = drawable->pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -123,7 +123,22 @@ void
glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt,
DDXPointPtr ppt)
{
- if (glamor_poly_point_nf(drawable, gc, mode, npt, ppt))
+ if (glamor_poly_point_gl(drawable, gc, mode, npt, ppt))
return;
miPolyPoint(drawable, gc, mode, npt, ppt);
}
+
+Bool
+glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ if (glamor_poly_point_gl(drawable, gc, mode, npt, ppt))
+ return TRUE;
+
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
+ return FALSE;
+
+ miPolyPoint(drawable, gc, mode, npt, ppt);
+ return TRUE;
+}
+
diff --git a/xorg-server/glamor/glamor_polyfillrect.c b/xorg-server/glamor/glamor_polyfillrect.c
deleted file mode 100644
index 1e361a44f..000000000
--- a/xorg-server/glamor/glamor_polyfillrect.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- * Copyright © 1998 Keith Packard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- *
- */
-
-#include "glamor_priv.h"
-
-/** @file glamor_fillspans.c
- *
- * GC PolyFillRect implementation, taken straight from fb_fill.c
- */
-
-static Bool
-_glamor_poly_fill_rect(DrawablePtr drawable,
- GCPtr gc, int nrect, xRectangle *prect, Bool fallback)
-{
- int fullX1, fullX2, fullY1, fullY2;
- int xorg, yorg;
- int n;
- register BoxPtr pbox;
- RegionPtr pClip = fbGetCompositeClip(gc);
- Bool ret = FALSE;
-
- xorg = drawable->x;
- yorg = drawable->y;
-
- while (nrect--) {
- fullX1 = prect->x + xorg;
- fullY1 = prect->y + yorg;
- fullX2 = fullX1 + (int) prect->width;
- fullY2 = fullY1 + (int) prect->height;
-
- n = REGION_NUM_RECTS(pClip);
- pbox = REGION_RECTS(pClip);
- /*
- * clip the rectangle to each box in the clip region
- * this is logically equivalent to calling Intersect(),
- * but rectangles may overlap each other here.
- */
- while (n--) {
- int x1 = fullX1;
- int x2 = fullX2;
- int y1 = fullY1;
- int y2 = fullY2;
-
- if (pbox->x1 > x1)
- x1 = pbox->x1;
- if (pbox->x2 < x2)
- x2 = pbox->x2;
- if (pbox->y1 > y1)
- y1 = pbox->y1;
- if (pbox->y2 < y2)
- y2 = pbox->y2;
-
- pbox++;
- if (x1 >= x2 || y1 >= y2)
- continue;
- if (!glamor_fill(drawable, gc, x1, y1, x2 - x1, y2 - y1, fallback)) {
- nrect++;
- goto fail;
- }
- }
- prect++;
- }
- ret = TRUE;
- goto done;
-
- fail:
-
- if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
- && glamor_ddx_fallback_check_gc(gc))
- goto done;
-
- glamor_fallback(" to %p (%c)\n",
- drawable, glamor_get_drawable_location(drawable));
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
- glamor_prepare_access_gc(gc)) {
- fbPolyFillRect(drawable, gc, nrect, prect);
- }
- glamor_finish_access_gc(gc);
- glamor_finish_access(drawable);
- ret = TRUE;
-
- done:
- return ret;
-}
-
-void
-glamor_poly_fill_rect(DrawablePtr drawable,
- GCPtr gc, int nrect, xRectangle *prect)
-{
- _glamor_poly_fill_rect(drawable, gc, nrect, prect, TRUE);
-}
-
-Bool
-glamor_poly_fill_rect_nf(DrawablePtr drawable,
- GCPtr gc, int nrect, xRectangle *prect)
-{
- return _glamor_poly_fill_rect(drawable, gc, nrect, prect, FALSE);
-}
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index 4c305abfc..0cafac4b5 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -205,6 +205,7 @@ typedef struct glamor_screen_private {
Bool yInverted;
unsigned int tick;
enum glamor_gl_flavor gl_flavor;
+ int glsl_version;
int has_pack_invert;
int has_fbo_blit;
int has_map_buffer_range;
@@ -223,6 +224,20 @@ typedef struct glamor_screen_private {
/* glamor point shader */
glamor_program point_prog;
+ /* glamor spans shaders */
+ glamor_program_fill fill_spans_program;
+
+ /* glamor rect shaders */
+ glamor_program_fill poly_fill_rect_program;
+
+ /* glamor glyphblt shaders */
+ glamor_program_fill poly_glyph_blt_progs;
+
+ /* glamor text shaders */
+ glamor_program_fill poly_text_progs;
+ glamor_program te_text_prog;
+ glamor_program image_text_prog;
+
/* vertext/elment_index buffer object for render */
GLuint vbo, ebo;
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
@@ -584,8 +599,6 @@ extern int glamor_debug_level;
/* glamor.c */
PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
-Bool glamor_destroy_pixmap(PixmapPtr pixmap);
-
glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private *
pixmap_priv);
void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
@@ -674,19 +687,9 @@ Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
Bool glamor_solid_boxes(PixmapPtr pixmap,
BoxPtr box, int nbox, unsigned long fg_pixel);
-/* glamor_fillspans.c */
-void glamor_fill_spans(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points, int *widths, int sorted);
-
void glamor_init_solid_shader(ScreenPtr screen);
void glamor_fini_solid_shader(ScreenPtr screen);
-/* glamor_getspans.c */
-void glamor_get_spans(DrawablePtr drawable,
- int wmax, DDXPointPtr points, int *widths,
- int nspans, char *dst_start);
-
/* glamor_glyphs.c */
Bool glamor_realize_glyph_caches(ScreenPtr screen);
void glamor_glyphs_fini(ScreenPtr screen);
@@ -697,14 +700,6 @@ void glamor_glyphs(CARD8 op,
INT16 xSrc,
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
-/* glamor_setspans.c */
-void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
- DDXPointPtr points, int *widths, int n, int sorted);
-
-/* glamor_polyfillrect.c */
-void glamor_poly_fill_rect(DrawablePtr drawable,
- GCPtr gc, int nrect, xRectangle *prect);
-
/* glamor_polylines.c */
void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
DDXPointPtr points);
@@ -967,6 +962,39 @@ RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int dstx, int dsty,
unsigned long bitPlane);
+/* glamor_text.c */
+int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char *chars);
+
+int glamor_poly_text16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars);
+
+void glamor_image_text8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char *chars);
+
+void glamor_image_text16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars);
+
+/* glamor_spans.c */
+void
+glamor_fill_spans(DrawablePtr drawable,
+ GCPtr gc,
+ int n, DDXPointPtr points, int *widths, int sorted);
+
+void
+glamor_get_spans(DrawablePtr drawable, int wmax,
+ DDXPointPtr points, int *widths, int count, char *dst);
+
+void
+glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+ DDXPointPtr points, int *widths, int numPoints, int sorted);
+
+/* glamor_rects.c */
+void
+glamor_poly_fill_rect(DrawablePtr drawable,
+ GCPtr gc, int nrect, xRectangle *prect);
+
+/* glamor_glyphblt.c */
void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, void *pglyphBase);
@@ -992,9 +1020,6 @@ void glamor_composite_rectangles(CARD8 op,
xRenderColor *color,
int num_rects, xRectangle *rects);
-extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
- struct glamor_context *glamor_ctx);
-
/* glamor_xv */
typedef struct {
uint32_t transform_index;
@@ -1039,4 +1064,6 @@ void glamor_fini_xv_shader(ScreenPtr screen);
//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
+#include "glamor_font.h"
+
#endif /* GLAMOR_PRIV_H */
diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c
index e2e1434ee..0f4d0f06a 100644
--- a/xorg-server/glamor/glamor_program.c
+++ b/xorg-server/glamor/glamor_program.c
@@ -45,9 +45,8 @@ use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_fill_tile = {
.name = "tile",
- .version = 130,
- .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n",
- .fs_exec = " gl_FragColor = texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0);\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
.locations = glamor_program_location_fill,
.use = use_tile,
};
@@ -108,6 +107,7 @@ static glamor_location_var location_vars[] = {
{
.location = glamor_program_location_fill,
.vs_vars = ("uniform vec2 fill_offset;\n"
+ "uniform vec2 fill_size;\n"
"varying vec2 fill_pos;\n"),
.fs_vars = ("uniform sampler2D sampler;\n"
"uniform vec2 fill_size;\n"
@@ -240,16 +240,8 @@ glamor_build_program(ScreenPtr screen,
flags |= fill->flags;
version = MAX(version, fill->version);
- if (version >= 130) {
-
- /* Would be nice to have a cleaner test for GLSL 1.30 support,
- * but for now this should suffice
- */
- if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP ||
- epoxy_gl_version() < 30) {
- goto fail;
- }
- }
+ if (version > glamor_priv->glsl_version)
+ goto fail;
vs_vars = vs_location_vars(locations);
fs_vars = fs_location_vars(locations);
diff --git a/xorg-server/glamor/glamor_rects.c b/xorg-server/glamor/glamor_rects.c
new file mode 100644
index 000000000..7731edec4
--- /dev/null
+++ b/xorg-server/glamor/glamor_rects.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_program.h"
+#include "glamor_transform.h"
+
+static const glamor_facet glamor_facet_polyfillrect_130 = {
+ .name = "poly_fill_rect",
+ .version = 130,
+ .vs_vars = "attribute vec4 primitive;\n",
+ .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+ GLAMOR_POS(gl_Position, (primitive.xy + pos))),
+};
+
+static const glamor_facet glamor_facet_polyfillrect_120 = {
+ .name = "poly_fill_rect",
+ .vs_vars = "attribute vec2 primitive;\n",
+ .vs_exec = (" vec2 pos = vec2(0,0);\n"
+ GLAMOR_POS(gl_Position, primitive.xy)),
+};
+
+static Bool
+glamor_poly_fill_rect_gl(DrawablePtr drawable,
+ GCPtr gc, int nrect, xRectangle *prect)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv;
+ glamor_program *prog;
+ int off_x, off_y;
+ GLshort *v;
+ char *vbo_offset;
+ int box_x, box_y;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ glamor_get_context(glamor_priv);
+
+ if (glamor_priv->glsl_version >= 130) {
+ prog = glamor_use_program_fill(pixmap, gc,
+ &glamor_priv->poly_fill_rect_program,
+ &glamor_facet_polyfillrect_130);
+
+ if (!prog)
+ goto bail_ctx;
+
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(drawable->pScreen, nrect * sizeof (xRectangle), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
+ 4 * sizeof (short), vbo_offset);
+
+ memcpy(v, prect, nrect * sizeof (xRectangle));
+
+ glamor_put_vbo_space(screen);
+ } else {
+ int n;
+
+ prog = glamor_use_program_fill(pixmap, gc,
+ &glamor_priv->poly_fill_rect_program,
+ &glamor_facet_polyfillrect_120);
+
+ if (!prog)
+ goto bail_ctx;
+
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(drawable->pScreen, nrect * 8 * sizeof (short), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
+ 2 * sizeof (short), vbo_offset);
+
+ for (n = 0; n < nrect; n++) {
+ v[0] = prect->x; v[1] = prect->y;
+ v[2] = prect->x; v[3] = prect->y + prect->height;
+ v[4] = prect->x + prect->width; v[5] = prect->y + prect->height;
+ v[6] = prect->x + prect->width; v[7] = prect->y;
+ prect++;
+ v += 8;
+ }
+
+ glamor_put_vbo_space(screen);
+ }
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ int nbox = RegionNumRects(gc->pCompositeClip);
+ BoxPtr box = RegionRects(gc->pCompositeClip);
+
+ glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+
+ while (nbox--) {
+ glScissor(box->x1 + off_x,
+ box->y1 + off_y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+ if (glamor_priv->glsl_version >= 130)
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
+ else {
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ glDrawArrays(GL_QUADS, 0, nrect * 4);
+ } else {
+ int i;
+ for (i = 0; i < nrect; i++) {
+ glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+ }
+ }
+ }
+ }
+ }
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_COLOR_LOGIC_OP);
+ if (glamor_priv->glsl_version >= 130)
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ glamor_put_context(glamor_priv);
+ return TRUE;
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+ glamor_put_context(glamor_priv);
+bail:
+ return FALSE;
+}
+
+static void
+glamor_poly_fill_rect_bail(DrawablePtr drawable,
+ GCPtr gc, int nrect, xRectangle *prect)
+{
+ glamor_fallback("to %p (%c)\n", drawable,
+ glamor_get_drawable_location(drawable));
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_gc(gc)) {
+ fbPolyFillRect(drawable, gc, nrect, prect);
+ }
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
+}
+
+void
+glamor_poly_fill_rect(DrawablePtr drawable,
+ GCPtr gc, int nrect, xRectangle *prect)
+{
+ if (glamor_poly_fill_rect_gl(drawable, gc, nrect, prect))
+ return;
+ glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
+}
+
+Bool
+glamor_poly_fill_rect_nf(DrawablePtr drawable,
+ GCPtr gc, int nrect, xRectangle *prect)
+{
+ if (glamor_poly_fill_rect_gl(drawable, gc, nrect, prect))
+ return TRUE;
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
+ return FALSE;
+ glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
+ return TRUE;
+}
diff --git a/xorg-server/glamor/glamor_setspans.c b/xorg-server/glamor/glamor_setspans.c
deleted file mode 100644
index a51e4c5be..000000000
--- a/xorg-server/glamor/glamor_setspans.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- * Zhigang Gong <zhigang.gong@linux.intel.com>
- *
- */
-
-#include "glamor_priv.h"
-
-static Bool
-_glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
- DDXPointPtr points, int *widths, int numPoints, int sorted,
- Bool fallback)
-{
- PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *dest_pixmap_priv;
- int i;
- uint8_t *drawpixels_src = (uint8_t *) src;
- RegionPtr clip = fbGetCompositeClip(gc);
- BoxRec *pbox;
- int x_off, y_off;
- Bool ret = FALSE;
-
- dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
- glamor_fallback("pixmap has no fbo.\n");
- goto fail;
- }
-
- if (gc->alu != GXcopy) {
- glamor_fallback("SetSpans with non-copy ALU.\n");
- goto fail;
- }
-
- if (!glamor_set_planemask(dest_pixmap, gc->planemask))
- goto fail;
-
- glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
- for (i = 0; i < numPoints; i++) {
-
- int n = REGION_NUM_RECTS(clip);
-
- pbox = REGION_RECTS(clip);
- while (n--) {
- int x1 = points[i].x;
- int x2 = x1 + widths[i];
- int y1 = points[i].y;
-
- if (pbox->y1 > points[i].y || pbox->y2 < points[i].y)
- break;
- x1 = x1 > pbox->x1 ? x1 : pbox->x1;
- x2 = x2 < pbox->x2 ? x2 : pbox->x2;
- if (x1 >= x2)
- continue;
- glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off,
- y1 + y_off, x2 - x1, 1,
- PixmapBytePad(widths[i],
- drawable->depth),
- drawpixels_src, 0);
- }
- drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
- }
- ret = TRUE;
- goto done;
-
- fail:
- if (!fallback && glamor_ddx_fallback_check_pixmap(drawable))
- goto done;
-
- glamor_fallback("to %p (%c)\n",
- drawable, glamor_get_drawable_location(drawable));
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
- glamor_prepare_access_gc(gc)) {
- fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
- }
- glamor_finish_access_gc(gc);
- glamor_finish_access(drawable);
- ret = TRUE;
-
- done:
- return ret;
-}
-
-void
-glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
- DDXPointPtr points, int *widths, int n, int sorted)
-{
- _glamor_set_spans(drawable, gc, src, points, widths, n, sorted, TRUE);
-}
-
-Bool
-glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
- DDXPointPtr points, int *widths, int n, int sorted)
-{
- return _glamor_set_spans(drawable, gc, src, points,
- widths, n, sorted, FALSE);
-}
diff --git a/xorg-server/glamor/glamor_spans.c b/xorg-server/glamor/glamor_spans.c
new file mode 100644
index 000000000..98842cdde
--- /dev/null
+++ b/xorg-server/glamor/glamor_spans.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_transform.h"
+#include "glamor_transfer.h"
+
+glamor_program fill_spans_progs[4];
+
+static const glamor_facet glamor_facet_fillspans_130 = {
+ .name = "fill_spans",
+ .version = 130,
+ .vs_vars = "attribute vec3 primitive;\n",
+ .vs_exec = (" vec2 pos = vec2(primitive.z,1) * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+ GLAMOR_POS(gl_Position, (primitive.xy + pos))),
+};
+
+static const glamor_facet glamor_facet_fillspans_120 = {
+ .name = "fill_spans",
+ .vs_vars = "attribute vec2 primitive;\n",
+ .vs_exec = (" vec2 pos = vec2(0,0);\n"
+ GLAMOR_POS(gl_Position, primitive.xy)),
+};
+
+static Bool
+glamor_fill_spans_gl(DrawablePtr drawable,
+ GCPtr gc,
+ int n, DDXPointPtr points, int *widths, int sorted)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv;
+ glamor_program *prog;
+ int off_x, off_y;
+ GLshort *v;
+ char *vbo_offset;
+ int c;
+ int box_x, box_y;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ glamor_get_context(glamor_priv);
+
+ if (glamor_priv->glsl_version >= 130) {
+ prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
+ &glamor_facet_fillspans_130);
+
+ if (!prog)
+ goto bail_ctx;
+
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(drawable->pScreen, n * (4 * sizeof (GLshort)), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
+ 4 * sizeof (GLshort), vbo_offset);
+
+ for (c = 0; c < n; c++) {
+ v[0] = points->x;
+ v[1] = points->y;
+ v[2] = *widths++;
+ points++;
+ v += 4;
+ }
+
+ glamor_put_vbo_space(screen);
+ } else {
+ prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
+ &glamor_facet_fillspans_120);
+
+ if (!prog)
+ goto bail_ctx;
+
+ /* Set up the vertex buffers for the points */
+
+ v = glamor_get_vbo_space(drawable->pScreen, n * 8 * sizeof (short), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
+ 2 * sizeof (short), vbo_offset);
+
+ for (c = 0; c < n; c++) {
+ v[0] = points->x; v[1] = points->y;
+ v[2] = points->x; v[3] = points->y + 1;
+ v[4] = points->x + *widths; v[5] = points->y + 1;
+ v[6] = points->x + *widths; v[7] = points->y;
+
+ widths++;
+ points++;
+ v += 8;
+ }
+
+ glamor_put_vbo_space(screen);
+ }
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ int nbox = RegionNumRects(gc->pCompositeClip);
+ BoxPtr box = RegionRects(gc->pCompositeClip);
+
+ glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+
+ while (nbox--) {
+ glScissor(box->x1 + off_x,
+ box->y1 + off_y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+ if (glamor_priv->glsl_version >= 130)
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
+ else {
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ glDrawArrays(GL_QUADS, 0, 4 * n);
+ } else {
+ int i;
+ for (i = 0; i < n; i++) {
+ glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+ }
+ }
+ }
+ }
+ }
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_COLOR_LOGIC_OP);
+ if (glamor_priv->glsl_version >= 130)
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ glamor_put_context(glamor_priv);
+ return TRUE;
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+ glamor_put_context(glamor_priv);
+bail:
+ return FALSE;
+}
+
+static void
+glamor_fill_spans_bail(DrawablePtr drawable,
+ GCPtr gc,
+ int n, DDXPointPtr points, int *widths, int sorted)
+{
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_gc(gc)) {
+ fbFillSpans(drawable, gc, n, points, widths, sorted);
+ }
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
+}
+
+void
+glamor_fill_spans(DrawablePtr drawable,
+ GCPtr gc,
+ int n, DDXPointPtr points, int *widths, int sorted)
+{
+ if (glamor_fill_spans_gl(drawable, gc, n, points, widths, sorted))
+ return;
+ glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
+}
+
+Bool
+glamor_fill_spans_nf(DrawablePtr drawable,
+ GCPtr gc,
+ int n, DDXPointPtr points, int *widths, int sorted)
+{
+ if (glamor_fill_spans_gl(drawable, gc, n, points, widths, sorted))
+ return TRUE;
+
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
+ return FALSE;
+
+ glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
+ return TRUE;
+}
+
+static Bool
+glamor_get_spans_gl(DrawablePtr drawable, int wmax,
+ DDXPointPtr points, int *widths, int count, char *dst)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv;
+ int box_x, box_y;
+ int n;
+ char *d;
+ GLenum type;
+ GLenum format;
+ int off_x, off_y;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+ glamor_format_for_pixmap(pixmap, &format, &type);
+
+ glamor_get_context(glamor_priv);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+
+ d = dst;
+ for (n = 0; n < count; n++) {
+ int x1 = points[n].x + off_x;
+ int y = points[n].y + off_y;
+ int w = widths[n];
+ int x2 = x1 + w;
+ char *l;
+
+ l = d;
+ d += PixmapBytePad(w, drawable->depth);
+
+ /* clip */
+ if (x1 < box->x1) {
+ l += (box->x1 - x1) * (drawable->bitsPerPixel >> 3);
+ x1 = box->x1;
+ }
+ if (x2 > box->x2)
+ x2 = box->x2;
+
+ if (x1 >= x2)
+ continue;
+ if (y < box->y1)
+ continue;
+ if (y >= box->y2)
+ continue;
+
+ glReadPixels(x1 - box->x1, y - box->y1, x2 - x1, 1, format, type, l);
+ }
+ }
+
+ glamor_put_context(glamor_priv);
+ return TRUE;
+bail:
+ return FALSE;
+}
+
+static void
+glamor_get_spans_bail(DrawablePtr drawable, int wmax,
+ DDXPointPtr points, int *widths, int count, char *dst)
+{
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO))
+ fbGetSpans(drawable, wmax, points, widths, count, dst);
+ glamor_finish_access(drawable);
+}
+
+void
+glamor_get_spans(DrawablePtr drawable, int wmax,
+ DDXPointPtr points, int *widths, int count, char *dst)
+{
+ if (glamor_get_spans_gl(drawable, wmax, points, widths, count, dst))
+ return;
+ glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
+}
+
+Bool
+glamor_get_spans_nf(DrawablePtr drawable, int wmax,
+ DDXPointPtr points, int *widths, int count, char *dst)
+{
+ if (glamor_get_spans_gl(drawable, wmax, points, widths, count, dst))
+ return TRUE;
+
+ if (glamor_ddx_fallback_check_pixmap(drawable))
+ return FALSE;
+
+ glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
+ return TRUE;
+}
+
+static Bool
+glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
+ DDXPointPtr points, int *widths, int numPoints, int sorted)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv;
+ int box_x, box_y;
+ int n;
+ char *s;
+ GLenum type;
+ GLenum format;
+ int off_x, off_y;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ if (gc->alu != GXcopy)
+ goto bail;
+
+ if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
+ goto bail;
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+ glamor_format_for_pixmap(pixmap, &format, &type);
+
+ glamor_get_context(glamor_priv);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, fbo->tex);
+
+ s = src;
+ for (n = 0; n < numPoints; n++) {
+
+ BoxPtr clip_box = RegionRects(gc->pCompositeClip);
+ int nclip_box = RegionNumRects(gc->pCompositeClip);
+ int w = widths[n];
+ int y = points[n].y;
+ int x = points[n].x;
+
+ while (nclip_box--) {
+ int x1 = x;
+ int x2 = x + w;
+ int y1 = y;
+ char *l = s;
+
+ /* clip to composite clip */
+ if (x1 < clip_box->x1) {
+ l += (clip_box->x1 - x1) * (drawable->bitsPerPixel >> 3);
+ x1 = clip_box->x1;
+ }
+ if (x2 > clip_box->x2)
+ x2 = clip_box->x2;
+
+ if (y < clip_box->y1)
+ continue;
+ if (y >= clip_box->y2)
+ continue;
+
+ /* adjust to pixmap coordinates */
+ x1 += off_x;
+ x2 += off_x;
+ y1 += off_y;
+
+ if (x1 < box->x1) {
+ l += (box->x1 - x1) * (drawable->bitsPerPixel >> 3);
+ x1 = box->x1;
+ }
+ if (x2 > box->x2)
+ x2 = box->x2;
+
+ if (x1 >= x2)
+ continue;
+ if (y1 < box->y1)
+ continue;
+ if (y1 >= box->y2)
+ continue;
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ x1 - box->x1, y1 - box->y1, x2 - x1, 1,
+ format, type,
+ l);
+ }
+ s += PixmapBytePad(w, drawable->depth);
+ }
+ }
+
+ glamor_put_context(glamor_priv);
+ return TRUE;
+
+bail:
+ return FALSE;
+}
+
+static void
+glamor_set_spans_bail(DrawablePtr drawable, GCPtr gc, char *src,
+ DDXPointPtr points, int *widths, int numPoints, int sorted)
+{
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc))
+ fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
+}
+
+void
+glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+ DDXPointPtr points, int *widths, int numPoints, int sorted)
+{
+ if (glamor_set_spans_gl(drawable, gc, src, points, widths, numPoints, sorted))
+ return;
+ glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
+}
+
+Bool
+glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
+ DDXPointPtr points, int *widths, int numPoints, int sorted)
+{
+ if (glamor_set_spans_gl(drawable, gc, src, points, widths, numPoints, sorted))
+ return TRUE;
+
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
+ return FALSE;
+
+ glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
+ return TRUE;
+}
diff --git a/xorg-server/glamor/glamor_text.c b/xorg-server/glamor/glamor_text.c
new file mode 100644
index 000000000..0e4b74c56
--- /dev/null
+++ b/xorg-server/glamor/glamor_text.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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.
+ */
+
+#include "glamor_priv.h"
+#include <dixfontstr.h>
+#include "glamor_transform.h"
+
+/*
+ * Fill in the array of charinfo pointers for the provided characters. For
+ * missing characters, place a NULL in the array so that the charinfo array
+ * aligns exactly with chars
+ */
+
+static void
+glamor_get_glyphs(FontPtr font, glamor_font_t *glamor_font,
+ int count, char *chars, Bool sixteen, CharInfoPtr *charinfo)
+{
+ unsigned long nglyphs;
+ FontEncoding encoding;
+ int char_step;
+
+ if (sixteen) {
+ char_step = 2;
+ if (FONTLASTROW(font) == 0)
+ encoding = Linear16Bit;
+ else
+ encoding = TwoD16Bit;
+ } else {
+ char_step = 1;
+ encoding = Linear8Bit;
+ }
+
+ /* If the font has a default character, then we don't have to
+ * worry about missing glyphs, so just get the whole string all at
+ * once. Otherwise, we have to fetch chars one at a time to notice
+ * missing ones.
+ */
+ if (glamor_font->default_char) {
+ GetGlyphs(font, (unsigned long) count, (unsigned char *) chars,
+ encoding, &nglyphs, charinfo);
+ } else {
+ int c;
+ for (c = 0; c < count; c++) {
+ GetGlyphs(font, 1, (unsigned char *) chars,
+ encoding, &nglyphs, &charinfo[c]);
+ if (!nglyphs)
+ charinfo[c] = NULL;
+ chars += char_step;
+ }
+ }
+}
+
+/*
+ * Construct quads for the provided list of characters and draw them
+ */
+
+static int
+glamor_text(DrawablePtr drawable, GCPtr gc,
+ glamor_font_t *glamor_font,
+ glamor_program *prog,
+ int x, int y,
+ int count, char *s_chars, CharInfoPtr *charinfo,
+ Bool sixteen)
+{
+ unsigned char *chars = (unsigned char *) s_chars;
+ FontPtr font = gc->font;
+ int off_x, off_y;
+ int c;
+ int nglyph;
+ GLshort *v;
+ char *vbo_offset;
+ CharInfoPtr ci;
+ int firstRow = font->info.firstRow;
+ int firstCol = font->info.firstCol;
+ int glyph_spacing_x = glamor_font->glyph_width_bytes * 8;
+ int glyph_spacing_y = glamor_font->glyph_height;
+ int box_x, box_y;
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+ /* Set the font as texture 1 */
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id);
+ glUniform1i(prog->font_uniform, 1);
+
+ /* Set up the vertex buffers for the font and destination */
+
+ v = glamor_get_vbo_space(drawable->pScreen, count * (6 * sizeof (GLshort)), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
+ 6 * sizeof (GLshort), vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1);
+ glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
+ 6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort));
+
+ /* Set the vertex coordinates */
+ nglyph = 0;
+
+ for (c = 0; c < count; c++) {
+ if ((ci = *charinfo++)) {
+ int x1 = x + ci->metrics.leftSideBearing;
+ int y1 = y - ci->metrics.ascent;
+ int width = GLYPHWIDTHPIXELS(ci);
+ int height = GLYPHHEIGHTPIXELS(ci);
+ int tx, ty = 0;
+ int row = 0, col;
+
+ x += ci->metrics.characterWidth;
+
+ if (sixteen) {
+ if (ci == glamor_font->default_char) {
+ row = glamor_font->default_row;
+ col = glamor_font->default_col;
+ } else {
+ row = chars[0];
+ col = chars[1];
+ }
+ if (FONTLASTROW(font) != 0)
+ ty = (row - firstRow) * glyph_spacing_y;
+ else
+ col += row << 8;
+ } else {
+ if (ci == glamor_font->default_char)
+ col = glamor_font->default_col;
+ else
+ col = chars[0];
+ }
+
+ tx = (col - firstCol) * glyph_spacing_x;
+
+ v[ 0] = x1;
+ v[ 1] = y1;
+ v[ 2] = width;
+ v[ 3] = height;
+ v[ 4] = tx;
+ v[ 5] = ty;
+
+ v += 6;
+ nglyph++;
+ }
+ chars += 1 + sixteen;
+ }
+ glamor_put_vbo_space(drawable->pScreen);
+
+ if (nglyph != 0) {
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ BoxPtr box = RegionRects(gc->pCompositeClip);
+ int nbox = RegionNumRects(gc->pCompositeClip);
+
+ glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+
+ /* Run over the clip list, drawing the glyphs
+ * in each box
+ */
+
+ while (nbox--) {
+ glScissor(box->x1 + off_x,
+ box->y1 + off_y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
+ }
+ }
+ glDisable(GL_SCISSOR_TEST);
+ }
+
+ glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glDisable(GL_COLOR_LOGIC_OP);
+
+ return x;
+}
+
+static const char vs_vars_text[] =
+ "attribute vec4 primitive;\n"
+ "attribute vec2 source;\n"
+ "varying vec2 glyph_pos;\n";
+
+static const char vs_exec_text[] =
+ " vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+ GLAMOR_POS(gl_Position, (primitive.xy + pos))
+ " glyph_pos = source + pos;\n";
+
+static const char fs_vars_text[] =
+ "varying vec2 glyph_pos;\n";
+
+static const char fs_exec_text[] =
+ " ivec2 itile_texture = ivec2(glyph_pos);\n"
+ " uint x = uint(itile_texture.x & 7);\n"
+ " itile_texture.x >>= 3;\n"
+ " uint texel = texelFetch(font, itile_texture, 0).x;\n"
+ " uint bit = (texel >> x) & uint(1);\n"
+ " if (bit == uint(0))\n"
+ " discard;\n";
+
+static const char fs_exec_te[] =
+ " ivec2 itile_texture = ivec2(glyph_pos);\n"
+ " uint x = uint(itile_texture.x & 7);\n"
+ " itile_texture.x >>= 3;\n"
+ " uint texel = texelFetch(font, itile_texture, 0).x;\n"
+ " uint bit = (texel >> x) & uint(1);\n"
+ " if (bit == uint(0))\n"
+ " gl_FragColor = bg;\n"
+ " else\n"
+ " gl_FragColor = fg;\n";
+
+static const glamor_facet glamor_facet_poly_text = {
+ .name = "poly_text",
+ .version = 130,
+ .vs_vars = vs_vars_text,
+ .vs_exec = vs_exec_text,
+ .fs_vars = fs_vars_text,
+ .fs_exec = fs_exec_text,
+ .source_name = "source",
+ .locations = glamor_program_location_font,
+};
+
+static Bool
+glamor_poly_text(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars, Bool sixteen, int *final_pos)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_program *prog;
+ glamor_pixmap_private *pixmap_priv;
+ glamor_font_t *glamor_font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ glamor_font = glamor_font_get(drawable->pScreen, gc->font);
+ if (!glamor_font)
+ goto bail;
+
+ glamor_get_glyphs(gc->font, glamor_font, count, chars, sixteen, charinfo);
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ glamor_get_context(glamor_priv);
+
+ prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_text_progs, &glamor_facet_poly_text);
+
+ if (!prog)
+ goto bail_ctx;
+
+ x = glamor_text(drawable, gc, glamor_font, prog,
+ x, y, count, chars, charinfo, sixteen);
+
+ glDisable(GL_COLOR_LOGIC_OP);
+
+ glamor_put_context(glamor_priv);
+
+ glamor_priv->state = RENDER_STATE;
+ glamor_priv->render_idle_cnt = 0;
+
+ *final_pos = x;
+ return TRUE;
+
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+ glamor_put_context(glamor_priv);
+bail:
+ return FALSE;
+}
+
+Bool
+glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars, int *final_pos)
+{
+ if (glamor_poly_text(drawable, gc, x, y, count, chars, FALSE, final_pos))
+ return TRUE;
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
+ return FALSE;
+ *final_pos = miPolyText8(drawable, gc, x, y, count, chars);
+ return TRUE;
+}
+
+int
+glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars)
+{
+ int final_pos;
+
+ if (glamor_poly_text(drawable, gc, x, y, count, chars, FALSE, &final_pos))
+ return final_pos;
+ return miPolyText8(drawable, gc, x, y, count, chars);
+}
+
+Bool
+glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, unsigned short *chars, int *final_pos)
+{
+ if (glamor_poly_text(drawable, gc, x, y, count, (char *) chars, TRUE, final_pos))
+ return TRUE;
+
+ if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
+ return FALSE;
+ *final_pos = miPolyText16(drawable, gc, x, y, count, chars);
+ return TRUE;
+}
+
+int
+glamor_poly_text16(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, unsigned short *chars)
+{
+ int final_pos;
+
+ if (glamor_poly_text(drawable, gc, x, y, count, (char *) chars, TRUE, &final_pos))
+ return final_pos;
+ return miPolyText16(drawable, gc, x, y, count, chars);
+}
+
+/*
+ * Draw image text, which is always solid in copy mode and has the
+ * background cleared while painting the text. For fonts which have
+ * their bitmap metrics exactly equal to the area to clear, we can use
+ * the accelerated version which paints both fg and bg at the same
+ * time. Otherwise, clear the whole area and then paint the glyphs on
+ * top
+ */
+
+static const glamor_facet glamor_facet_image_text = {
+ .name = "image_text",
+ .version = 130,
+ .vs_vars = vs_vars_text,
+ .vs_exec = vs_exec_text,
+ .fs_vars = fs_vars_text,
+ .fs_exec = fs_exec_text,
+ .source_name = "source",
+ .locations = glamor_program_location_font,
+};
+
+static Bool
+use_image_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
+{
+ return glamor_set_solid(pixmap, gc, FALSE, prog->fg_uniform);
+}
+
+static const glamor_facet glamor_facet_image_fill = {
+ .name = "solid",
+ .fs_exec = " gl_FragColor = fg;\n",
+ .locations = glamor_program_location_fg,
+ .use = use_image_solid,
+};
+
+static Bool
+glamor_te_text_use(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
+{
+ if (!glamor_set_solid(pixmap, gc, FALSE, prog->fg_uniform))
+ return FALSE;
+ glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
+ return TRUE;
+}
+
+static const glamor_facet glamor_facet_te_text = {
+ .name = "te_text",
+ .version = 130,
+ .vs_vars = vs_vars_text,
+ .vs_exec = vs_exec_text,
+ .fs_vars = fs_vars_text,
+ .fs_exec = fs_exec_te,
+ .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_font,
+ .source_name = "source",
+ .use = glamor_te_text_use,
+};
+
+static Bool
+glamor_image_text(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars,
+ Bool sixteen)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_program *prog;
+ glamor_pixmap_private *pixmap_priv;
+ glamor_font_t *glamor_font;
+ const glamor_facet *prim_facet;
+ const glamor_facet *fill_facet;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return FALSE;
+
+ glamor_font = glamor_font_get(drawable->pScreen, gc->font);
+ if (!glamor_font)
+ return FALSE;
+
+ glamor_get_glyphs(gc->font, glamor_font, count, chars, sixteen, charinfo);
+
+ glamor_get_context(glamor_priv);
+
+ if (TERMINALFONT(gc->font))
+ prog = &glamor_priv->te_text_prog;
+ else
+ prog = &glamor_priv->image_text_prog;
+
+ if (prog->failed)
+ goto bail;
+
+ if (!prog->prog) {
+ if (TERMINALFONT(gc->font)) {
+ prim_facet = &glamor_facet_te_text;
+ fill_facet = NULL;
+ } else {
+ prim_facet = &glamor_facet_image_text;
+ fill_facet = &glamor_facet_image_fill;
+ }
+
+ if (!glamor_build_program(screen, prog, prim_facet, fill_facet))
+ goto bail;
+ }
+
+ if (!TERMINALFONT(gc->font)) {
+ int width = 0;
+ int c;
+ RegionRec region;
+ BoxRec box;
+ int off_x, off_y;
+
+ /* Check planemask before drawing background to
+ * bail early if it's not OK
+ */
+ if (!glamor_set_planemask(pixmap, gc->planemask))
+ goto bail;
+ for (c = 0; c < count; c++)
+ if (charinfo[c])
+ width += charinfo[c]->metrics.characterWidth;
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+ if (width >= 0) {
+ box.x1 = off_x + drawable->x + x;
+ box.x2 = off_x + drawable->x + x + width;
+ } else {
+ box.x1 = off_x + drawable->x + x + width;
+ box.x2 = off_x + drawable->x + x;
+ }
+ box.y1 = off_y + drawable->y + y - gc->font->info.fontAscent;
+ box.y2 = off_y + drawable->y + y + gc->font->info.fontDescent;
+ RegionInit(&region, &box, 1);
+ RegionIntersect(&region, &region, gc->pCompositeClip);
+ glamor_solid_boxes(pixmap, RegionRects(&region), RegionNumRects(&region), gc->bgPixel);
+ RegionUninit(&region);
+ }
+
+ if (!glamor_use_program(pixmap, gc, prog, NULL))
+ goto bail;
+
+ (void) glamor_text(drawable, gc, glamor_font, prog,
+ x, y, count, chars, charinfo, sixteen);
+
+ glamor_put_context(glamor_priv);
+
+ glamor_priv->state = RENDER_STATE;
+ glamor_priv->render_idle_cnt = 0;
+
+ return TRUE;
+
+bail:
+ glDisable(GL_COLOR_LOGIC_OP);
+ glamor_put_context(glamor_priv);
+ return FALSE;
+}
+
+Bool
+glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars)
+{
+ return glamor_image_text(drawable, gc, x, y, count, chars, FALSE);
+}
+
+void
+glamor_image_text8(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, char *chars)
+{
+ if (!glamor_image_text(drawable, gc, x, y, count, chars, FALSE))
+ miImageText8(drawable, gc, x, y, count, chars);
+}
+
+Bool
+glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, unsigned short *chars)
+{
+ return glamor_image_text(drawable, gc, x, y, count, (char *) chars, FALSE);
+}
+
+void
+glamor_image_text16(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int count, unsigned short *chars)
+{
+ if (!glamor_image_text(drawable, gc, x, y, count, (char *) chars, TRUE))
+ miImageText16(drawable, gc, x, y, count, chars);
+}
diff --git a/xorg-server/glamor/glamor_transfer.c b/xorg-server/glamor/glamor_transfer.c
new file mode 100644
index 000000000..0378bb076
--- /dev/null
+++ b/xorg-server/glamor/glamor_transfer.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_transfer.h"
+
+/* XXX a kludge for now */
+void
+glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
+{
+ switch (pixmap->drawable.depth) {
+ case 24:
+ case 32:
+ *format = GL_BGRA;
+ *type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ case 16:
+ *format = GL_RGB;
+ *type = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+ case 15:
+ *format = GL_BGRA;
+ *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ break;
+ case 8:
+ *format = GL_ALPHA;
+ *type = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ FatalError("Invalid pixmap depth %d\n", pixmap->drawable.depth);
+ break;
+ }
+}
+
+/*
+ * Write a region of bits into a pixmap
+ */
+void
+glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src,
+ int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+ int box_x, box_y;
+ int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
+ GLenum type;
+ GLenum format;
+
+ glamor_format_for_pixmap(pixmap, &format, &type);
+
+ glamor_get_context(glamor_priv);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+
+ glamor_pixmap_loop(priv, box_x, box_y) {
+ BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+ BoxPtr boxes = in_boxes;
+ int nbox = in_nbox;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, fbo->tex);
+
+ while (nbox--) {
+
+ /* compute drawable coordinates */
+ int x1 = boxes->x1 + dx_dst;
+ int x2 = boxes->x2 + dx_dst;
+ int y1 = boxes->y1 + dy_dst;
+ int y2 = boxes->y2 + dy_dst;
+
+ boxes++;
+
+ if (x1 < box->x1)
+ x1 = box->x1;
+ if (box->x2 < x2)
+ x2 = box->x2;
+
+ if (x2 <= x1)
+ continue;
+
+ if (y1 < box->y1)
+ y1 = box->y1;
+ if (box->y2 < y2)
+ y2 = box->y2;
+
+ if (y2 <= y1)
+ continue;
+
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1 - dx_dst + dx_src);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ x1 - box->x1, y1 - box->y1,
+ x2 - x1, y2 - y1,
+ format, type,
+ bits);
+ }
+ }
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glamor_put_context(glamor_priv);
+}
+
+/*
+ * Upload a region of data
+ */
+
+void
+glamor_upload_region(PixmapPtr pixmap, RegionPtr region,
+ int region_x, int region_y,
+ uint8_t *bits, uint32_t byte_stride)
+{
+ glamor_upload_boxes(pixmap, RegionRects(region), RegionNumRects(region),
+ -region_x, -region_y,
+ 0, 0,
+ bits, byte_stride);
+}
+
+/*
+ * Take the data in the pixmap and stuff it back into the FBO
+ */
+void
+glamor_upload_pixmap(PixmapPtr pixmap)
+{
+ BoxRec box;
+
+ box.x1 = 0;
+ box.x2 = pixmap->drawable.width;
+ box.y1 = 0;
+ box.y2 = pixmap->drawable.height;
+ glamor_upload_boxes(pixmap, &box, 1, 0, 0, 0, 0,
+ pixmap->devPrivate.ptr, pixmap->devKind);
+}
+
+/*
+ * Read stuff from the pixmap FBOs and write to memory
+ */
+void
+glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src,
+ int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+ int box_x, box_y;
+ int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
+ GLenum type;
+ GLenum format;
+
+ glamor_format_for_pixmap(pixmap, &format, &type);
+
+ glamor_get_context(glamor_priv);
+
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+
+ glamor_pixmap_loop(priv, box_x, box_y) {
+ BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+ BoxPtr boxes = in_boxes;
+ int nbox = in_nbox;
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb);
+
+ while (nbox--) {
+
+ /* compute drawable coordinates */
+ int x1 = boxes->x1 + dx_src;
+ int x2 = boxes->x2 + dx_src;
+ int y1 = boxes->y1 + dy_src;
+ int y2 = boxes->y2 + dy_src;
+
+ boxes++;
+
+ if (x1 < box->x1)
+ x1 = box->x1;
+ if (box->x2 < x2)
+ x2 = box->x2;
+
+ if (y1 < box->y1)
+ y1 = box->y1;
+ if (box->y2 < y2)
+ y2 = box->y2;
+
+ if (x2 <= x1)
+ continue;
+ if (y2 <= y1)
+ continue;
+
+ glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
+ glPixelStorei(GL_PACK_SKIP_ROWS, y1 - dy_src + dy_dst);
+ glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits);
+ }
+ }
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ glamor_put_context(glamor_priv);
+}
+
+/*
+ * Read data from the pixmap FBO
+ */
+void
+glamor_download_rect(PixmapPtr pixmap, int x, int y, int w, int h, uint8_t *bits)
+{
+ BoxRec box;
+
+ box.x1 = x;
+ box.x2 = x + w;
+ box.y1 = y;
+ box.y2 = y + h;
+
+ glamor_download_boxes(pixmap, &box, 1, 0, 0, -x, -y,
+ bits, PixmapBytePad(w, pixmap->drawable.depth));
+}
+
+/*
+ * Pull the data from the FBO down to the pixmap
+ */
+void
+glamor_download_pixmap(PixmapPtr pixmap)
+{
+ BoxRec box;
+
+ box.x1 = 0;
+ box.x2 = pixmap->drawable.width;
+ box.y1 = 0;
+ box.y2 = pixmap->drawable.height;
+
+ glamor_download_boxes(pixmap, &box, 1, 0, 0, 0, 0,
+ pixmap->devPrivate.ptr, pixmap->devKind);
+}
diff --git a/xorg-server/glamor/glamor_transfer.h b/xorg-server/glamor/glamor_transfer.h
new file mode 100644
index 000000000..de8186a70
--- /dev/null
+++ b/xorg-server/glamor/glamor_transfer.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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 _GLAMOR_TRANSFER_H_
+#define _GLAMOR_TRANSFER_H_
+
+void
+glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type);
+
+void
+glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src,
+ int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride);
+
+void
+glamor_upload_region(PixmapPtr pixmap, RegionPtr region,
+ int region_x, int region_y,
+ uint8_t *bits, uint32_t byte_stride);
+
+void
+glamor_upload_pixmap(PixmapPtr pixmap);
+
+void
+glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src,
+ int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride);
+
+void
+glamor_download_rect(PixmapPtr pixmap, int x, int y, int w, int h, uint8_t *bits);
+
+void
+glamor_download_pixmap(PixmapPtr pixmap);
+
+#endif /* _GLAMOR_TRANSFER_H_ */
diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c
index 17745a4e8..4e60fa3a4 100644
--- a/xorg-server/glamor/glamor_xv.c
+++ b/xorg-server/glamor/glamor_xv.c
@@ -114,18 +114,6 @@ glamor_init_xv_shader(ScreenPtr screen)
glamor_put_context(glamor_priv);
}
-void
-glamor_fini_xv_shader(ScreenPtr screen)
-{
- glamor_screen_private *glamor_priv;
-
- glamor_priv = glamor_get_screen_private(screen);
- glamor_get_context(glamor_priv);
-
- glDeleteProgram(glamor_priv->xv_prog);
- glamor_put_context(glamor_priv);
-}
-
#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
@@ -559,6 +547,8 @@ glamor_xv_init(ScreenPtr screen, int num_texture_ports)
XF86VideoAdaptorPtr adapt;
int i;
+ glamor_init_xv_shader(screen);
+
adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
(sizeof(glamor_port_private) + sizeof(DevUnion)));
if (adapt == NULL)
diff --git a/xorg-server/hw/Makefile.am b/xorg-server/hw/Makefile.am
index 6c2cc6bd4..19895dc77 100644
--- a/xorg-server/hw/Makefile.am
+++ b/xorg-server/hw/Makefile.am
@@ -26,6 +26,10 @@ if XQUARTZ
XQUARTZ_SUBDIRS = xquartz
endif
+if XWAYLAND
+XWAYLAND_SUBDIRS = xwayland
+endif
+
SUBDIRS = \
$(XORG_SUBDIRS) \
$(XWIN_SUBDIRS) \
@@ -33,9 +37,10 @@ SUBDIRS = \
$(XNEST_SUBDIRS) \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
- $(XQUARTZ_SUBDIRS)
+ $(XQUARTZ_SUBDIRS) \
+ $(XWAYLAND_SUBDIRS)
-DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
+DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland
relink:
$(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done
diff --git a/xorg-server/hw/dmx/Makefile.am b/xorg-server/hw/dmx/Makefile.am
index a05af139e..eef84cb66 100644
--- a/xorg-server/hw/dmx/Makefile.am
+++ b/xorg-server/hw/dmx/Makefile.am
@@ -65,7 +65,6 @@ Xdmx_SOURCES = dmx.c \
dmxwindow.c \
dmxwindow.h \
$(top_srcdir)/mi/miinitext.c \
- $(top_srcdir)/fb/fbcmap_mi.c \
$(GLX_SRCS)
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
index 9903cc772..eaf565496 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -313,7 +313,6 @@ ephyr_glamor_get_visual(void)
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER, 1,
- GLX_VISUAL_ID, DefaultVisual(dpy, DefaultScreen(dpy)),
None
};
int event_base = 0, error_base = 0, nelements;
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index 4f48770a6..435919e0a 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -734,13 +734,16 @@ hostx_screen_init(KdScreenInfo *screen,
scrpriv->win_width = width;
scrpriv->win_height = height;
+#ifdef GLAMOR
if (ephyr_glamor) {
*bytes_per_line = 0;
*bits_per_pixel = 0;
ephyr_glamor_set_window_size(scrpriv->glamor,
scrpriv->win_width, scrpriv->win_height);
return NULL;
- } else if (host_depth_matches_server(scrpriv)) {
+ } else
+#endif
+ if (host_depth_matches_server(scrpriv)) {
*bytes_per_line = scrpriv->ximg->stride;
*bits_per_pixel = scrpriv->ximg->bpp;
diff --git a/xorg-server/hw/kdrive/src/Makefile.am b/xorg-server/hw/kdrive/src/Makefile.am
index 5799ddbdb..d69f0dd99 100644
--- a/xorg-server/hw/kdrive/src/Makefile.am
+++ b/xorg-server/hw/kdrive/src/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = \
AM_CFLAGS = -DHAVE_DIX_CONFIG_H
-noinst_LTLIBRARIES = libkdrive.la libkdrivestubs.la
+noinst_LTLIBRARIES = libkdrive.la
if XV
KDRIVE_XV_SOURCES = \
@@ -23,6 +23,3 @@ libkdrive_la_SOURCES = \
kshadow.c \
$(KDRIVE_XV_SOURCES) \
$(top_srcdir)/mi/miinitext.c
-
-libkdrivestubs_la_SOURCES = \
- $(top_srcdir)/fb/fbcmap_mi.c
diff --git a/xorg-server/hw/vfb/Makefile.am b/xorg-server/hw/vfb/Makefile.am
index 9f4992c8b..f0f9fee47 100644
--- a/xorg-server/hw/vfb/Makefile.am
+++ b/xorg-server/hw/vfb/Makefile.am
@@ -1,7 +1,6 @@
SUBDIRS = man
bin_PROGRAMS = Xvfb
-noinst_LIBRARIES = libfbcmap.a
AM_CFLAGS = -DHAVE_DIX_CONFIG_H \
$(XVFBMODULES_CFLAGS) \
@@ -9,20 +8,16 @@ AM_CFLAGS = -DHAVE_DIX_CONFIG_H \
SRCS = InitInput.c \
InitOutput.c \
- $(top_srcdir)/Xext/dpmsstubs.c \
- $(top_srcdir)/Xi/stubs.c \
$(top_srcdir)/mi/miinitext.c
-libfbcmap_a_CFLAGS = $(AM_CFLAGS)
-libfbcmap_a_SOURCES = $(top_srcdir)/fb/fbcmap_mi.c
-
Xvfb_SOURCES = $(SRCS)
XVFB_LIBS = \
@XVFB_LIBS@ \
- libfbcmap.a \
$(MAIN_LIB) \
- $(XSERVER_LIBS)
+ $(XSERVER_LIBS) \
+ $(top_builddir)/Xext/libXextdpmsstubs.la \
+ $(top_builddir)/Xi/libXistubs.la
Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
Xvfb_DEPENDENCIES = $(XVFB_LIBS)
diff --git a/xorg-server/hw/xfree86/.gitignore b/xorg-server/hw/xfree86/.gitignore
index 997a94efe..fb6830b2c 100644
--- a/xorg-server/hw/xfree86/.gitignore
+++ b/xorg-server/hw/xfree86/.gitignore
@@ -1,4 +1,5 @@
Xorg
+Xorg.sh
xorg.conf.example
sdksyms.c
sdksyms.dep
diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am
index 18fa99b08..c5992c372 100644
--- a/xorg-server/hw/xfree86/Makefile.am
+++ b/xorg-server/hw/xfree86/Makefile.am
@@ -89,7 +89,7 @@ endif
BUILT_SOURCES = xorg.conf.example
DISTCLEANFILES = xorg.conf.example
-EXTRA_DIST = xorgconf.cpp Xorg.sh.in
+EXTRA_DIST = xorgconf.cpp
# Without logdir, X will post an error on the terminal and will not start
install-data-local:
@@ -105,6 +105,7 @@ if INSTALL_SETUID
chmod u+s $(DESTDIR)$(bindir)/Xorg
endif
if SUID_WRAPPER
+ $(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR)
mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.bin
${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg
-chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index 06af73903..35a673d15 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -56,6 +56,7 @@
#include <X11/X.h>
#include <X11/Xpoll.h>
#include <X11/Xproto.h>
+#include <X11/Xatom.h>
#include "misc.h"
#include "compiler.h"
#include "xf86.h"
@@ -431,6 +432,29 @@ xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo)
pInfo->flags &= ~XI86_DEVICE_DISABLED;
}
+/*
+ * xf86UpdateHasVTProperty --
+ * Update a flag property on the root window to say whether the server VT
+ * is currently the active one as some clients need to know this.
+ */
+static void
+xf86UpdateHasVTProperty(Bool hasVT)
+{
+ Atom property_name;
+ int32_t value = hasVT ? 1 : 0;
+ int i;
+
+ property_name = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1,
+ FALSE);
+ if (property_name == BAD_RESOURCE)
+ FatalError("Failed to retrieve \"HAS_VT\" atom\n");
+ for (i = 0; i < xf86NumScreens; i++) {
+ ChangeWindowProperty(xf86ScrnToScreen(xf86Screens[i])->root,
+ property_name, XA_INTEGER, 32,
+ PropModeReplace, 1, &value, TRUE);
+ }
+}
+
void
xf86VTLeave(void)
{
@@ -490,6 +514,8 @@ xf86VTLeave(void)
if (xorgHWAccess)
xf86DisableIO();
+ xf86UpdateHasVTProperty(FALSE);
+
return;
switch_failed:
@@ -574,6 +600,8 @@ xf86VTEnter(void)
xf86platformVTProbe();
#endif
+ xf86UpdateHasVTProperty(TRUE);
+
OsReleaseSIGIO();
}
diff --git a/xorg-server/hw/xfree86/common/xf86Globals.c b/xorg-server/hw/xfree86/common/xf86Globals.c
index 7df7a80c4..984c39bca 100644
--- a/xorg-server/hw/xfree86/common/xf86Globals.c
+++ b/xorg-server/hw/xfree86/common/xf86Globals.c
@@ -143,7 +143,7 @@ const char *xf86ConfigFile = NULL;
const char *xf86ConfigDir = NULL;
const char *xf86ModulePath = DEFAULT_MODULE_PATH;
MessageType xf86ModPathFrom = X_DEFAULT;
-const char *xf86LogFile = DEFAULT_LOGPREFIX;
+const char *xf86LogFile = DEFAULT_LOGDIR "/" DEFAULT_LOGPREFIX;
MessageType xf86LogFileFrom = X_DEFAULT;
Bool xf86LogFileWasOpened = FALSE;
serverLayoutRec xf86ConfigLayout = { NULL, };
diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c
index 12a877159..e2b32a074 100644
--- a/xorg-server/hw/xfree86/common/xf86Helper.c
+++ b/xorg-server/hw/xfree86/common/xf86Helper.c
@@ -1217,16 +1217,45 @@ xf86ErrorF(const char *format, ...)
va_end(ap);
}
+/* Note temporarily modifies the passed in buffer! */
+static void xf86_mkdir_p(char *path)
+{
+ char *sep = path;
+
+ while ((sep = strchr(sep + 1, '/'))) {
+ *sep = 0;
+ (void)mkdir(path, 0777);
+ *sep = '/';
+ }
+ (void)mkdir(path, 0777);
+}
+
void
xf86LogInit(void)
{
- char *lf = NULL;
+ char *env, *lf = NULL;
+ char buf[PATH_MAX];
#define LOGSUFFIX ".log"
#define LOGOLDSUFFIX ".old"
/* Get the log file name */
if (xf86LogFileFrom == X_DEFAULT) {
+ /* When not running as root, we won't be able to write to /var/log */
+ if (geteuid() != 0) {
+ if ((env = getenv("XDG_DATA_HOME")))
+ snprintf(buf, sizeof(buf), "%s/%s", env,
+ DEFAULT_XDG_DATA_HOME_LOGDIR);
+ else if ((env = getenv("HOME")))
+ snprintf(buf, sizeof(buf), "%s/%s/%s", env,
+ DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR);
+
+ if (env) {
+ xf86_mkdir_p(buf);
+ strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf));
+ xf86LogFile = buf;
+ }
+ }
/* Append the display number and ".log" */
if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
FatalError("Cannot allocate space for the log file name\n");
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 4579ff591..5a45004f5 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -387,6 +387,11 @@ InstallSignalHandlers(void)
}
}
+/* The memory storing the initial value of the XFree86_has_VT root window
+ * property. This has to remain available until server start-up, so we just
+ * use a global. */
+static CARD32 HasVTValue = 1;
+
/*
* InitOutput --
* Initialize screenInfo for all actually accessible framebuffers.
@@ -731,7 +736,9 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
if (xf86Info.vtno >= 0) {
#define VT_ATOM_NAME "XFree86_VT"
Atom VTAtom = -1;
+ Atom HasVTAtom = -1;
CARD32 *VT = NULL;
+ CARD32 *HasVT = &HasVTValue;
int ret;
/* This memory needs to stay available until the screen has been
@@ -744,6 +751,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
*VT = xf86Info.vtno;
VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
+ HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME,
+ sizeof(HAS_VT_ATOM_NAME) - 1, TRUE);
for (i = 0, ret = Success; i < xf86NumScreens && ret == Success;
i++) {
@@ -751,9 +760,14 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
VTAtom, XA_INTEGER, 32, 1,
VT);
+ if (ret == Success)
+ ret = xf86RegisterRootWindowProperty(xf86Screens[i]
+ ->scrnIndex,
+ HasVTAtom, XA_INTEGER,
+ 32, 1, HasVT);
if (ret != Success)
xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
- "Failed to register VT property\n");
+ "Failed to register VT properties\n");
}
}
diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h
index e8c24f26c..62ac95d5a 100644
--- a/xorg-server/hw/xfree86/common/xf86Module.h
+++ b/xorg-server/hw/xfree86/common/xf86Module.h
@@ -80,7 +80,7 @@ typedef enum {
* mask is 0xFFFF0000.
*/
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
-#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(16, 0)
+#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(17, 0)
#define ABI_XINPUT_VERSION SET_ABI_VERSION(21, 0)
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(8, 0)
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
diff --git a/xorg-server/hw/xfree86/common/xf86Privstr.h b/xorg-server/hw/xfree86/common/xf86Privstr.h
index f7a9c9f1c..410ef17ac 100644
--- a/xorg-server/hw/xfree86/common/xf86Privstr.h
+++ b/xorg-server/hw/xfree86/common/xf86Privstr.h
@@ -163,4 +163,8 @@ typedef struct _RootWinProp {
#define WSCONS 32
#endif
+/* Root window property to tell clients whether our VT is currently active.
+ * Name chosen to match the "XFree86_VT" property. */
+#define HAS_VT_ATOM_NAME "XFree86_has_VT"
+
#endif /* _XF86PRIVSTR_H */
diff --git a/xorg-server/hw/xfree86/dixmods/Makefile.am b/xorg-server/hw/xfree86/dixmods/Makefile.am
index 3c43640ec..dd076e421 100644
--- a/xorg-server/hw/xfree86/dixmods/Makefile.am
+++ b/xorg-server/hw/xfree86/dixmods/Makefile.am
@@ -19,12 +19,12 @@ AM_CPPFLAGS = @XORG_INCS@ \
libfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG)
libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
-libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
+libfb_la_SOURCES = fbmodule.c
libfb_la_CFLAGS = $(AM_CFLAGS)
libwfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG)
libwfb_la_LIBADD = $(top_builddir)/fb/libwfb.la
-libwfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
+libwfb_la_SOURCES = fbmodule.c
libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER
libglx_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG)
diff --git a/xorg-server/hw/xfree86/man/Xorg.man b/xorg-server/hw/xfree86/man/Xorg.man
index 0cd5a1068..3ff6aef89 100644
--- a/xorg-server/hw/xfree86/man/Xorg.man
+++ b/xorg-server/hw/xfree86/man/Xorg.man
@@ -301,9 +301,11 @@ Use the file called
.I filename
as the
.B Xorg
-server log file. The default log file is
+server log file. The default log file when running as root is
.BI __logdir__/Xorg. n .log
-on most platforms, where
+and for non root it is
+.BI $XDG_DATA_HOME/xorg/Xorg. n .log
+where
.I n
is the display number of the
.B Xorg
diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man
index 85f9f2ee1..6d2652e84 100644
--- a/xorg-server/hw/xfree86/man/xorg.conf.man
+++ b/xorg-server/hw/xfree86/man/xorg.conf.man
@@ -442,11 +442,15 @@ __modulepath__
.TP 7
.BI "LogFile \*q" path \*q
sets the name of the Xorg server log file.
-The default log file name is
+The default log file name when running as root is
.PP
.RS 11
.RI __logdir__/Xorg. <n> .log
.RE
+and for non root it is
+.RS 11
+.RI $XDG_DATA_HOME/xorg/Xorg. <n> .log
+.RE
.PP
.RS 7
where
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h
index c127d78af..5407deb0e 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.h
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h
@@ -186,13 +186,13 @@ typedef struct _xf86CrtcFuncs {
/**
* Load monochrome image
*/
- void
+ Bool
(*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image);
/**
* Load ARGB image
*/
- void
+ Bool
(*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
/**
diff --git a/xorg-server/hw/xfree86/modes/xf86Cursors.c b/xorg-server/hw/xfree86/modes/xf86Cursors.c
index 2b0db3492..10ef6f6d4 100644
--- a/xorg-server/hw/xfree86/modes/xf86Cursors.c
+++ b/xorg-server/hw/xfree86/modes/xf86Cursors.c
@@ -211,7 +211,7 @@ set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask)
/*
* Load a two color cursor into a driver that supports only ARGB cursors
*/
-static void
+static Bool
xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src)
{
ScrnInfoPtr scrn = crtc->scrn;
@@ -244,7 +244,7 @@ xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src)
bits = 0;
cursor_image[y * cursor_info->MaxWidth + x] = bits;
}
- crtc->funcs->load_cursor_argb(crtc, cursor_image);
+ return crtc->funcs->load_cursor_argb(crtc, cursor_image);
}
/*
@@ -415,7 +415,7 @@ xf86_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
/*
* Load a two-color cursor into a crtc, performing rotation as needed
*/
-static void
+static Bool
xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src)
{
ScrnInfoPtr scrn = crtc->scrn;
@@ -450,13 +450,13 @@ xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src)
set_bit(cursor_image, cursor_info, x, y, TRUE);
}
}
- crtc->funcs->load_cursor_image(crtc, cursor_image);
+ return crtc->funcs->load_cursor_image(crtc, cursor_image);
}
/*
* Load a cursor image into all active CRTCs
*/
-static void
+static Bool
xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -466,12 +466,17 @@ xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src)
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled) {
- if (crtc->funcs->load_cursor_image)
- xf86_crtc_load_cursor_image(crtc, src);
- else if (crtc->funcs->load_cursor_argb)
- xf86_crtc_convert_cursor_to_argb(crtc, src);
+ if (crtc->funcs->load_cursor_image) {
+ if (!xf86_crtc_load_cursor_image(crtc, src))
+ return FALSE;
+ } else if (crtc->funcs->load_cursor_argb) {
+ if (!xf86_crtc_convert_cursor_to_argb(crtc, src))
+ return FALSE;
+ } else
+ return FALSE;
}
}
+ return TRUE;
}
static Bool
@@ -516,7 +521,7 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
return TRUE;
}
-static void
+static Bool
xf86_crtc_load_cursor_argb(xf86CrtcPtr crtc, CursorPtr cursor)
{
ScrnInfoPtr scrn = crtc->scrn;
@@ -544,10 +549,10 @@ xf86_crtc_load_cursor_argb(xf86CrtcPtr crtc, CursorPtr cursor)
cursor_image[y * image_width + x] = bits;
}
- crtc->funcs->load_cursor_argb(crtc, cursor_image);
+ return crtc->funcs->load_cursor_argb(crtc, cursor_image);
}
-static void
+static Bool
xf86_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -557,8 +562,10 @@ xf86_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor)
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->enabled)
- xf86_crtc_load_cursor_argb(crtc, cursor);
+ if (!xf86_crtc_load_cursor_argb(crtc, cursor))
+ return FALSE;
}
+ return TRUE;
}
Bool
@@ -608,6 +615,8 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags)
* Called when anything on the screen is reconfigured.
*
* Reloads cursor images as needed, then adjusts cursor positions
+ * @note We assume that all hardware cursors to be loaded have already been
+ * found to be usable by the hardware.
*/
void
diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
index 62858b062..ed670a88c 100644
--- a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c
@@ -310,10 +310,31 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
dbus_int32_t major, minor;
char *pause_str;
- if (strcmp(dbus_message_get_path(message), info->session) != 0)
+ dbus_error_init(&error);
+
+ if (dbus_message_is_signal(message,
+ "org.freedesktop.DBus", "NameOwnerChanged")) {
+ char *name, *old_owner, *new_owner;
+
+ dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &old_owner,
+ DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID);
+ if (dbus_error_is_set(&error)) {
+ LogMessage(X_ERROR, "systemd-logind: NameOwnerChanged: %s\n",
+ error.message);
+ dbus_error_free(&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (name && strcmp(name, "org.freedesktop.login1") == 0)
+ FatalError("systemd-logind disappeared (stopped/restarted?)\n");
+
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
- dbus_error_init(&error);
+ if (strcmp(dbus_message_get_path(message), info->session) != 0)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",
"PauseDevice")) {
@@ -472,6 +493,15 @@ connect_hook(DBusConnection *connection, void *data)
goto cleanup;
}
+ dbus_bus_add_match(connection,
+ "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus'",
+ &error);
+ if (dbus_error_is_set(&error)) {
+ LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n",
+ error.message);
+ goto cleanup;
+ }
+
/*
* HdG: This is not useful with systemd <= 208 since the signal only
* contains invalidated property names there, rather than property, val
diff --git a/xorg-server/hw/xfree86/parser/DRI.c b/xorg-server/hw/xfree86/parser/DRI.c
index ad053f746..6be32d7ea 100644
--- a/xorg-server/hw/xfree86/parser/DRI.c
+++ b/xorg-server/hw/xfree86/parser/DRI.c
@@ -31,6 +31,7 @@
#include <xorg-config.h>
#endif
+#include "os.h"
#include "xf86Parser.h"
#include "xf86tokens.h"
#include "Configint.h"
diff --git a/xorg-server/hw/xfree86/parser/Extensions.c b/xorg-server/hw/xfree86/parser/Extensions.c
index b5ba72e5f..a6fcb56f0 100644
--- a/xorg-server/hw/xfree86/parser/Extensions.c
+++ b/xorg-server/hw/xfree86/parser/Extensions.c
@@ -35,6 +35,7 @@
#include <xorg-config.h>
#endif
+#include "os.h"
#include "xf86Parser.h"
#include "xf86tokens.h"
#include "Configint.h"
diff --git a/xorg-server/hw/xfree86/ramdac/IBM.c b/xorg-server/hw/xfree86/ramdac/IBM.c
index bc716231a..872d3d4e7 100644
--- a/xorg-server/hw/xfree86/ramdac/IBM.c
+++ b/xorg-server/hw/xfree86/ramdac/IBM.c
@@ -570,7 +570,7 @@ IBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
(*ramdacPtr->WriteData) (pScrn, bg);
}
-static void
+static Bool
IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
@@ -582,9 +582,10 @@ IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
*/
for (i = 0; i < 1024; i++)
(*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_array + i, 0x00, (*src++));
+ return TRUE;
}
-static void
+static Bool
IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
@@ -596,6 +597,7 @@ IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
*/
for (i = 0; i < 1024; i++)
(*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++));
+ return TRUE;
}
static Bool
diff --git a/xorg-server/hw/xfree86/ramdac/TI.c b/xorg-server/hw/xfree86/ramdac/TI.c
index 393b774d4..7d4e0d796 100644
--- a/xorg-server/hw/xfree86/ramdac/TI.c
+++ b/xorg-server/hw/xfree86/ramdac/TI.c
@@ -642,7 +642,7 @@ TIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
(*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0, (fg & 0x000000ff));
}
-static void
+static Bool
TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
@@ -657,6 +657,7 @@ TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
/* NOT_DONE: might need a delay here */
(*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++));
}
+ return TRUE;
}
static Bool
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
index 860704e1c..fac682210 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
@@ -352,12 +352,13 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
NullCursor, x, y);
- xf86SetCursor(pScreen, cursor, x, y);
- ScreenPriv->SWCursor = FALSE;
- ScreenPriv->isUp = TRUE;
+ if (xf86SetCursor(pScreen, cursor, x, y)) {
+ ScreenPriv->SWCursor = FALSE;
+ ScreenPriv->isUp = TRUE;
- miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse);
- return;
+ miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse);
+ return;
+ }
}
miPointerSetWaitForUpdate(pScreen, TRUE);
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.h b/xorg-server/hw/xfree86/ramdac/xf86Cursor.h
index 5658e7b30..1ecbdcd8d 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.h
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.h
@@ -12,7 +12,7 @@ typedef struct _xf86CursorInfoRec {
int MaxHeight;
void (*SetCursorColors) (ScrnInfoPtr pScrn, int bg, int fg);
void (*SetCursorPosition) (ScrnInfoPtr pScrn, int x, int y);
- void (*LoadCursorImage) (ScrnInfoPtr pScrn, unsigned char *bits);
+ Bool (*LoadCursorImage) (ScrnInfoPtr pScrn, unsigned char *bits);
void (*HideCursor) (ScrnInfoPtr pScrn);
void (*ShowCursor) (ScrnInfoPtr pScrn);
unsigned char *(*RealizeCursor) (struct _xf86CursorInfoRec *, CursorPtr);
@@ -20,7 +20,7 @@ typedef struct _xf86CursorInfoRec {
#ifdef ARGB_CURSOR
Bool (*UseHWCursorARGB) (ScreenPtr, CursorPtr);
- void (*LoadCursorARGB) (ScrnInfoPtr, CursorPtr);
+ Bool (*LoadCursorARGB) (ScrnInfoPtr, CursorPtr);
#endif
} xf86CursorInfoRec, *xf86CursorInfoPtr;
diff --git a/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h b/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h
index a5d2aabc3..f34c1c7fc 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h
+++ b/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h
@@ -37,7 +37,7 @@ typedef struct {
void *transparentData;
} xf86CursorScreenRec, *xf86CursorScreenPtr;
-void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
+Bool xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
void xf86SetTransparentCursor(ScreenPtr pScreen);
void xf86MoveCursor(ScreenPtr pScreen, int x, int y);
void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed);
diff --git a/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c b/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c
index 3b69698db..0b5caa20a 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c
@@ -119,7 +119,7 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
return TRUE;
}
-void
+Bool
xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
{
xf86CursorScreenPtr ScreenPriv =
@@ -130,7 +130,7 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
if (pCurs == NullCursor) {
(*infoPtr->HideCursor) (infoPtr->pScrn);
- return;
+ return TRUE;
}
bits =
@@ -152,18 +152,21 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
(*infoPtr->HideCursor) (infoPtr->pScrn);
#ifdef ARGB_CURSOR
- if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
- (*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
- else
+ if (pCurs->bits->argb && infoPtr->LoadCursorARGB) {
+ if (!(*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs))
+ return FALSE;
+ } else
#endif
if (bits)
- (*infoPtr->LoadCursorImage) (infoPtr->pScrn, bits);
+ if (!(*infoPtr->LoadCursorImage) (infoPtr->pScrn, bits))
+ return FALSE;
xf86RecolorCursor(pScreen, pCurs, 1);
(*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
(*infoPtr->ShowCursor) (infoPtr->pScrn);
+ return TRUE;
}
void
diff --git a/xorg-server/hw/xnest/Makefile.am b/xorg-server/hw/xnest/Makefile.am
index 3c099cd6b..eb550c0f7 100644
--- a/xorg-server/hw/xnest/Makefile.am
+++ b/xorg-server/hw/xnest/Makefile.am
@@ -1,7 +1,6 @@
SUBDIRS = man
bin_PROGRAMS = Xnest
-noinst_LIBRARIES = libfbcmap.a
AM_CFLAGS = -DHAVE_XNEST_CONFIG_H \
$(DIX_CFLAGS) \
@@ -42,16 +41,12 @@ SRCS = Args.c \
XNPixmap.h \
XNWindow.h \
xnest-config.h \
- $(top_srcdir)/Xext/dpmsstubs.c \
- $(top_srcdir)/Xi/stubs.c \
$(top_srcdir)/mi/miinitext.c
-libfbcmap_a_SOURCES = $(top_srcdir)/fb/fbcmap_mi.c
-libfbcmap_a_CFLAGS = $(AM_CFLAGS)
-
XNEST_LIBS = \
@XNEST_LIBS@ \
- libfbcmap.a
+ $(top_builddir)/Xext/libXextdpmsstubs.la \
+ $(top_builddir)/Xi/libXistubs.la
Xnest_SOURCES = $(SRCS)
diff --git a/xorg-server/hw/xquartz/Makefile.am b/xorg-server/hw/xquartz/Makefile.am
index 2ca953cf9..4da896d76 100644
--- a/xorg-server/hw/xquartz/Makefile.am
+++ b/xorg-server/hw/xquartz/Makefile.am
@@ -20,7 +20,6 @@ SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup man
DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup man
libXquartz_la_SOURCES = \
- $(top_srcdir)/fb/fbcmap_mi.c \
$(top_srcdir)/mi/miinitext.c \
X11Application.m \
X11Controller.m \
diff --git a/xorg-server/hw/xquartz/X11Controller.m b/xorg-server/hw/xquartz/X11Controller.m
index 5445c6f3a..022e83258 100644
--- a/xorg-server/hw/xquartz/X11Controller.m
+++ b/xorg-server/hw/xquartz/X11Controller.m
@@ -942,9 +942,8 @@ extern char *bundle_id_prefix;
/* shutdown the X server, it will exit () for us. */
DarwinSendDDXEvent(kXquartzQuit, 0);
- /* In case it doesn't, exit anyway after a while. */
- remain = 10000000;
- while ((remain = usleep(remain)) > 0) ;
+ /* In case it doesn't, exit anyway after 5s. */
+ [NSThread sleepForTimeInterval:5.0];
exit(1);
}
diff --git a/xorg-server/hw/xwayland/.gitignore b/xorg-server/hw/xwayland/.gitignore
new file mode 100644
index 000000000..c54ba2de9
--- /dev/null
+++ b/xorg-server/hw/xwayland/.gitignore
@@ -0,0 +1,3 @@
+Xwayland
+drm-client-protocol.h
+drm-protocol.c
diff --git a/xorg-server/hw/xwayland/Makefile.am b/xorg-server/hw/xwayland/Makefile.am
new file mode 100644
index 000000000..36e6127df
--- /dev/null
+++ b/xorg-server/hw/xwayland/Makefile.am
@@ -0,0 +1,30 @@
+bin_PROGRAMS = Xwayland
+
+Xwayland_CFLAGS = \
+ -I$(top_srcdir)/dri3 \
+ -DHAVE_DIX_CONFIG_H \
+ $(XWAYLANDMODULES_CFLAGS) \
+ $(DIX_CFLAGS)
+
+Xwayland_SOURCES = \
+ xwayland.c \
+ xwayland-input.c \
+ xwayland-cursor.c \
+ xwayland-shm.c \
+ xwayland-output.c \
+ xwayland-cvt.c \
+ xwayland.h \
+ $(top_srcdir)/Xext/dpmsstubs.c \
+ $(top_srcdir)/Xi/stubs.c \
+ $(top_srcdir)/mi/miinitext.c
+
+Xwayland_LDADD = \
+ $(XWAYLAND_LIBS) \
+ $(XWAYLAND_SYS_LIBS) \
+ $(XSERVER_SYS_LIBS)
+Xwayland_DEPENDENCIES = $(XWAYLAND_LIBS)
+Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+
+
+relink:
+ $(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT)
diff --git a/xorg-server/hw/xwayland/xwayland-cursor.c b/xorg-server/hw/xwayland/xwayland-cursor.c
new file mode 100644
index 000000000..5a9d1fe70
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland-cursor.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ * 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.
+ */
+
+#include "xwayland.h"
+
+#include <mipointer.h>
+
+static DevPrivateKeyRec xwl_cursor_private_key;
+
+static void
+expand_source_and_mask(CursorPtr cursor, CARD32 *data)
+{
+ CARD32 *p, d, fg, bg;
+ CursorBitsPtr bits = cursor->bits;
+ int x, y, stride, i, bit;
+
+ p = data;
+ 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;
+ }
+}
+
+static Bool
+xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
+{
+ PixmapPtr pixmap;
+
+ pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width,
+ cursor->bits->height, 32, 0);
+ dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap);
+
+ return TRUE;
+}
+
+static Bool
+xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
+{
+ PixmapPtr pixmap;
+
+ pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
+
+ return xwl_shm_destroy_pixmap(pixmap);
+}
+
+void
+xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
+{
+ PixmapPtr pixmap;
+ CursorPtr cursor;
+ int stride;
+
+ 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;
+ }
+
+ cursor = xwl_seat->x_cursor;
+ pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
+ stride = cursor->bits->width * 4;
+ if (cursor->bits->argb)
+ memcpy(pixmap->devPrivate.ptr,
+ cursor->bits->argb, cursor->bits->height * stride);
+ else
+ expand_source_and_mask(cursor, pixmap->devPrivate.ptr);
+
+ 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,
+ xwl_shm_pixmap_get_wl_buffer(pixmap), 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_seat *xwl_seat;
+
+ xwl_seat = device->public.devicePrivate;
+ if (xwl_seat == NULL)
+ return;
+
+ 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)
+{
+ return TRUE;
+}
+
+static void
+xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr 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
+};
+
+static Bool
+xwl_cursor_off_screen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+xwl_cross_screen(ScreenPtr pScreen, Bool entering)
+{
+}
+
+static void
+xwl_pointer_warp_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+}
+
+static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
+ xwl_cursor_off_screen,
+ xwl_cross_screen,
+ xwl_pointer_warp_cursor
+};
+
+Bool
+xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
+{
+ if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0))
+ return FALSE;
+
+ return miPointerInitialize(xwl_screen->screen,
+ &xwl_pointer_sprite_funcs,
+ &xwl_pointer_screen_funcs, TRUE);
+}
diff --git a/xorg-server/hw/xwayland/xwayland-cvt.c b/xorg-server/hw/xwayland/xwayland-cvt.c
new file mode 100644
index 000000000..35665597f
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland-cvt.c
@@ -0,0 +1,304 @@
+/* Copied from hw/xfree86/modes/xf86cvt.c into xwayland DDX and
+ * changed to generate an RRMode */
+
+/*
+ * Copyright 2005-2006 Luc Verhaegen.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The reason for having this function in a file of its own is
+ * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
+ * code is shared directly.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#include <randrstr.h>
+#include "xwayland.h"
+
+/*
+ * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
+ *
+ * These calculations are stolen from the CVT calculation spreadsheet written
+ * by Graham Loveridge. He seems to be claiming no copyright and there seems to
+ * be no license attached to this. He apparently just wants to see his name
+ * mentioned.
+ *
+ * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
+ *
+ * Comments and structure corresponds to the comments and structure of the xls.
+ * This should ease importing of future changes to the standard (not very
+ * likely though).
+ *
+ * About margins; i'm sure that they are to be the bit between HDisplay and
+ * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and
+ * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
+ * outside sync "margin" for some reason. Since we prefer seeing proper
+ * blanking instead of the overscan colour, and since the Crtc* values will
+ * probably get altered after us, we will disable margins altogether. With
+ * these calculations, Margins will plainly expand H/VDisplay, and we don't
+ * want that. -- libv
+ *
+ */
+RRModePtr
+xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
+ Bool Interlaced)
+{
+ /* 1) top/bottom margin size (% of height) - default: 1.8 */
+#define CVT_MARGIN_PERCENTAGE 1.8
+
+ /* 2) character cell horizontal granularity (pixels) - default 8 */
+#define CVT_H_GRANULARITY 8
+
+ /* 4) Minimum vertical porch (lines) - default 3 */
+#define CVT_MIN_V_PORCH 3
+
+ /* 4) Minimum number of vertical back porch lines - default 6 */
+#define CVT_MIN_V_BPORCH 6
+
+ /* Pixel Clock step (kHz) */
+#define CVT_CLOCK_STEP 250
+
+ Bool Margins = FALSE;
+ float VFieldRate, HPeriod;
+ int HDisplayRnd, HMargin;
+ int VDisplayRnd, VMargin, VSync;
+ float Interlace; /* Please rename this */
+ char name[128];
+ xRRModeInfo modeinfo;
+
+ memset(&modeinfo, 0, sizeof modeinfo);
+
+ /* CVT default is 60.0Hz */
+ if (!VRefresh)
+ VRefresh = 60.0;
+
+ /* 1. Required field rate */
+ if (Interlaced)
+ VFieldRate = VRefresh * 2;
+ else
+ VFieldRate = VRefresh;
+
+ /* 2. Horizontal pixels */
+ HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
+
+ /* 3. Determine left and right borders */
+ if (Margins) {
+ /* right margin is actually exactly the same as left */
+ HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
+ HMargin -= HMargin % CVT_H_GRANULARITY;
+ }
+ else
+ HMargin = 0;
+
+ /* 4. Find total active pixels */
+ modeinfo.width = HDisplayRnd + 2 * HMargin;
+
+ /* 5. Find number of lines per field */
+ if (Interlaced)
+ VDisplayRnd = VDisplay / 2;
+ else
+ VDisplayRnd = VDisplay;
+
+ /* 6. Find top and bottom margins */
+ /* nope. */
+ if (Margins)
+ /* top and bottom margins are equal again. */
+ VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
+ else
+ VMargin = 0;
+
+ modeinfo.height = VDisplay + 2 * VMargin;
+
+ /* 7. Interlace */
+ if (Interlaced)
+ Interlace = 0.5;
+ else
+ Interlace = 0.0;
+
+ /* Determine VSync Width from aspect ratio */
+ if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
+ VSync = 4;
+ else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
+ VSync = 5;
+ else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
+ VSync = 6;
+ else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
+ VSync = 7;
+ else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
+ VSync = 7;
+ else /* Custom */
+ VSync = 10;
+
+ if (!Reduced) { /* simplified GTF calculation */
+
+ /* 4) Minimum time of vertical sync + back porch interval (µs)
+ * default 550.0 */
+#define CVT_MIN_VSYNC_BP 550.0
+
+ /* 3) Nominal HSync width (% of line period) - default 8 */
+#define CVT_HSYNC_PERCENTAGE 8
+
+ float HBlankPercentage;
+ int VSyncAndBackPorch, VBackPorch;
+ int HBlank;
+
+ /* 8. Estimated Horizontal period */
+ HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) /
+ (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
+
+ /* 9. Find number of lines in sync + backporch */
+ if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) <
+ (VSync + CVT_MIN_V_PORCH))
+ VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
+ else
+ VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1;
+
+ /* 10. Find number of lines in back porch */
+ VBackPorch = VSyncAndBackPorch - VSync;
+ (void) VBackPorch;
+
+ /* 11. Find total number of lines in vertical field */
+ modeinfo.vTotal =
+ VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace +
+ CVT_MIN_V_PORCH;
+
+ /* 5) Definition of Horizontal blanking time limitation */
+ /* Gradient (%/kHz) - default 600 */
+#define CVT_M_FACTOR 600
+
+ /* Offset (%) - default 40 */
+#define CVT_C_FACTOR 40
+
+ /* Blanking time scaling factor - default 128 */
+#define CVT_K_FACTOR 128
+
+ /* Scaling factor weighting - default 20 */
+#define CVT_J_FACTOR 20
+
+#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
+#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
+ CVT_J_FACTOR
+
+ /* 12. Find ideal blanking duty cycle from formula */
+ HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0;
+
+ /* 13. Blanking time */
+ if (HBlankPercentage < 20)
+ HBlankPercentage = 20;
+
+ HBlank = modeinfo.width * HBlankPercentage / (100.0 - HBlankPercentage);
+ HBlank -= HBlank % (2 * CVT_H_GRANULARITY);
+
+ /* 14. Find total number of pixels in a line. */
+ modeinfo.hTotal = modeinfo.width + HBlank;
+
+ /* Fill in HSync values */
+ modeinfo.hSyncEnd = modeinfo.width + HBlank / 2;
+
+ modeinfo.hSyncStart = modeinfo.hSyncEnd -
+ (modeinfo.hTotal * CVT_HSYNC_PERCENTAGE) / 100;
+ modeinfo.hSyncStart += CVT_H_GRANULARITY -
+ modeinfo.hSyncStart % CVT_H_GRANULARITY;
+
+ /* Fill in VSync values */
+ modeinfo.vSyncStart = modeinfo.height + CVT_MIN_V_PORCH;
+ modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync;
+
+ }
+ else { /* Reduced blanking */
+ /* Minimum vertical blanking interval time (µs) - default 460 */
+#define CVT_RB_MIN_VBLANK 460.0
+
+ /* Fixed number of clocks for horizontal sync */
+#define CVT_RB_H_SYNC 32.0
+
+ /* Fixed number of clocks for horizontal blanking */
+#define CVT_RB_H_BLANK 160.0
+
+ /* Fixed number of lines for vertical front porch - default 3 */
+#define CVT_RB_VFPORCH 3
+
+ int VBILines;
+
+ /* 8. Estimate Horizontal period. */
+ HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) /
+ (VDisplayRnd + 2 * VMargin);
+
+ /* 9. Find number of lines in vertical blanking */
+ VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
+
+ /* 10. Check if vertical blanking is sufficient */
+ if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
+ VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
+
+ /* 11. Find total number of lines in vertical field */
+ modeinfo.vTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
+
+ /* 12. Find total number of pixels in a line */
+ modeinfo.hTotal = modeinfo.width + CVT_RB_H_BLANK;
+
+ /* Fill in HSync values */
+ modeinfo.hSyncEnd = modeinfo.width + CVT_RB_H_BLANK / 2;
+ modeinfo.hSyncStart = modeinfo.hSyncEnd - CVT_RB_H_SYNC;
+
+ /* Fill in VSync values */
+ modeinfo.vSyncStart = modeinfo.height + CVT_RB_VFPORCH;
+ modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync;
+ }
+
+ /* 15/13. Find pixel clock frequency (kHz for xf86) */
+ modeinfo.dotClock = modeinfo.hTotal * 1000.0 / HPeriod;
+ modeinfo.dotClock -= modeinfo.dotClock % CVT_CLOCK_STEP;
+ modeinfo.dotClock *= 1000.0;
+#if 0
+ /* 16/14. Find actual Horizontal Frequency (kHz) */
+ modeinfo.hSync = ((float) modeinfo.dotClock) / ((float) modeinfo.hTotal);
+#endif
+
+#if 0
+ /* 17/15. Find actual Field rate */
+ modeinfo.vRefresh = (1000.0 * ((float) modeinfo.dotClock)) /
+ ((float) (modeinfo.hTotal * modeinfo.vTotal));
+#endif
+
+ /* 18/16. Find actual vertical frame frequency */
+ /* ignore - just set the mode flag for interlaced */
+ if (Interlaced)
+ modeinfo.vTotal *= 2;
+
+ if (Reduced)
+ modeinfo.modeFlags |= RR_HSyncPositive | RR_VSyncNegative;
+ else
+ modeinfo.modeFlags |= RR_HSyncNegative | RR_VSyncPositive;
+
+ if (Interlaced)
+ modeinfo.modeFlags |= RR_Interlace;
+
+ snprintf(name, sizeof name, "%dx%d@%.1fHz",
+ modeinfo.width, modeinfo.height, VRefresh);
+ modeinfo.nameLength = strlen(name);
+
+ return RRModeGet(&modeinfo, name);
+}
diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c
new file mode 100644
index 000000000..990cb82d8
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland-input.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ * 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.
+ */
+
+#include "xwayland.h"
+
+#include <linux/input.h>
+
+#include <sys/mman.h>
+#include <xkbsrv.h>
+#include <xserver-properties.h>
+#include <inpututils.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)
+{
+}
+
+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 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);
+ CheckMotion(NULL, GetMaster(dev, MASTER_POINTER));
+
+ /* 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);
+}
+
+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;
+
+ xwl_seat->xwl_screen->serial = serial;
+
+ xwl_seat->focus_window = NULL;
+ CheckMotion(NULL, GetMaster(dev, MASTER_POINTER));
+}
+
+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;
+ }
+
+ 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);
+
+ if (xwl_seat->keyboard->key)
+ /* 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 DeviceIntPtr
+add_device(struct xwl_seat *xwl_seat,
+ const char *driver, DeviceProc device_proc)
+{
+ DeviceIntPtr dev = NULL;
+ static Atom type_atom;
+ char name[32];
+
+ dev = AddInputDevice(serverClient, device_proc, TRUE);
+ if (dev == NULL)
+ return NULL;
+
+ if (type_atom == None)
+ type_atom = MakeAtom(driver, strlen(driver), TRUE);
+ snprintf(name, sizeof name, "%s:%d", driver, xwl_seat->id);
+ AssignTypeAndName(dev, type_atom, name);
+ dev->public.devicePrivate = xwl_seat;
+ dev->type = SLAVE;
+ dev->spriteInfo->spriteOwner = FALSE;
+
+ return dev;
+}
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+ enum wl_seat_capability caps)
+{
+ struct xwl_seat *xwl_seat = data;
+
+ if (caps & WL_SEAT_CAPABILITY_POINTER && xwl_seat->pointer == NULL) {
+ 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);
+ xwl_seat->pointer =
+ add_device(xwl_seat, "xwayland-pointer", xwl_pointer_proc);
+ }
+ else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->pointer) {
+ wl_pointer_release(xwl_seat->wl_pointer);
+ RemoveDevice(xwl_seat->pointer, FALSE);
+ xwl_seat->pointer = NULL;
+ }
+
+ if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->keyboard == NULL) {
+ xwl_seat->wl_keyboard = wl_seat_get_keyboard(seat);
+ wl_keyboard_add_listener(xwl_seat->wl_keyboard,
+ &keyboard_listener, xwl_seat);
+ xwl_seat->keyboard =
+ add_device(xwl_seat, "xwayland-keyboard", xwl_keyboard_proc);
+ }
+ else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && xwl_seat->keyboard) {
+ wl_keyboard_release(xwl_seat->wl_keyboard);
+ RemoveDevice(xwl_seat->keyboard, FALSE);
+ xwl_seat->keyboard = NULL;
+ }
+
+ xwl_seat->xwl_screen->expecting_event--;
+ /* FIXME: Touch ... */
+}
+
+static void
+seat_handle_name(void *data, struct wl_seat *seat,
+ const char *name)
+{
+
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_handle_capabilities,
+ seat_handle_name
+};
+
+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, 3);
+ 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);
+}
+
+void
+xwl_seat_destroy(struct xwl_seat *xwl_seat)
+{
+ RemoveDevice(xwl_seat->pointer, FALSE);
+ RemoveDevice(xwl_seat->keyboard, FALSE);
+ wl_seat_destroy(xwl_seat->seat);
+ wl_surface_destroy(xwl_seat->cursor);
+ wl_array_release(&xwl_seat->keys);
+ free(xwl_seat);
+}
+
+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 && version >= 3) {
+ create_input_device(xwl_screen, id);
+ xwl_screen->expecting_event++;
+ }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+}
+
+static const struct wl_registry_listener input_listener = {
+ input_handler,
+ global_remove,
+};
+
+Bool
+LegalModifier(unsigned int key, DeviceIntPtr pDev)
+{
+ return TRUE;
+}
+
+void
+ProcessInputEvents(void)
+{
+ mieqProcessInputEvents();
+}
+
+void
+DDXRingBell(int volume, int pitch, int duration)
+{
+}
+
+static WindowPtr
+xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y)
+{
+ struct xwl_seat *xwl_seat = NULL;
+ DeviceIntPtr device;
+
+ for (device = inputInfo.devices; device; device = device->next) {
+ if (device->deviceProc == xwl_pointer_proc &&
+ device->spriteInfo->sprite == sprite) {
+ xwl_seat = device->public.devicePrivate;
+ break;
+ }
+ }
+
+ if (xwl_seat == NULL) {
+ /* XTEST device */
+ sprite->spriteTraceGood = 1;
+ return sprite->spriteTrace[0];
+ }
+
+ if (xwl_seat->focus_window) {
+ sprite->spriteTraceGood = 2;
+ sprite->spriteTrace[1] = xwl_seat->focus_window->window;
+ return miSpriteTrace(sprite, x, y);
+ }
+ else {
+ sprite->spriteTraceGood = 1;
+ return sprite->spriteTrace[0];
+ }
+}
+
+void
+InitInput(int argc, char *argv[])
+{
+ ScreenPtr pScreen = screenInfo.screens[0];
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+
+ mieqInit();
+
+ xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
+ wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
+ xwl_screen);
+
+ xwl_screen->XYToWindow = pScreen->XYToWindow;
+ pScreen->XYToWindow = xwl_xy_to_window;
+
+ xwl_screen->expecting_event = 0;
+ wl_display_roundtrip(xwl_screen->display);
+ while (xwl_screen->expecting_event)
+ wl_display_roundtrip(xwl_screen->display);
+}
+
+void
+CloseInput(void)
+{
+ mieqFini();
+}
diff --git a/xorg-server/hw/xwayland/xwayland-output.c b/xorg-server/hw/xwayland/xwayland-output.c
new file mode 100644
index 000000000..778914c61
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland-output.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright © 2011-2014 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_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xwayland.h"
+#include <randrstr.h>
+
+static Rotation
+wl_transform_to_xrandr(enum wl_output_transform transform)
+{
+ switch (transform) {
+ default:
+ 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;
+ }
+}
+
+static int
+wl_subpixel_to_xrandr(int subpixel)
+{
+ switch (subpixel) {
+ default:
+ case WL_OUTPUT_SUBPIXEL_UNKNOWN:
+ return SubPixelUnknown;
+ case WL_OUTPUT_SUBPIXEL_NONE:
+ return SubPixelNone;
+ case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
+ return SubPixelHorizontalRGB;
+ case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
+ return SubPixelHorizontalBGR;
+ case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
+ return SubPixelVerticalRGB;
+ case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
+ return SubPixelVerticalBGR;
+ }
+}
+
+static void
+output_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;
+
+ RROutputSetPhysicalSize(xwl_output->randr_output,
+ physical_width, physical_height);
+ RROutputSetSubpixelOrder(xwl_output->randr_output,
+ wl_subpixel_to_xrandr(subpixel));
+ xwl_output->x = x;
+ xwl_output->y = y;
+
+ xwl_output->rotation = wl_transform_to_xrandr(transform);
+}
+
+static void
+output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+ int width, int height, int refresh)
+{
+ struct xwl_output *xwl_output = data;
+ RRModePtr randr_mode;
+
+ if (!(flags & WL_OUTPUT_MODE_CURRENT))
+ return;
+
+ xwl_output->width = width;
+ xwl_output->height = height;
+
+ randr_mode = xwayland_cvt(width, height, refresh / 1000.0, 0, 0);
+
+ RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1);
+
+ RRCrtcNotify(xwl_output->randr_crtc, randr_mode,
+ xwl_output->x, xwl_output->y,
+ xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
+}
+
+static void
+output_handle_done(void *data, struct wl_output *wl_output)
+{
+ struct xwl_output *xwl_output = data;
+ struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+ int width, height;
+
+ xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+
+ width = 0;
+ height = 0;
+ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
+ if (width < xwl_output->x + xwl_output->width)
+ width = xwl_output->x + xwl_output->width;
+ if (height < xwl_output->y + xwl_output->height)
+ height = xwl_output->y + xwl_output->height;
+ }
+
+ xwl_screen->width = width;
+ xwl_screen->height = height;
+ RRScreenSizeNotify(xwl_screen->screen);
+
+ xwl_screen->expecting_event--;
+}
+
+static void
+output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)
+{
+}
+
+static const struct wl_output_listener output_listener = {
+ output_handle_geometry,
+ output_handle_mode,
+ output_handle_done,
+ output_handle_scale
+};
+
+struct xwl_output *
+xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
+{
+ struct xwl_output *xwl_output;
+ static int serial;
+ char name[256];
+
+ xwl_output = calloc(sizeof *xwl_output, 1);
+ if (xwl_output == NULL) {
+ ErrorF("create_output ENOMEM");
+ return NULL;
+ }
+
+ xwl_output->output = wl_registry_bind(xwl_screen->registry, id,
+ &wl_output_interface, 2);
+ wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
+
+ if (snprintf(name, sizeof name, "XWAYLAND%d", serial++) < 0) {
+ ErrorF("create_output ENOMEM");
+ free(xwl_output);
+ return NULL;
+ }
+
+ xwl_output->xwl_screen = xwl_screen;
+ xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
+ xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name,
+ strlen(name), xwl_output);
+ RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
+ RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
+ RROutputSetConnection(xwl_output->randr_output, RR_Connected);
+
+ return xwl_output;
+}
+
+void
+xwl_output_destroy(struct xwl_output *xwl_output)
+{
+ wl_output_destroy(xwl_output->output);
+ RRCrtcDestroy(xwl_output->randr_crtc);
+ RROutputDestroy(xwl_output->randr_output);
+ free(xwl_output);
+}
+
+static Bool
+xwl_randr_get_info(ScreenPtr pScreen, Rotation * rotations)
+{
+ *rotations = 0;
+
+ return TRUE;
+}
+
+static Bool
+xwl_randr_set_config(ScreenPtr pScreen,
+ Rotation rotation, int rate, RRScreenSizePtr pSize)
+{
+ return FALSE;
+}
+
+Bool
+xwl_screen_init_output(struct xwl_screen *xwl_screen)
+{
+ rrScrPrivPtr rp;
+
+ if (!RRScreenInit(xwl_screen->screen))
+ return FALSE;
+
+ RRScreenSetSizeRange(xwl_screen->screen, 320, 200, 8192, 8192);
+
+ rp = rrGetScrPriv(xwl_screen->screen);
+ rp->rrGetInfo = xwl_randr_get_info;
+ rp->rrSetConfig = xwl_randr_set_config;
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwayland/xwayland-shm.c b/xorg-server/hw/xwayland/xwayland-shm.c
new file mode 100644
index 000000000..2d0ce3eb6
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland-shm.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * 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.
+ */
+
+#include "xwayland.h"
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct xwl_pixmap {
+ struct wl_buffer *buffer;
+ int fd;
+ void *data;
+ size_t size;
+};
+
+#ifndef HAVE_MKOSTEMP
+static int
+set_cloexec_or_close(int fd)
+{
+ long flags;
+
+ if (fd == -1)
+ return -1;
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ goto err;
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ goto err;
+
+ return fd;
+
+ err:
+ close(fd);
+ return -1;
+}
+#endif
+
+static int
+create_tmpfile_cloexec(char *tmpname)
+{
+ int fd;
+
+#ifdef HAVE_MKOSTEMP
+ fd = mkostemp(tmpname, O_CLOEXEC);
+ if (fd >= 0)
+ unlink(tmpname);
+#else
+ fd = mkstemp(tmpname);
+ if (fd >= 0) {
+ fd = set_cloexec_or_close(fd);
+ unlink(tmpname);
+ }
+#endif
+
+ return fd;
+}
+
+/*
+ * Create a new, unique, anonymous file of the given size, and
+ * return the file descriptor for it. The file descriptor is set
+ * CLOEXEC. The file is immediately suitable for mmap()'ing
+ * the given size at offset zero.
+ *
+ * The file should not have a permanent backing store like a disk,
+ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
+ *
+ * The file name is deleted from the file system.
+ *
+ * The file is suitable for buffer sharing between processes by
+ * transmitting the file descriptor over Unix sockets using the
+ * SCM_RIGHTS methods.
+ *
+ * If the C library implements posix_fallocate(), it is used to
+ * guarantee that disk space is available for the file at the
+ * given size. If disk space is insufficent, errno is set to ENOSPC.
+ * If posix_fallocate() is not supported, program may receive
+ * SIGBUS on accessing mmap()'ed file contents instead.
+ */
+static int
+os_create_anonymous_file(off_t size)
+{
+ static const char template[] = "/weston-shared-XXXXXX";
+ const char *path;
+ char *name;
+ int fd;
+ int ret;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ name = malloc(strlen(path) + sizeof(template));
+ if (!name)
+ return -1;
+
+ strcpy(name, path);
+ strcat(name, template);
+
+ fd = create_tmpfile_cloexec(name);
+
+ free(name);
+
+ if (fd < 0)
+ return -1;
+
+#ifdef HAVE_POSIX_FALLOCATE
+ ret = posix_fallocate(fd, 0, size);
+ if (ret != 0) {
+ close(fd);
+ errno = ret;
+ return -1;
+ }
+#else
+ ret = ftruncate(fd, size);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+#endif
+
+ return fd;
+}
+
+static uint32_t
+shm_format_for_depth(int depth)
+{
+ switch (depth) {
+ case 32:
+ return WL_SHM_FORMAT_ARGB8888;
+ case 24:
+ default:
+ return WL_SHM_FORMAT_XRGB8888;
+#ifdef WL_SHM_FORMAT_RGB565
+ case 16:
+ /* XXX: Check run-time protocol version too */
+ return WL_SHM_FORMAT_RGB565;
+#endif
+ }
+}
+
+PixmapPtr
+xwl_shm_create_pixmap(ScreenPtr screen,
+ int width, int height, int depth, unsigned int hint)
+{
+ PixmapPtr pixmap;
+ struct xwl_pixmap *xwl_pixmap;
+ size_t size, stride;
+
+ if (hint == CREATE_PIXMAP_USAGE_GLYPH_PICTURE ||
+ (width == 0 && height == 0) || depth < 15)
+ return fbCreatePixmap(screen, width, height, depth, hint);
+
+ pixmap = fbCreatePixmap(screen, 0, 0, depth, hint);
+ if (!pixmap)
+ return NULL;
+
+ xwl_pixmap = malloc(sizeof *xwl_pixmap);
+ if (xwl_pixmap == NULL)
+ goto err_destroy_pixmap;
+
+ stride = PixmapBytePad(width, depth);
+ size = stride * height;
+ xwl_pixmap->buffer = NULL;
+ xwl_pixmap->size = size;
+ xwl_pixmap->fd = os_create_anonymous_file(size);
+ if (xwl_pixmap->fd < 0)
+ goto err_free_xwl_pixmap;
+
+ xwl_pixmap->data = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, xwl_pixmap->fd, 0);
+ if (xwl_pixmap->data == MAP_FAILED)
+ goto err_close_fd;
+
+ if (!(*screen->ModifyPixmapHeader) (pixmap, width, height, depth,
+ BitsPerPixel(depth),
+ stride, xwl_pixmap->data))
+ goto err_munmap;
+
+ xwl_pixmap_set_private(pixmap, xwl_pixmap);
+
+ return pixmap;
+
+ err_munmap:
+ munmap(xwl_pixmap->data, size);
+ err_close_fd:
+ close(xwl_pixmap->fd);
+ err_free_xwl_pixmap:
+ free(xwl_pixmap);
+ err_destroy_pixmap:
+ fbDestroyPixmap(pixmap);
+
+ return NULL;
+}
+
+Bool
+xwl_shm_destroy_pixmap(PixmapPtr pixmap)
+{
+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+
+ if (xwl_pixmap && pixmap->refcnt == 1) {
+ if (xwl_pixmap->buffer)
+ wl_buffer_destroy(xwl_pixmap->buffer);
+ munmap(xwl_pixmap->data, xwl_pixmap->size);
+ close(xwl_pixmap->fd);
+ free(xwl_pixmap);
+ }
+
+ return fbDestroyPixmap(pixmap);
+}
+
+struct wl_buffer *
+xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+ struct wl_shm_pool *pool;
+ uint32_t format;
+
+ if (xwl_pixmap->buffer)
+ return xwl_pixmap->buffer;
+
+ pool = wl_shm_create_pool(xwl_screen->shm,
+ xwl_pixmap->fd, xwl_pixmap->size);
+
+ format = shm_format_for_depth(pixmap->drawable.depth);
+ xwl_pixmap->buffer = wl_shm_pool_create_buffer(pool, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->devKind, format);
+
+ wl_shm_pool_destroy(pool);
+
+ return xwl_pixmap->buffer;
+}
+
+Bool
+xwl_shm_create_screen_resources(ScreenPtr screen)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ int ret;
+
+ screen->CreateScreenResources = xwl_screen->CreateScreenResources;
+ ret = (*screen->CreateScreenResources) (screen);
+ xwl_screen->CreateScreenResources = screen->CreateScreenResources;
+ screen->CreateScreenResources = xwl_shm_create_screen_resources;
+
+ if (!ret)
+ return ret;
+
+ if (xwl_screen->rootless)
+ screen->devPrivate =
+ fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
+ else
+ screen->devPrivate =
+ xwl_shm_create_pixmap(screen, screen->width, screen->height,
+ screen->rootDepth,
+ CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+
+ return screen->devPrivate != NULL;
+}
diff --git a/xorg-server/hw/xwayland/xwayland.c b/xorg-server/hw/xwayland/xwayland.c
new file mode 100644
index 000000000..c2c6481af
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland.c
@@ -0,0 +1,652 @@
+/*
+ * Copyright © 2011-2014 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.
+ */
+
+#include "xwayland.h"
+
+#include <stdio.h>
+
+#include <selection.h>
+#include <micmap.h>
+#include <misyncshm.h>
+#include <compositeext.h>
+#include <glx_extinit.h>
+
+void
+ddxGiveUp(enum ExitCode error)
+{
+}
+
+void
+AbortDDX(enum ExitCode error)
+{
+ ddxGiveUp(error);
+}
+
+void
+OsVendorInit(void)
+{
+}
+
+void
+OsVendorFatalError(const char *f, va_list args)
+{
+}
+
+#if defined(DDXBEFORERESET)
+void
+ddxBeforeReset(void)
+{
+ return;
+}
+#endif
+
+void
+ddxUseMsg(void)
+{
+ ErrorF("-rootless run rootless, requires wm support\n");
+ ErrorF("-wm fd create X client for wm on given fd\n");
+ ErrorF("-listen fd add give fd as a listen socket\n");
+}
+
+int
+ddxProcessArgument(int argc, char *argv[], int i)
+{
+ if (strcmp(argv[i], "-rootless") == 0) {
+ return 1;
+ }
+ else if (strcmp(argv[i], "-listen") == 0) {
+ NoListenAll = TRUE;
+ return 2;
+ }
+ else if (strcmp(argv[i], "-wm") == 0) {
+ return 2;
+ }
+ else if (strcmp(argv[i], "-shm") == 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static DevPrivateKeyRec xwl_window_private_key;
+static DevPrivateKeyRec xwl_screen_private_key;
+static DevPrivateKeyRec xwl_pixmap_private_key;
+
+struct xwl_screen *
+xwl_screen_get(ScreenPtr screen)
+{
+ return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
+}
+
+static Bool
+xwl_close_screen(ScreenPtr screen)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_output *xwl_output, *next_xwl_output;
+ struct xwl_seat *xwl_seat, *next_xwl_seat;
+
+ xorg_list_for_each_entry_safe(xwl_output, next_xwl_output,
+ &xwl_screen->output_list, link)
+ xwl_output_destroy(xwl_output);
+
+ xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat,
+ &xwl_screen->seat_list, link)
+ xwl_seat_destroy(xwl_seat);
+
+ wl_display_disconnect(xwl_screen->display);
+
+ screen->CloseScreen = xwl_screen->CloseScreen;
+ free(xwl_screen);
+
+ return screen->CloseScreen(screen);
+}
+
+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 void
+shell_surface_ping(void *data,
+ struct wl_shell_surface *shell_surface, uint32_t serial)
+{
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+shell_surface_configure(void *data,
+ struct wl_shell_surface *wl_shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+}
+
+static void
+shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface)
+{
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+ shell_surface_ping,
+ shell_surface_configure,
+ shell_surface_popup_done
+};
+
+void
+xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap)
+{
+ dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key, xwl_pixmap);
+}
+
+struct xwl_pixmap *
+xwl_pixmap_get(PixmapPtr pixmap)
+{
+ return dixLookupPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key);
+}
+
+static void
+send_surface_id_event(struct xwl_window *xwl_window)
+{
+ static const char atom_name[] = "WL_SURFACE_ID";
+ static Atom type_atom;
+ DeviceIntPtr dev;
+ xEvent e;
+
+ if (type_atom == None)
+ type_atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
+
+ e.u.u.type = ClientMessage;
+ e.u.u.detail = 32;
+ e.u.clientMessage.window = xwl_window->window->drawable.id;
+ e.u.clientMessage.u.l.type = type_atom;
+ e.u.clientMessage.u.l.longs0 =
+ wl_proxy_get_id((struct wl_proxy *) xwl_window->surface);
+ e.u.clientMessage.u.l.longs1 = 0;
+ e.u.clientMessage.u.l.longs2 = 0;
+ e.u.clientMessage.u.l.longs3 = 0;
+ e.u.clientMessage.u.l.longs4 = 0;
+
+ dev = PickPointer(serverClient);
+ DeliverEventsToWindow(dev, xwl_window->xwl_screen->screen->root,
+ &e, 1, SubstructureRedirectMask, NullGrab);
+}
+
+static Bool
+xwl_realize_window(WindowPtr window)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ struct xwl_screen *xwl_screen;
+ struct xwl_window *xwl_window;
+ struct wl_region *region;
+ 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->rootless && !window->parent) {
+ ErrorF("Clearing root clip\n");
+ RegionNull(&window->clipList);
+ RegionNull(&window->borderClip);
+ RegionNull(&window->winSize);
+ }
+
+ if (xwl_screen->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->rootless) {
+ xwl_window->shell_surface =
+ wl_shell_get_shell_surface(xwl_screen->shell, xwl_window->surface);
+ wl_shell_surface_add_listener(xwl_window->shell_surface,
+ &shell_surface_listener, xwl_window);
+
+ wl_shell_surface_set_toplevel(xwl_window->shell_surface);
+
+ region = wl_compositor_create_region(xwl_screen->compositor);
+ wl_region_add(region, 0, 0,
+ window->drawable.width, window->drawable.height);
+ wl_surface_set_opaque_region(xwl_window->surface, region);
+ wl_region_destroy(region);
+ }
+
+ wl_display_flush(xwl_screen->display);
+
+ send_surface_id_event(xwl_window);
+
+ wl_surface_set_user_data(xwl_window->surface, xwl_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_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;
+ }
+
+ 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;
+
+ wl_surface_destroy(xwl_window->surface);
+ 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 Bool
+xwl_save_screen(ScreenPtr pScreen, int on)
+{
+ return TRUE;
+}
+
+static void
+xwl_screen_post_damage(struct xwl_screen *xwl_screen)
+{
+ struct xwl_window *xwl_window;
+ RegionPtr region;
+ BoxPtr box;
+ int count, i;
+ struct wl_buffer *buffer;
+ PixmapPtr pixmap;
+
+ xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
+ link_damage) {
+ region = DamageRegion(xwl_window->damage);
+ count = RegionNumRects(region);
+
+ pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
+
+ buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
+ wl_surface_attach(xwl_window->surface, buffer, 0, 0);
+ 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_commit(xwl_window->surface);
+ DamageEmpty(xwl_window->damage);
+ }
+
+ xorg_list_init(&xwl_screen->damage_window_list);
+}
+
+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);
+ }
+ else if (strcmp(interface, "wl_shell") == 0) {
+ xwl_screen->shell =
+ wl_registry_bind(registry, id, &wl_shell_interface, 1);
+ }
+ else if (strcmp(interface, "wl_output") == 0 && version >= 2) {
+ xwl_output_create(xwl_screen, id);
+ xwl_screen->expecting_event++;
+ }
+}
+
+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_read_events(xwl_screen->display);
+ if (ret == -1)
+ FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+
+ xwl_screen->prepare_read = 0;
+
+ ret = wl_display_dispatch_pending(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;
+
+ xwl_screen_post_damage(xwl_screen);
+
+ while (xwl_screen->prepare_read == 0 &&
+ wl_display_prepare_read(xwl_screen->display) == -1) {
+ ret = wl_display_dispatch_pending(xwl_screen->display);
+ if (ret == -1)
+ FatalError("failed to dispatch Wayland events: %s\n",
+ strerror(errno));
+ }
+
+ xwl_screen->prepare_read = 1;
+
+ ret = wl_display_flush(xwl_screen->display);
+ if (ret == -1)
+ FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
+}
+
+static CARD32
+add_client_fd(OsTimerPtr timer, CARD32 time, void *arg)
+{
+ struct xwl_screen *xwl_screen = arg;
+
+ if (!AddClientOnOpenFD(xwl_screen->wm_fd))
+ FatalError("Failed to add wm client\n");
+
+ TimerFree(timer);
+
+ return 0;
+}
+
+static void
+listen_on_fds(struct xwl_screen *xwl_screen)
+{
+ int i;
+
+ for (i = 0; i < xwl_screen->listen_fd_count; i++)
+ ListenOnOpenFD(xwl_screen->listen_fds[i], TRUE);
+}
+
+static void
+wm_selection_callback(CallbackListPtr *p, void *data, void *arg)
+{
+ SelectionInfoRec *info = arg;
+ struct xwl_screen *xwl_screen = data;
+ static const char atom_name[] = "WM_S0";
+ static Atom atom_wm_s0;
+
+ if (atom_wm_s0 == None)
+ atom_wm_s0 = MakeAtom(atom_name, strlen(atom_name), TRUE);
+ if (info->selection->selection != atom_wm_s0 ||
+ info->kind != SelectionSetOwner)
+ return;
+
+ listen_on_fds(xwl_screen);
+
+ DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
+}
+
+static Bool
+xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
+{
+ struct xwl_screen *xwl_screen;
+ Pixel red_mask, blue_mask, green_mask;
+ int ret, bpc, green_bpc, i;
+
+ xwl_screen = calloc(sizeof *xwl_screen, 1);
+ xwl_screen->wm_fd = -1;
+ if (xwl_screen == NULL)
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
+ xwl_screen->screen = pScreen;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-rootless") == 0) {
+ xwl_screen->rootless = 1;
+ }
+ else if (strcmp(argv[i], "-wm") == 0) {
+ xwl_screen->wm_fd = atoi(argv[i + 1]);
+ i++;
+ TimerSet(NULL, 0, 1, add_client_fd, xwl_screen);
+ }
+ else if (strcmp(argv[i], "-listen") == 0) {
+ if (xwl_screen->listen_fd_count ==
+ ARRAY_SIZE(xwl_screen->listen_fds))
+ FatalError("Too many -listen arguments given, max is %ld\n",
+ ARRAY_SIZE(xwl_screen->listen_fds));
+
+ xwl_screen->listen_fds[xwl_screen->listen_fd_count++] =
+ atoi(argv[i + 1]);
+ i++;
+ }
+ }
+
+ if (xwl_screen->listen_fd_count > 0) {
+ if (xwl_screen->wm_fd >= 0)
+ AddCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
+ else
+ listen_on_fds(xwl_screen);
+ }
+
+ xorg_list_init(&xwl_screen->output_list);
+ xorg_list_init(&xwl_screen->seat_list);
+ xorg_list_init(&xwl_screen->damage_window_list);
+ xwl_screen->depth = 24;
+
+ xwl_screen->display = wl_display_connect(NULL);
+ if (xwl_screen->display == NULL) {
+ ErrorF("could not connect to wayland server\n");
+ return FALSE;
+ }
+
+ if (!xwl_screen_init_output(xwl_screen))
+ return FALSE;
+
+ xwl_screen->expecting_event = 0;
+ xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
+ wl_registry_add_listener(xwl_screen->registry,
+ &registry_listener, xwl_screen);
+ ret = wl_display_roundtrip(xwl_screen->display);
+ if (ret == -1) {
+ ErrorF("could not connect to wayland server\n");
+ return FALSE;
+ }
+
+ while (xwl_screen->expecting_event > 0)
+ wl_display_roundtrip(xwl_screen->display);
+
+ bpc = xwl_screen->depth / 3;
+ green_bpc = xwl_screen->depth - 2 * bpc;
+ blue_mask = (1 << bpc) - 1;
+ green_mask = ((1 << green_bpc) - 1) << bpc;
+ red_mask = blue_mask << (green_bpc + bpc);
+
+ miSetVisualTypesAndMasks(xwl_screen->depth,
+ ((1 << TrueColor) | (1 << DirectColor)),
+ green_bpc, TrueColor,
+ red_mask, green_mask, blue_mask);
+
+ miSetPixmapDepths();
+
+ ret = fbScreenInit(pScreen, NULL,
+ xwl_screen->width, xwl_screen->height,
+ 96, 96, 0,
+ BitsPerPixel(xwl_screen->depth));
+ if (!ret)
+ return FALSE;
+
+ fbPictureInit(pScreen, 0, 0);
+
+ if (!miSyncShmScreenInit(pScreen))
+ return FALSE;
+
+ xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
+ AddGeneralSocket(xwl_screen->wayland_fd);
+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
+
+ pScreen->SaveScreen = xwl_save_screen;
+
+ pScreen->blackPixel = 0;
+ pScreen->whitePixel = 1;
+
+ ret = fbCreateDefColormap(pScreen);
+
+ if (!xwl_screen_init_cursor(xwl_screen))
+ return FALSE;
+
+ xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = xwl_shm_create_screen_resources;
+ pScreen->CreatePixmap = xwl_shm_create_pixmap;
+ pScreen->DestroyPixmap = xwl_shm_destroy_pixmap;
+
+ xwl_screen->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = xwl_realize_window;
+
+ xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = xwl_unrealize_window;
+
+ xwl_screen->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xwl_close_screen;
+
+ return ret;
+}
+
+static void _X_ATTRIBUTE_PRINTF(1, 0)
+xwl_log_handler(const char *format, va_list args)
+{
+ char msg[256];
+
+ vsnprintf(msg, sizeof msg, format, args);
+ FatalError("%s", msg);
+}
+
+static const ExtensionModule glx_extension[] = {
+ { GlxExtensionInit, "GLX", &noGlxExtension },
+};
+
+void
+InitOutput(ScreenInfo * screen_info, int argc, char **argv)
+{
+ int depths[] = { 1, 4, 8, 15, 16, 24, 32 };
+ int bpp[] = { 1, 8, 8, 16, 16, 32, 32 };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(depths); i++) {
+ screen_info->formats[i].depth = depths[i];
+ screen_info->formats[i].bitsPerPixel = bpp[i];
+ screen_info->formats[i].scanlinePad = BITMAP_SCANLINE_PAD;
+ }
+
+ screen_info->imageByteOrder = IMAGE_BYTE_ORDER;
+ screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ screen_info->bitmapBitOrder = BITMAP_BIT_ORDER;
+ screen_info->numPixmapFormats = ARRAY_SIZE(depths);
+
+ LoadExtensionList(glx_extension, ARRAY_SIZE(glx_extension), FALSE);
+
+ /* Cast away warning from missing printf annotation for
+ * wl_log_func_t. Wayland 1.5 will have the annotation, so we can
+ * remove the cast and require that when it's released. */
+ wl_log_set_handler_client((void *) xwl_log_handler);
+
+ if (AddScreen(xwl_screen_init, argc, argv) == -1) {
+ FatalError("Couldn't add screen\n");
+ }
+}
diff --git a/xorg-server/hw/xwayland/xwayland.h b/xorg-server/hw/xwayland/xwayland.h
new file mode 100644
index 000000000..8157e71ff
--- /dev/null
+++ b/xorg-server/hw/xwayland/xwayland.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright © 2014 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.
+ */
+
+#ifndef XWAYLAND_H
+#define XWAYLAND_H
+
+#include <dix-config.h>
+#include <xorg-server.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <wayland-client.h>
+
+#include <X11/X.h>
+
+#include <fb.h>
+#include <input.h>
+#include <dix.h>
+#include <randrstr.h>
+#include <exevents.h>
+
+struct xwl_screen {
+ int width;
+ int height;
+ int depth;
+ ScreenPtr screen;
+ WindowPtr pointer_limbo_window;
+ int expecting_event;
+
+ int wm_fd;
+ int listen_fds[5];
+ int listen_fd_count;
+ int rootless;
+
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ XYToWindowProcPtr XYToWindow;
+
+ struct xorg_list output_list;
+ struct xorg_list seat_list;
+ struct xorg_list damage_window_list;
+
+ int wayland_fd;
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_registry *input_registry;
+ struct wl_compositor *compositor;
+ struct wl_shm *shm;
+ struct wl_shell *shell;
+
+ uint32_t serial;
+
+#define XWL_FORMAT_ARGB8888 (1 << 0)
+#define XWL_FORMAT_XRGB8888 (1 << 1)
+#define XWL_FORMAT_RGB565 (1 << 2)
+
+ int prepare_read;
+};
+
+struct xwl_window {
+ struct xwl_screen *xwl_screen;
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+ WindowPtr window;
+ DamagePtr damage;
+ struct xorg_list link_damage;
+};
+
+#define MODIFIER_META 0x01
+
+struct xwl_seat {
+ DeviceIntPtr pointer;
+ DeviceIntPtr keyboard;
+ 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_output {
+ struct xorg_list link;
+ struct wl_output *output;
+ struct xwl_screen *xwl_screen;
+ RROutputPtr randr_output;
+ RRCrtcPtr randr_crtc;
+ int32_t x, y, width, height;
+ Rotation rotation;
+};
+
+struct xwl_pixmap;
+
+Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
+
+struct xwl_screen *xwl_screen_get(ScreenPtr screen);
+
+void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
+
+void xwl_seat_destroy(struct xwl_seat *xwl_seat);
+
+Bool xwl_screen_init_output(struct xwl_screen *xwl_screen);
+
+struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen,
+ uint32_t id);
+
+void xwl_output_destroy(struct xwl_output *xwl_output);
+
+RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
+ float VRefresh, Bool Reduced, Bool Interlaced);
+
+void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);
+struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);
+
+
+Bool xwl_shm_create_screen_resources(ScreenPtr screen);
+PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height,
+ int depth, unsigned int hint);
+Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap);
+struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap);
+
+
+#endif
diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am
index 7f0eaf097..cf42cfd2d 100644
--- a/xorg-server/hw/xwin/Makefile.am
+++ b/xorg-server/hw/xwin/Makefile.am
@@ -127,10 +127,7 @@ SRCS = InitInput.c \
winresource.h \
winwindow.h \
XWin.rc \
- $(top_srcdir)/Xext/dpmsstubs.c \
- $(top_srcdir)/Xi/stubs.c \
$(top_srcdir)/mi/miinitext.c \
- $(top_srcdir)/fb/fbcmap_mi.c \
$(SRCS_CLIPBOARD) \
$(SRCS_MULTIWINDOW) \
$(SRCS_MULTIWINDOWEXTWM) \
@@ -153,12 +150,14 @@ XWin_SOURCES = $(SRCS)
AM_CPPFLAGS = -I$(top_srcdir)/miext/rootless
XWIN_SYS_LIBS += -ldxguid
-XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la
-
+XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la \
+ $(top_builddir)/Xext/libXextdpmsstubs.la \
+ $(top_builddir)/Xi/libXistubs.la
XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS)
XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
XWin_LDFLAGS = -mwindows -static -Wl,--disable-stdcall-fixup
+
.rc.o:
$(AM_V_GEN)$(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index 36463f2d1..cbf949b53 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -607,6 +607,7 @@ extern int GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type);
void FixUpEventFromWindow(SpritePtr pSprite,
xEvent *xE,
WindowPtr pWin, Window child, Bool calcChild);
+extern Bool PointInBorderSize(WindowPtr pWin, int x, int y);
extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
extern int EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win);
extern Bool ActivatePassiveGrab(DeviceIntPtr dev, GrabPtr grab,
diff --git a/xorg-server/include/opaque.h b/xorg-server/include/opaque.h
index 7ec1d850f..6b8071c5b 100644
--- a/xorg-server/include/opaque.h
+++ b/xorg-server/include/opaque.h
@@ -51,6 +51,7 @@ extern _X_EXPORT int defaultScreenSaverBlanking;
extern _X_EXPORT int defaultScreenSaverAllowExposures;
extern _X_EXPORT const char *display;
extern _X_EXPORT int displayfd;
+extern _X_EXPORT Bool explicit_display;
extern _X_EXPORT int defaultBackingStore;
extern _X_EXPORT Bool disableBackingStore;
diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h
index 86da78966..6acdadd7a 100644
--- a/xorg-server/include/scrnintstr.h
+++ b/xorg-server/include/scrnintstr.h
@@ -353,6 +353,11 @@ typedef Bool (*StopPixmapTrackingProcPtr)(PixmapPtr, PixmapPtr);
typedef Bool (*ReplaceScanoutPixmapProcPtr)(DrawablePtr, PixmapPtr, Bool);
+typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen,
+ SpritePtr pSprite, int x, int y);
+
+typedef int (*NameWindowPixmapProcPtr)(WindowPtr, PixmapPtr, CARD32);
+
typedef struct _Screen {
int myNum; /* index of this instance in Screens[] */
ATOM id;
@@ -463,6 +468,7 @@ typedef struct _Screen {
SetWindowPixmapProcPtr SetWindowPixmap;
GetScreenPixmapProcPtr GetScreenPixmap;
SetScreenPixmapProcPtr SetScreenPixmap;
+ NameWindowPixmapProcPtr NameWindowPixmap;
PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */
@@ -513,6 +519,7 @@ typedef struct _Screen {
struct xorg_list offload_head;
ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
+ XYToWindowProcPtr XYToWindow;
} ScreenRec;
static inline RegionPtr
diff --git a/xorg-server/include/xorg-config.h.in b/xorg-server/include/xorg-config.h.in
index 77a1aae55..629ae4057 100644
--- a/xorg-server/include/xorg-config.h.in
+++ b/xorg-server/include/xorg-config.h.in
@@ -45,9 +45,18 @@
/* Path to installed libraries. */
#undef DEFAULT_LIBRARY_PATH
-/* Path to server log file. */
+/* Default log location */
+#undef DEFAULT_LOGDIR
+
+/* Default logfile prefix */
#undef DEFAULT_LOGPREFIX
+/* Default XDG_DATA dir under HOME */
+#undef DEFAULT_XDG_DATA_HOME
+
+/* Default log dir under XDG_DATA_HOME */
+#undef DEFAULT_XDG_DATA_HOME_LOGDIR
+
/* Building DRI-capable DDX. */
#undef XF86DRI
diff --git a/xorg-server/include/xwin-config.h.in b/xorg-server/include/xwin-config.h.in
index 176c01980..a5e6b17b3 100644
--- a/xorg-server/include/xwin-config.h.in
+++ b/xorg-server/include/xwin-config.h.in
@@ -26,8 +26,5 @@
/* Vendor web address for support */
#undef __VENDORDWEBSUPPORT__
-/* Default log location */
-#undef DEFAULT_LOGDIR
-
/* Whether we should re-locate the root to where the executable lives */
#undef RELOCATE_PROJECTROOT
diff --git a/xorg-server/mi/mi.h b/xorg-server/mi/mi.h
index 950ee3812..1209a16c4 100644
--- a/xorg-server/mi/mi.h
+++ b/xorg-server/mi/mi.h
@@ -507,6 +507,10 @@ extern _X_EXPORT void miMarkUnrealizedWindow(WindowPtr /*pChild */ ,
extern _X_EXPORT void miSegregateChildren(WindowPtr pWin, RegionPtr pReg,
int depth);
+extern _X_EXPORT WindowPtr miSpriteTrace(SpritePtr pSprite, int x, int y);
+
+extern _X_EXPORT WindowPtr miXYToWindow(ScreenPtr pScreen, SpritePtr pSprite, int x, int y);
+
/* mizerarc.c */
extern _X_EXPORT void miZeroPolyArc(DrawablePtr /*pDraw */ ,
diff --git a/xorg-server/mi/miscrinit.c b/xorg-server/mi/miscrinit.c
index 6aed52f51..00c15f713 100644
--- a/xorg-server/mi/miscrinit.c
+++ b/xorg-server/mi/miscrinit.c
@@ -272,6 +272,7 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */
pScreen->ChangeBorderWidth = miChangeBorderWidth;
pScreen->SetShape = miSetShape;
pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
+ pScreen->XYToWindow = miXYToWindow;
miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
diff --git a/xorg-server/mi/miwindow.c b/xorg-server/mi/miwindow.c
index 697ffbc26..951b8c519 100644
--- a/xorg-server/mi/miwindow.c
+++ b/xorg-server/mi/miwindow.c
@@ -57,6 +57,7 @@ SOFTWARE.
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "mivalidate.h"
+#include "inputstr.h"
void
miClearToBackground(WindowPtr pWin,
@@ -758,3 +759,68 @@ miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
miSegregateChildren(pChild, pReg, depth);
}
}
+
+WindowPtr
+miSpriteTrace(SpritePtr pSprite, int x, int y)
+{
+ WindowPtr pWin;
+ BoxRec box;
+
+ pWin = DeepestSpriteWin(pSprite);
+ while (pWin) {
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
+ (x < pWin->drawable.x + (int) pWin->drawable.width +
+ wBorderWidth(pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
+ (y < pWin->drawable.y + (int) pWin->drawable.height +
+ wBorderWidth(pWin))
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ RegionContainsPoint(wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#ifdef ROOTLESS
+ /* In rootless mode windows may be offscreen, even when
+ * they're in X's stack. (E.g. if the native window system
+ * implements some form of virtual desktop system).
+ */
+ && !pWin->rootlessUnhittable
+#endif
+ ) {
+ if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
+ pSprite->spriteTraceSize += 10;
+ pSprite->spriteTrace = realloc(pSprite->spriteTrace,
+ pSprite->spriteTraceSize *
+ sizeof(WindowPtr));
+ }
+ pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return DeepestSpriteWin(pSprite);
+}
+
+/**
+ * Traversed from the root window to the window at the position x/y. While
+ * traversing, it sets up the traversal history in the spriteTrace array.
+ * After completing, the spriteTrace history is set in the following way:
+ * spriteTrace[0] ... root window
+ * spriteTrace[1] ... top level window that encloses x/y
+ * ...
+ * spriteTrace[spriteTraceGood - 1] ... window at x/y
+ *
+ * @returns the window at the given coordinates.
+ */
+WindowPtr
+miXYToWindow(ScreenPtr pScreen, SpritePtr pSprite, int x, int y)
+{
+ pSprite->spriteTraceGood = 1; /* root window still there */
+ return miSpriteTrace(pSprite, x, y);
+}
diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c
index b3640b8e4..e914d9d94 100644
--- a/xorg-server/os/connection.c
+++ b/xorg-server/os/connection.c
@@ -352,8 +352,8 @@ void
NotifyParentProcess(void)
{
#if !defined(WIN32)
- if (dynamic_display[0]) {
- write(displayfd, dynamic_display, strlen(dynamic_display));
+ if (displayfd >= 0) {
+ write(displayfd, display, strlen(display));
write(displayfd, "\n", 1);
close(displayfd);
}
@@ -405,18 +405,18 @@ CreateWellKnownSockets(void)
FD_ZERO(&WellKnownConnections);
/* display is initialized to "0" by main(). It is then set to the display
- * number if specified on the command line, or to NULL when the -displayfd
- * option is used. */
+ * number if specified on the command line. */
+
if (NoListenAll) {
ListenTransCount = 0;
}
- else if (display) {
+ else if ((displayfd < 0) || explicit_display) {
if (TryCreateSocket(atoi(display), &partial) &&
ListenTransCount >= 1)
if (!PartialNetwork && partial)
FatalError ("Failed to establish all listening sockets");
}
- else { /* -displayfd */
+ else { /* -displayfd and no explicit display number */
Bool found = 0;
for (i = 0; i < 65535 - X_TCP_PORT; i++) {
if (TryCreateSocket(i, &partial) && !partial) {
diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c
index c513968ad..6e6974e89 100644
--- a/xorg-server/os/utils.c
+++ b/xorg-server/os/utils.c
@@ -666,6 +666,7 @@ ProcessCommandLine(int argc, char *argv[])
else if (argv[i][0] == ':') {
/* initialize display */
display = argv[i];
+ explicit_display = TRUE;
display++;
if (!VerifyDisplayName(display)) {
ErrorF("Bad display name: %s\n", display);
@@ -736,7 +737,6 @@ ProcessCommandLine(int argc, char *argv[])
else if (strcmp(argv[i], "-displayfd") == 0) {
if (++i < argc) {
displayfd = atoi(argv[i]);
- display = NULL;
#ifdef LOCK_SERVER
nolock = TRUE;
#endif
diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am
index 88fb6aa96..3ad24d9ec 100644
--- a/xorg-server/test/Makefile.am
+++ b/xorg-server/test/Makefile.am
@@ -70,9 +70,7 @@ endif
else
nodist_libxservertest_la_SOURCES = \
ddxstubs.c \
- $(top_srcdir)/mi/miinitext.c \
- $(top_srcdir)/Xext/dpmsstubs.c \
- $(top_srcdir)/Xi/stubs.c
+ $(top_srcdir)/mi/miinitext.c
libxservertest_la_LIBADD += \
$(top_builddir)/damageext/libdamageext.la \
@@ -83,7 +81,9 @@ libxservertest_la_LIBADD += \
$(top_builddir)/randr/librandr.la \
$(top_builddir)/render/librender.la \
$(top_builddir)/Xext/libXext.la \
+ $(top_builddir)/Xext/libXextdpmsstubs.la \
$(top_builddir)/Xi/libXi.la \
+ $(top_builddir)/Xi/libXistubs.la \
$(top_builddir)/xfixes/libxfixes.la \
$(top_builddir)/xkb/libxkb.la \
$(top_builddir)/xkb/libxkbstubs.la
diff --git a/xorg-server/xkb/xkbAccessX.c b/xorg-server/xkb/xkbAccessX.c
index cb4bca008..5f3de0d9e 100644
--- a/xorg-server/xkb/xkbAccessX.c
+++ b/xorg-server/xkb/xkbAccessX.c
@@ -711,7 +711,7 @@ ProcessPointerEvent(InternalEvent *ev, DeviceIntPtr mouse)
xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse);
DeviceEvent *event = &ev->device_event;
- dev = (IsMaster(mouse) || IsFloating(mouse)) ? mouse : GetMaster(mouse, MASTER_KEYBOARD);
+ dev = IsFloating(mouse) ? mouse : GetMaster(mouse, MASTER_KEYBOARD);
if (dev && dev->key) {
xkbi = dev->key->xkbInfo;