aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/ephyr
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr')
-rw-r--r--xorg-server/hw/kdrive/ephyr/Makefile.am91
-rw-r--r--xorg-server/hw/kdrive/ephyr/Makefile.in934
-rw-r--r--xorg-server/hw/kdrive/ephyr/README73
-rw-r--r--xorg-server/hw/kdrive/ephyr/XF86dri.c654
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c1155
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.h202
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_draw.c524
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrdri.c291
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrdri.h75
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrdriext.c1443
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrdriext.h42
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrglxext.c732
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrglxext.h35
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrhostglx.c703
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrhostglx.h76
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c1014
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrhostvideo.h238
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrinit.c345
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrlog.h67
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c1278
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c1434
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.h261
-rw-r--r--xorg-server/hw/kdrive/ephyr/os.c51
23 files changed, 11718 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am
new file mode 100644
index 000000000..7a56d34a8
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/Makefile.am
@@ -0,0 +1,91 @@
+INCLUDES = \
+ @KDRIVE_INCS@ \
+ @KDRIVE_CFLAGS@ \
+ -I$(srcdir)/../../../exa
+
+if XV
+ LIBXEPHYR_HOSTXV=libxephyr-hostxv.a
+else
+ LIBXEPHYR_HOSTXV=
+endif
+
+if XEPHYR_HAS_DRI
+ LIBXEPHYR_HOSTDRI=libxephyr-hostdri.a
+else
+ LIBXEPHYR_HOSTDRI=
+endif
+
+noinst_LIBRARIES = libxephyr-hostx.a $(LIBXEPHYR_HOSTXV) $(LIBXEPHYR_HOSTDRI) libxephyr.a
+
+bin_PROGRAMS = Xephyr
+
+libxephyr_hostx_a_SOURCES = \
+ hostx.c \
+ hostx.h
+
+libxephyr_hostxv_a_INCLUDES = @XEPHYR_INCS@
+
+if XV
+libxephyr_hostxv_a_SOURCES= \
+ ephyrhostvideo.c \
+ ephyrhostvideo.h
+endif
+
+if XEPHYR_HAS_DRI
+
+libxephyr_hostdri_a_SOURCES= \
+ephyrdriext.c \
+ephyrdriext.h \
+ephyrdri.c \
+ephyrdri.h \
+XF86dri.c \
+ephyrglxext.c \
+ephyrglxext.h \
+ephyrhostglx.c \
+ephyrhostglx.h
+
+libxephyr_hostdri_a_CFLAGS= \
+-I$(top_srcdir) \
+@LIBDRM_CFLAGS@ \
+@DRIPROTO_CFLAGS@
+
+endif
+
+libxephyr_a_SOURCES = \
+ ephyr.c \
+ ephyr_draw.c \
+ ephyrvideo.c \
+ os.c \
+ hostx.h \
+ ephyr.h \
+ ephyrlog.h
+
+libxephyr_a_CFLAGS = \
+-I$(top_srcdir) \
+@LIBDRM_CFLAGS@
+
+Xephyr_SOURCES = \
+ ephyrinit.c
+
+Xephyr_LDADD = \
+ libxephyr.a \
+ libxephyr-hostx.a \
+ $(LIBXEPHYR_HOSTXV) \
+ $(LIBXEPHYR_HOSTDRI) \
+ ../../../exa/libexa.la \
+ @KDRIVE_LIBS@ \
+ @XEPHYR_LIBS@ \
+ @LIBDRM_LIBS@ \
+ @XEPHYR_DRI_LIBS@
+
+Xephyr_DEPENDENCIES = \
+ libxephyr.a \
+ libxephyr-hostx.a \
+ $(LIBXEPHYR_HOSTXV) \
+ $(LIBXEPHYR_HOSTDRI) \
+ @KDRIVE_LOCAL_LIBS@
+
+Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.in b/xorg-server/hw/kdrive/ephyr/Makefile.in
new file mode 100644
index 000000000..67efca081
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/Makefile.in
@@ -0,0 +1,934 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = Xephyr$(EXEEXT)
+subdir = hw/kdrive/ephyr
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \
+ $(top_builddir)/include/xorg-server.h \
+ $(top_builddir)/include/dix-config.h \
+ $(top_builddir)/include/xgl-config.h \
+ $(top_builddir)/include/xorg-config.h \
+ $(top_builddir)/include/xkb-config.h \
+ $(top_builddir)/include/xwin-config.h \
+ $(top_builddir)/include/kdrive-config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libxephyr_hostdri_a_AR = $(AR) $(ARFLAGS)
+libxephyr_hostdri_a_LIBADD =
+am__libxephyr_hostdri_a_SOURCES_DIST = ephyrdriext.c ephyrdriext.h \
+ ephyrdri.c ephyrdri.h XF86dri.c ephyrglxext.c ephyrglxext.h \
+ ephyrhostglx.c ephyrhostglx.h
+@XEPHYR_HAS_DRI_TRUE@am_libxephyr_hostdri_a_OBJECTS = libxephyr_hostdri_a-ephyrdriext.$(OBJEXT) \
+@XEPHYR_HAS_DRI_TRUE@ libxephyr_hostdri_a-ephyrdri.$(OBJEXT) \
+@XEPHYR_HAS_DRI_TRUE@ libxephyr_hostdri_a-XF86dri.$(OBJEXT) \
+@XEPHYR_HAS_DRI_TRUE@ libxephyr_hostdri_a-ephyrglxext.$(OBJEXT) \
+@XEPHYR_HAS_DRI_TRUE@ libxephyr_hostdri_a-ephyrhostglx.$(OBJEXT)
+libxephyr_hostdri_a_OBJECTS = $(am_libxephyr_hostdri_a_OBJECTS)
+libxephyr_hostx_a_AR = $(AR) $(ARFLAGS)
+libxephyr_hostx_a_LIBADD =
+am_libxephyr_hostx_a_OBJECTS = hostx.$(OBJEXT)
+libxephyr_hostx_a_OBJECTS = $(am_libxephyr_hostx_a_OBJECTS)
+libxephyr_hostxv_a_AR = $(AR) $(ARFLAGS)
+libxephyr_hostxv_a_LIBADD =
+am__libxephyr_hostxv_a_SOURCES_DIST = ephyrhostvideo.c \
+ ephyrhostvideo.h
+@XV_TRUE@am_libxephyr_hostxv_a_OBJECTS = ephyrhostvideo.$(OBJEXT)
+libxephyr_hostxv_a_OBJECTS = $(am_libxephyr_hostxv_a_OBJECTS)
+libxephyr_a_AR = $(AR) $(ARFLAGS)
+libxephyr_a_LIBADD =
+am_libxephyr_a_OBJECTS = libxephyr_a-ephyr.$(OBJEXT) \
+ libxephyr_a-ephyr_draw.$(OBJEXT) \
+ libxephyr_a-ephyrvideo.$(OBJEXT) libxephyr_a-os.$(OBJEXT)
+libxephyr_a_OBJECTS = $(am_libxephyr_a_OBJECTS)
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_Xephyr_OBJECTS = ephyrinit.$(OBJEXT)
+Xephyr_OBJECTS = $(am_Xephyr_OBJECTS)
+@XV_TRUE@am__DEPENDENCIES_1 = libxephyr-hostxv.a
+@XEPHYR_HAS_DRI_TRUE@am__DEPENDENCIES_2 = libxephyr-hostdri.a
+Xephyr_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(Xephyr_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libxephyr_hostdri_a_SOURCES) $(libxephyr_hostx_a_SOURCES) \
+ $(libxephyr_hostxv_a_SOURCES) $(libxephyr_a_SOURCES) \
+ $(Xephyr_SOURCES)
+DIST_SOURCES = $(am__libxephyr_hostdri_a_SOURCES_DIST) \
+ $(libxephyr_hostx_a_SOURCES) \
+ $(am__libxephyr_hostxv_a_SOURCES_DIST) $(libxephyr_a_SOURCES) \
+ $(Xephyr_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
+ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+APPDEFAULTDIR = @APPDEFAULTDIR@
+APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASE_FONT_PATH = @BASE_FONT_PATH@
+BUILD_DATE = @BUILD_DATE@
+BUILD_TIME = @BUILD_TIME@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DARWIN_LIBS = @DARWIN_LIBS@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@
+DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@
+DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DGA_CFLAGS = @DGA_CFLAGS@
+DGA_LIBS = @DGA_LIBS@
+DIX_CFLAGS = @DIX_CFLAGS@
+DLLTOOL = @DLLTOOL@
+DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@
+DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@
+DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@
+DMXMODULES_LIBS = @DMXMODULES_LIBS@
+DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@
+DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@
+DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@
+DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@
+DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
+DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
+DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
+DRIPROTO_LIBS = @DRIPROTO_LIBS@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
+DSYMUTIL = @DSYMUTIL@
+DTRACE = @DTRACE@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
+GLX_DEFINES = @GLX_DEFINES@
+GL_CFLAGS = @GL_CFLAGS@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+HAL_CFLAGS = @HAL_CFLAGS@
+HAL_LIBS = @HAL_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KDRIVE_CFLAGS = @KDRIVE_CFLAGS@
+KDRIVE_INCS = @KDRIVE_INCS@
+KDRIVE_LIBS = @KDRIVE_LIBS@
+KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@
+KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@
+KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@
+LAUNCHD = @LAUNCHD@
+LDFLAGS = @LDFLAGS@
+LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
+LIBDRM_LIBS = @LIBDRM_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_MAN_DIR = @LIB_MAN_DIR@
+LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
+LINUXDOC = @LINUXDOC@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKE_HTML = @MAKE_HTML@
+MAKE_PDF = @MAKE_PDF@
+MAKE_PS = @MAKE_PS@
+MAKE_TEXT = @MAKE_TEXT@
+MESA_SOURCE = @MESA_SOURCE@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MKDIR_P = @MKDIR_P@
+MKFONTDIR = @MKFONTDIR@
+MKFONTSCALE = @MKFONTSCALE@
+NMEDIT = @NMEDIT@
+OBJC = @OBJC@
+OBJCCLD = @OBJCCLD@
+OBJCDEPMODE = @OBJCDEPMODE@
+OBJCFLAGS = @OBJCFLAGS@
+OBJCLINK = @OBJCLINK@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
+PCIACCESS_LIBS = @PCIACCESS_LIBS@
+PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PROJECTROOT = @PROJECTROOT@
+PS2PDF = @PS2PDF@
+RANLIB = @RANLIB@
+RAWCPP = @RAWCPP@
+RAWCPPFLAGS = @RAWCPPFLAGS@
+SED = @SED@
+SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@
+SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@
+STRIP = @STRIP@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+UTILS_SYS_LIBS = @UTILS_SYS_LIBS@
+VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@
+VENDOR_NAME = @VENDOR_NAME@
+VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
+VENDOR_RELEASE = @VENDOR_RELEASE@
+VERSION = @VERSION@
+X11APP_ARCHS = @X11APP_ARCHS@
+X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@
+X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@
+XDMCP_CFLAGS = @XDMCP_CFLAGS@
+XDMCP_LIBS = @XDMCP_LIBS@
+XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@
+XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@
+XDMX_CFLAGS = @XDMX_CFLAGS@
+XDMX_LIBS = @XDMX_LIBS@
+XDMX_SYS_LIBS = @XDMX_SYS_LIBS@
+XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@
+XEGL_LIBS = @XEGL_LIBS@
+XEGL_SYS_LIBS = @XEGL_SYS_LIBS@
+XEPHYR_CFLAGS = @XEPHYR_CFLAGS@
+XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@
+XEPHYR_INCS = @XEPHYR_INCS@
+XEPHYR_LIBS = @XEPHYR_LIBS@
+XF86CONFIGFILE = @XF86CONFIGFILE@
+XF86MISC_CFLAGS = @XF86MISC_CFLAGS@
+XF86MISC_LIBS = @XF86MISC_LIBS@
+XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
+XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
+XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@
+XGLMODULES_LIBS = @XGLMODULES_LIBS@
+XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@
+XGLXMODULES_LIBS = @XGLXMODULES_LIBS@
+XGLX_LIBS = @XGLX_LIBS@
+XGLX_SYS_LIBS = @XGLX_SYS_LIBS@
+XGL_LIBS = @XGL_LIBS@
+XGL_MODULE_PATH = @XGL_MODULE_PATH@
+XGL_SYS_LIBS = @XGL_SYS_LIBS@
+XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@
+XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@
+XKB_COMPILED_DIR = @XKB_COMPILED_DIR@
+XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@
+XLIB_CFLAGS = @XLIB_CFLAGS@
+XLIB_LIBS = @XLIB_LIBS@
+XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@
+XNESTMODULES_LIBS = @XNESTMODULES_LIBS@
+XNEST_LIBS = @XNEST_LIBS@
+XNEST_SYS_LIBS = @XNEST_SYS_LIBS@
+XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@
+XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@
+XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@
+XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@
+XORG_CFLAGS = @XORG_CFLAGS@
+XORG_INCS = @XORG_INCS@
+XORG_LIBS = @XORG_LIBS@
+XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@
+XORG_MODULES_LIBS = @XORG_MODULES_LIBS@
+XORG_OS = @XORG_OS@
+XORG_OS_SUBDIR = @XORG_OS_SUBDIR@
+XORG_SYS_LIBS = @XORG_SYS_LIBS@
+XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@
+XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@
+XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@
+XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@
+XPRINT_CFLAGS = @XPRINT_CFLAGS@
+XPRINT_LIBS = @XPRINT_LIBS@
+XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@
+XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@
+XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@
+XSDL_INCS = @XSDL_INCS@
+XSDL_LIBS = @XSDL_LIBS@
+XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@
+XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@
+XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@
+XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@
+XSERVER_LIBS = @XSERVER_LIBS@
+XSERVER_SYS_LIBS = @XSERVER_SYS_LIBS@
+XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@
+XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@
+XVFB_LIBS = @XVFB_LIBS@
+XVFB_SYS_LIBS = @XVFB_SYS_LIBS@
+XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@
+XWINMODULES_LIBS = @XWINMODULES_LIBS@
+XWIN_LIBS = @XWIN_LIBS@
+XWIN_SERVER_NAME = @XWIN_SERVER_NAME@
+XWIN_SYS_LIBS = @XWIN_SYS_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+__XCONFIGFILE__ = @__XCONFIGFILE__@
+abi_ansic = @abi_ansic@
+abi_extension = @abi_extension@
+abi_font = @abi_font@
+abi_videodrv = @abi_videodrv@
+abi_xinput = @abi_xinput@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+driverdir = @driverdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+extdir = @extdir@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+launchagentsdir = @launchagentsdir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+logdir = @logdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sdkdir = @sdkdir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xglmoduledir = @xglmoduledir@
+xpconfigdir = @xpconfigdir@
+INCLUDES = \
+ @KDRIVE_INCS@ \
+ @KDRIVE_CFLAGS@ \
+ -I$(srcdir)/../../../exa
+
+@XV_FALSE@LIBXEPHYR_HOSTXV =
+@XV_TRUE@LIBXEPHYR_HOSTXV = libxephyr-hostxv.a
+@XEPHYR_HAS_DRI_FALSE@LIBXEPHYR_HOSTDRI =
+@XEPHYR_HAS_DRI_TRUE@LIBXEPHYR_HOSTDRI = libxephyr-hostdri.a
+noinst_LIBRARIES = libxephyr-hostx.a $(LIBXEPHYR_HOSTXV) $(LIBXEPHYR_HOSTDRI) libxephyr.a
+libxephyr_hostx_a_SOURCES = \
+ hostx.c \
+ hostx.h
+
+libxephyr_hostxv_a_INCLUDES = @XEPHYR_INCS@
+@XV_TRUE@libxephyr_hostxv_a_SOURCES = \
+@XV_TRUE@ ephyrhostvideo.c \
+@XV_TRUE@ ephyrhostvideo.h
+
+@XEPHYR_HAS_DRI_TRUE@libxephyr_hostdri_a_SOURCES = \
+@XEPHYR_HAS_DRI_TRUE@ephyrdriext.c \
+@XEPHYR_HAS_DRI_TRUE@ephyrdriext.h \
+@XEPHYR_HAS_DRI_TRUE@ephyrdri.c \
+@XEPHYR_HAS_DRI_TRUE@ephyrdri.h \
+@XEPHYR_HAS_DRI_TRUE@XF86dri.c \
+@XEPHYR_HAS_DRI_TRUE@ephyrglxext.c \
+@XEPHYR_HAS_DRI_TRUE@ephyrglxext.h \
+@XEPHYR_HAS_DRI_TRUE@ephyrhostglx.c \
+@XEPHYR_HAS_DRI_TRUE@ephyrhostglx.h
+
+@XEPHYR_HAS_DRI_TRUE@libxephyr_hostdri_a_CFLAGS = \
+@XEPHYR_HAS_DRI_TRUE@-I$(top_srcdir) \
+@XEPHYR_HAS_DRI_TRUE@@LIBDRM_CFLAGS@ \
+@XEPHYR_HAS_DRI_TRUE@@DRIPROTO_CFLAGS@
+
+libxephyr_a_SOURCES = \
+ ephyr.c \
+ ephyr_draw.c \
+ ephyrvideo.c \
+ os.c \
+ hostx.h \
+ ephyr.h \
+ ephyrlog.h
+
+libxephyr_a_CFLAGS = \
+-I$(top_srcdir) \
+@LIBDRM_CFLAGS@
+
+Xephyr_SOURCES = \
+ ephyrinit.c
+
+Xephyr_LDADD = \
+ libxephyr.a \
+ libxephyr-hostx.a \
+ $(LIBXEPHYR_HOSTXV) \
+ $(LIBXEPHYR_HOSTDRI) \
+ ../../../exa/libexa.la \
+ @KDRIVE_LIBS@ \
+ @XEPHYR_LIBS@ \
+ @LIBDRM_LIBS@ \
+ @XEPHYR_DRI_LIBS@
+
+Xephyr_DEPENDENCIES = \
+ libxephyr.a \
+ libxephyr-hostx.a \
+ $(LIBXEPHYR_HOSTXV) \
+ $(LIBXEPHYR_HOSTDRI) \
+ @KDRIVE_LOCAL_LIBS@
+
+Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign hw/kdrive/ephyr/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign hw/kdrive/ephyr/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libxephyr-hostdri.a: $(libxephyr_hostdri_a_OBJECTS) $(libxephyr_hostdri_a_DEPENDENCIES)
+ -rm -f libxephyr-hostdri.a
+ $(libxephyr_hostdri_a_AR) libxephyr-hostdri.a $(libxephyr_hostdri_a_OBJECTS) $(libxephyr_hostdri_a_LIBADD)
+ $(RANLIB) libxephyr-hostdri.a
+libxephyr-hostx.a: $(libxephyr_hostx_a_OBJECTS) $(libxephyr_hostx_a_DEPENDENCIES)
+ -rm -f libxephyr-hostx.a
+ $(libxephyr_hostx_a_AR) libxephyr-hostx.a $(libxephyr_hostx_a_OBJECTS) $(libxephyr_hostx_a_LIBADD)
+ $(RANLIB) libxephyr-hostx.a
+libxephyr-hostxv.a: $(libxephyr_hostxv_a_OBJECTS) $(libxephyr_hostxv_a_DEPENDENCIES)
+ -rm -f libxephyr-hostxv.a
+ $(libxephyr_hostxv_a_AR) libxephyr-hostxv.a $(libxephyr_hostxv_a_OBJECTS) $(libxephyr_hostxv_a_LIBADD)
+ $(RANLIB) libxephyr-hostxv.a
+libxephyr.a: $(libxephyr_a_OBJECTS) $(libxephyr_a_DEPENDENCIES)
+ -rm -f libxephyr.a
+ $(libxephyr_a_AR) libxephyr.a $(libxephyr_a_OBJECTS) $(libxephyr_a_LIBADD)
+ $(RANLIB) libxephyr.a
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+Xephyr$(EXEEXT): $(Xephyr_OBJECTS) $(Xephyr_DEPENDENCIES)
+ @rm -f Xephyr$(EXEEXT)
+ $(Xephyr_LINK) $(Xephyr_OBJECTS) $(Xephyr_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ephyrhostvideo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ephyrinit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_a-ephyr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_a-ephyr_draw.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_a-ephyrvideo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_a-os.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_hostdri_a-XF86dri.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libxephyr_hostdri_a-ephyrdriext.o: ephyrdriext.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrdriext.o -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Tpo -c -o libxephyr_hostdri_a-ephyrdriext.o `test -f 'ephyrdriext.c' || echo '$(srcdir)/'`ephyrdriext.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrdriext.c' object='libxephyr_hostdri_a-ephyrdriext.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrdriext.o `test -f 'ephyrdriext.c' || echo '$(srcdir)/'`ephyrdriext.c
+
+libxephyr_hostdri_a-ephyrdriext.obj: ephyrdriext.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrdriext.obj -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Tpo -c -o libxephyr_hostdri_a-ephyrdriext.obj `if test -f 'ephyrdriext.c'; then $(CYGPATH_W) 'ephyrdriext.c'; else $(CYGPATH_W) '$(srcdir)/ephyrdriext.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrdriext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrdriext.c' object='libxephyr_hostdri_a-ephyrdriext.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrdriext.obj `if test -f 'ephyrdriext.c'; then $(CYGPATH_W) 'ephyrdriext.c'; else $(CYGPATH_W) '$(srcdir)/ephyrdriext.c'; fi`
+
+libxephyr_hostdri_a-ephyrdri.o: ephyrdri.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrdri.o -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Tpo -c -o libxephyr_hostdri_a-ephyrdri.o `test -f 'ephyrdri.c' || echo '$(srcdir)/'`ephyrdri.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrdri.c' object='libxephyr_hostdri_a-ephyrdri.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrdri.o `test -f 'ephyrdri.c' || echo '$(srcdir)/'`ephyrdri.c
+
+libxephyr_hostdri_a-ephyrdri.obj: ephyrdri.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrdri.obj -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Tpo -c -o libxephyr_hostdri_a-ephyrdri.obj `if test -f 'ephyrdri.c'; then $(CYGPATH_W) 'ephyrdri.c'; else $(CYGPATH_W) '$(srcdir)/ephyrdri.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrdri.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrdri.c' object='libxephyr_hostdri_a-ephyrdri.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrdri.obj `if test -f 'ephyrdri.c'; then $(CYGPATH_W) 'ephyrdri.c'; else $(CYGPATH_W) '$(srcdir)/ephyrdri.c'; fi`
+
+libxephyr_hostdri_a-XF86dri.o: XF86dri.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-XF86dri.o -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-XF86dri.Tpo -c -o libxephyr_hostdri_a-XF86dri.o `test -f 'XF86dri.c' || echo '$(srcdir)/'`XF86dri.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-XF86dri.Tpo $(DEPDIR)/libxephyr_hostdri_a-XF86dri.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='XF86dri.c' object='libxephyr_hostdri_a-XF86dri.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-XF86dri.o `test -f 'XF86dri.c' || echo '$(srcdir)/'`XF86dri.c
+
+libxephyr_hostdri_a-XF86dri.obj: XF86dri.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-XF86dri.obj -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-XF86dri.Tpo -c -o libxephyr_hostdri_a-XF86dri.obj `if test -f 'XF86dri.c'; then $(CYGPATH_W) 'XF86dri.c'; else $(CYGPATH_W) '$(srcdir)/XF86dri.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-XF86dri.Tpo $(DEPDIR)/libxephyr_hostdri_a-XF86dri.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='XF86dri.c' object='libxephyr_hostdri_a-XF86dri.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-XF86dri.obj `if test -f 'XF86dri.c'; then $(CYGPATH_W) 'XF86dri.c'; else $(CYGPATH_W) '$(srcdir)/XF86dri.c'; fi`
+
+libxephyr_hostdri_a-ephyrglxext.o: ephyrglxext.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrglxext.o -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Tpo -c -o libxephyr_hostdri_a-ephyrglxext.o `test -f 'ephyrglxext.c' || echo '$(srcdir)/'`ephyrglxext.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrglxext.c' object='libxephyr_hostdri_a-ephyrglxext.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrglxext.o `test -f 'ephyrglxext.c' || echo '$(srcdir)/'`ephyrglxext.c
+
+libxephyr_hostdri_a-ephyrglxext.obj: ephyrglxext.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrglxext.obj -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Tpo -c -o libxephyr_hostdri_a-ephyrglxext.obj `if test -f 'ephyrglxext.c'; then $(CYGPATH_W) 'ephyrglxext.c'; else $(CYGPATH_W) '$(srcdir)/ephyrglxext.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrglxext.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrglxext.c' object='libxephyr_hostdri_a-ephyrglxext.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrglxext.obj `if test -f 'ephyrglxext.c'; then $(CYGPATH_W) 'ephyrglxext.c'; else $(CYGPATH_W) '$(srcdir)/ephyrglxext.c'; fi`
+
+libxephyr_hostdri_a-ephyrhostglx.o: ephyrhostglx.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrhostglx.o -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Tpo -c -o libxephyr_hostdri_a-ephyrhostglx.o `test -f 'ephyrhostglx.c' || echo '$(srcdir)/'`ephyrhostglx.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrhostglx.c' object='libxephyr_hostdri_a-ephyrhostglx.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrhostglx.o `test -f 'ephyrhostglx.c' || echo '$(srcdir)/'`ephyrhostglx.c
+
+libxephyr_hostdri_a-ephyrhostglx.obj: ephyrhostglx.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -MT libxephyr_hostdri_a-ephyrhostglx.obj -MD -MP -MF $(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Tpo -c -o libxephyr_hostdri_a-ephyrhostglx.obj `if test -f 'ephyrhostglx.c'; then $(CYGPATH_W) 'ephyrhostglx.c'; else $(CYGPATH_W) '$(srcdir)/ephyrhostglx.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Tpo $(DEPDIR)/libxephyr_hostdri_a-ephyrhostglx.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrhostglx.c' object='libxephyr_hostdri_a-ephyrhostglx.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_hostdri_a_CFLAGS) $(CFLAGS) -c -o libxephyr_hostdri_a-ephyrhostglx.obj `if test -f 'ephyrhostglx.c'; then $(CYGPATH_W) 'ephyrhostglx.c'; else $(CYGPATH_W) '$(srcdir)/ephyrhostglx.c'; fi`
+
+libxephyr_a-ephyr.o: ephyr.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-ephyr.o -MD -MP -MF $(DEPDIR)/libxephyr_a-ephyr.Tpo -c -o libxephyr_a-ephyr.o `test -f 'ephyr.c' || echo '$(srcdir)/'`ephyr.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-ephyr.Tpo $(DEPDIR)/libxephyr_a-ephyr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyr.c' object='libxephyr_a-ephyr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-ephyr.o `test -f 'ephyr.c' || echo '$(srcdir)/'`ephyr.c
+
+libxephyr_a-ephyr.obj: ephyr.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-ephyr.obj -MD -MP -MF $(DEPDIR)/libxephyr_a-ephyr.Tpo -c -o libxephyr_a-ephyr.obj `if test -f 'ephyr.c'; then $(CYGPATH_W) 'ephyr.c'; else $(CYGPATH_W) '$(srcdir)/ephyr.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-ephyr.Tpo $(DEPDIR)/libxephyr_a-ephyr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyr.c' object='libxephyr_a-ephyr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-ephyr.obj `if test -f 'ephyr.c'; then $(CYGPATH_W) 'ephyr.c'; else $(CYGPATH_W) '$(srcdir)/ephyr.c'; fi`
+
+libxephyr_a-ephyr_draw.o: ephyr_draw.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-ephyr_draw.o -MD -MP -MF $(DEPDIR)/libxephyr_a-ephyr_draw.Tpo -c -o libxephyr_a-ephyr_draw.o `test -f 'ephyr_draw.c' || echo '$(srcdir)/'`ephyr_draw.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-ephyr_draw.Tpo $(DEPDIR)/libxephyr_a-ephyr_draw.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyr_draw.c' object='libxephyr_a-ephyr_draw.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-ephyr_draw.o `test -f 'ephyr_draw.c' || echo '$(srcdir)/'`ephyr_draw.c
+
+libxephyr_a-ephyr_draw.obj: ephyr_draw.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-ephyr_draw.obj -MD -MP -MF $(DEPDIR)/libxephyr_a-ephyr_draw.Tpo -c -o libxephyr_a-ephyr_draw.obj `if test -f 'ephyr_draw.c'; then $(CYGPATH_W) 'ephyr_draw.c'; else $(CYGPATH_W) '$(srcdir)/ephyr_draw.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-ephyr_draw.Tpo $(DEPDIR)/libxephyr_a-ephyr_draw.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyr_draw.c' object='libxephyr_a-ephyr_draw.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-ephyr_draw.obj `if test -f 'ephyr_draw.c'; then $(CYGPATH_W) 'ephyr_draw.c'; else $(CYGPATH_W) '$(srcdir)/ephyr_draw.c'; fi`
+
+libxephyr_a-ephyrvideo.o: ephyrvideo.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-ephyrvideo.o -MD -MP -MF $(DEPDIR)/libxephyr_a-ephyrvideo.Tpo -c -o libxephyr_a-ephyrvideo.o `test -f 'ephyrvideo.c' || echo '$(srcdir)/'`ephyrvideo.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-ephyrvideo.Tpo $(DEPDIR)/libxephyr_a-ephyrvideo.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrvideo.c' object='libxephyr_a-ephyrvideo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-ephyrvideo.o `test -f 'ephyrvideo.c' || echo '$(srcdir)/'`ephyrvideo.c
+
+libxephyr_a-ephyrvideo.obj: ephyrvideo.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-ephyrvideo.obj -MD -MP -MF $(DEPDIR)/libxephyr_a-ephyrvideo.Tpo -c -o libxephyr_a-ephyrvideo.obj `if test -f 'ephyrvideo.c'; then $(CYGPATH_W) 'ephyrvideo.c'; else $(CYGPATH_W) '$(srcdir)/ephyrvideo.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-ephyrvideo.Tpo $(DEPDIR)/libxephyr_a-ephyrvideo.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ephyrvideo.c' object='libxephyr_a-ephyrvideo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-ephyrvideo.obj `if test -f 'ephyrvideo.c'; then $(CYGPATH_W) 'ephyrvideo.c'; else $(CYGPATH_W) '$(srcdir)/ephyrvideo.c'; fi`
+
+libxephyr_a-os.o: os.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-os.o -MD -MP -MF $(DEPDIR)/libxephyr_a-os.Tpo -c -o libxephyr_a-os.o `test -f 'os.c' || echo '$(srcdir)/'`os.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-os.Tpo $(DEPDIR)/libxephyr_a-os.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='os.c' object='libxephyr_a-os.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-os.o `test -f 'os.c' || echo '$(srcdir)/'`os.c
+
+libxephyr_a-os.obj: os.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -MT libxephyr_a-os.obj -MD -MP -MF $(DEPDIR)/libxephyr_a-os.Tpo -c -o libxephyr_a-os.obj `if test -f 'os.c'; then $(CYGPATH_W) 'os.c'; else $(CYGPATH_W) '$(srcdir)/os.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libxephyr_a-os.Tpo $(DEPDIR)/libxephyr_a-os.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='os.c' object='libxephyr_a-os.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxephyr_a_CFLAGS) $(CFLAGS) -c -o libxephyr_a-os.obj `if test -f 'os.c'; then $(CYGPATH_W) 'os.c'; else $(CYGPATH_W) '$(srcdir)/os.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool \
+ clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool clean-noinstLIBRARIES ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS
+
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/xorg-server/hw/kdrive/ephyr/README b/xorg-server/hw/kdrive/ephyr/README
new file mode 100644
index 000000000..6d6a222ef
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/README
@@ -0,0 +1,73 @@
+Xephyr README
+=============
+
+
+What Is It ?
+============
+
+Xephyr is a a kdrive server that outputs to a window on a pre-existing
+'host' X display. Think Xnest but with support for modern extensions
+like composite, damage and randr.
+
+Unlike Xnest which is an X proxy, i.e. limited to the
+capabilities of the host X server, Xephyr is a real X server which
+uses the host X server window as "framebuffer" via fast SHM XImages.
+
+It also has support for 'visually' debugging what the server is
+painting.
+
+
+How To Use
+==========
+
+You probably want to run like;
+
+Xephyr :1 -ac -screen 800x600 &
+
+Then set DISPLAY=:1 and run whatever X apps you like.
+
+Use 'xrandr' to change to orientation/size.
+
+There is a '-parent' switch which works just like Xnests ( for use
+with things like matchbox-nest - http://matchbox.handhelds.org ).
+
+There is also a '-host-cursor' switch to set 'cursor acceleration' -
+The host's cursor is reused. This is only really there to aid
+debugging by avoiding server paints for the cursor. Performance
+improvement is negiable.
+
+Send a SIGUSR1 to the server ( eg kill -USR1 `pidof Xephyr` ) to
+toggle the debugging mode. In this mode red rectangles are painted to
+screen areas getting painted before painting the actual content. The
+delay between this can be altered by setting a XEPHYR_PAUSE env var to
+a value in micro seconds.
+
+
+Caveats
+=======
+
+ - Depth is limited to being the same as the host.
+ *Update* As of 8/11/2004. Xephyr can now do 8bpp & 16bpp
+ on 24bpp host.
+
+ - Rotated displays are currently updated via full blits. This
+ is slower than a normal oprientated display. Debug mode will
+ therefor not be of much use rotated.
+
+ - The '-host-cursor' cursor is static in its appearence.
+
+ - The build gets a warning about 'nanosleep'. I think the various '-D'
+ build flags are causing this. I havn't figured as yet how to work
+ round it. It doesn't appear to break anything however.
+
+ - Keyboard handling is basic but works.
+
+ - Mouse button 5 probably wont work.
+
+
+
+
+
+Matthew Allum <mallum@o-hand.com> 2004
+
+
diff --git a/xorg-server/hw/kdrive/ephyr/XF86dri.c b/xorg-server/hw/kdrive/ephyr/XF86dri.c
new file mode 100644
index 000000000..63e630c9c
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/XF86dri.c
@@ -0,0 +1,654 @@
+/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+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, sub license, 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+/*
+ * This file has been copied from the mesa source tree and a little bit
+ * modified by:
+ *
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+/*
+ * including some server headers (like kdrive-config.h)
+ * might define the macro _XSERVER64
+ * on 64 bits machines. That macro must _NOT_ be defined for Xlib
+ * client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+
+#ifdef XEPHYR_DRI
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <GL/glx.h>
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86dristr.h>
+#include "GL/internal/dri_interface.h"
+
+static XExtensionInfo _xf86dri_info_data;
+static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
+static char xf86dri_extension_name[] = XF86DRINAME;
+
+#define XF86DRICheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xf86dri_extension_name, val)
+
+/*****************************************************************************
+ * *
+ * private utility routines *
+ * *
+ *****************************************************************************/
+
+static int close_display(Display *dpy, XExtCodes *extCodes);
+static /* const */ XExtensionHooks xf86dri_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
+ xf86dri_extension_name,
+ &xf86dri_extension_hooks,
+ 0, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
+
+
+/*****************************************************************************
+ * *
+ * public XFree86-DRI Extension routines *
+ * *
+ *****************************************************************************/
+
+#if 0
+#include <stdio.h>
+#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
+#else
+#define TRACE(msg)
+#endif
+
+Bool XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable);
+Bool XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable);
+
+Bool XF86DRIQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+
+ TRACE("QueryExtension...");
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ TRACE("QueryExtension... return True");
+ return True;
+ } else {
+ TRACE("QueryExtension... return False");
+ return False;
+ }
+}
+
+Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
+ Display* dpy;
+ int* majorVersion;
+ int* minorVersion;
+ int* patchVersion;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIQueryVersionReply rep;
+ xXF86DRIQueryVersionReq *req;
+
+ TRACE("QueryVersion...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIQueryVersion;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryVersion... return False");
+ return False;
+ }
+ *majorVersion = rep.majorVersion;
+ *minorVersion = rep.minorVersion;
+ *patchVersion = rep.patchVersion;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryVersion... return True");
+ return True;
+}
+
+Bool
+XF86DRIQueryDirectRenderingCapable (Display *dpy, int screen, Bool *isCapable)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ xXF86DRIQueryDirectRenderingCapableReq *req;
+
+ TRACE("QueryDirectRenderingCapable...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIQueryDirectRenderingCapable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryDirectRenderingCapable... return False");
+ return False;
+ }
+ *isCapable = rep.isCapable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryDirectRenderingCapable... return True");
+ return True;
+}
+
+Bool
+XF86DRIOpenConnection (Display *dpy, int screen,
+ drm_handle_t *hSAREA,
+ char **busIdString)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIOpenConnectionReply rep;
+ xXF86DRIOpenConnectionReq *req;
+
+ TRACE("OpenConnection...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIOpenConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIOpenConnection;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return False");
+ return False;
+ }
+
+ *hSAREA = rep.hSAREALow;
+ if (sizeof(drm_handle_t) == 8) {
+ int shift = 32; /* var to prevent warning on next line */
+ *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
+ }
+
+ if (rep.length) {
+ if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
+ _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return False");
+ return False;
+ }
+ _XReadPad(dpy, *busIdString, rep.busIdStringLength);
+ } else {
+ *busIdString = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return True");
+ return True;
+}
+
+Bool XF86DRIAuthConnection(dpy, screen, magic)
+ Display* dpy;
+ int screen;
+ drm_magic_t magic;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIAuthConnectionReq *req;
+ xXF86DRIAuthConnectionReply rep;
+
+ TRACE("AuthConnection...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIAuthConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIAuthConnection;
+ req->screen = screen;
+ req->magic = magic;
+ rep.authenticated = 0;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("AuthConnection... return False");
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("AuthConnection... return True");
+ return True;
+}
+
+Bool XF86DRICloseConnection(dpy, screen)
+ Display* dpy;
+ int screen;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRICloseConnectionReq *req;
+
+ TRACE("CloseConnection...");
+
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICloseConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICloseConnection;
+ req->screen = screen;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CloseConnection... return True");
+ return True;
+}
+
+Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
+ ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
+ Display* dpy;
+ int screen;
+ int* ddxDriverMajorVersion;
+ int* ddxDriverMinorVersion;
+ int* ddxDriverPatchVersion;
+ char** clientDriverName;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIGetClientDriverNameReply rep;
+ xXF86DRIGetClientDriverNameReq *req;
+
+ TRACE("GetClientDriverName...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetClientDriverName, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetClientDriverName;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return False");
+ return False;
+ }
+
+ *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
+ *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
+ *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
+
+ if (rep.length) {
+ if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
+ _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return False");
+ return False;
+ }
+ _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
+ } else {
+ *clientDriverName = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return True");
+ return True;
+}
+
+Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
+ hHWContext)
+ Display* dpy;
+ int screen;
+ int configID;
+ XID* context;
+ drm_context_t * hHWContext;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRICreateContextReply rep;
+ xXF86DRICreateContextReq *req;
+
+ TRACE("CreateContext...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICreateContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICreateContext;
+ req->visual = configID;
+ req->screen = screen;
+ *context = XAllocID(dpy);
+ req->context = *context;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateContext... return False");
+ return False;
+ }
+ *hHWContext = rep.hHWContext;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateContext... return True");
+ return True;
+}
+
+Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
+ Display* dpy;
+ int screen;
+ Visual* visual;
+ XID* context;
+ drm_context_t * hHWContext;
+{
+ return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
+ context, hHWContext );
+}
+
+GLboolean XF86DRIDestroyContext( Display *dpy, int screen, XID context)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIDestroyContextReq *req;
+
+ TRACE("DestroyContext...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIDestroyContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIDestroyContext;
+ req->screen = screen;
+ req->context = context;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("DestroyContext... return True");
+ return True;
+}
+
+GLboolean
+XF86DRICreateDrawable (Display *dpy, int screen,
+ XID drawable, drm_drawable_t * hHWDrawable)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRICreateDrawableReply rep;
+ xXF86DRICreateDrawableReq *req;
+
+ TRACE("CreateDrawable...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICreateDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICreateDrawable;
+ req->screen = screen;
+ req->drawable = drawable;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateDrawable... return False");
+ return False;
+ }
+ *hHWDrawable = rep.hHWDrawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateDrawable... return True");
+ return True;
+}
+
+static int noopErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+ return 0;
+}
+
+GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen,
+ XID drawable )
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIDestroyDrawableReq *req;
+ int (*oldXErrorHandler)(Display *, XErrorEvent *);
+
+ TRACE("DestroyDrawable...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ /* This is called from the DRI driver, which used call it like this
+ *
+ * if (windowExists(drawable))
+ * destroyDrawable(drawable);
+ *
+ * which is a textbook race condition - the window may disappear
+ * from the server between checking for its existance and
+ * destroying it. Instead we change the semantics of
+ * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
+ * the windows is gone, by wrapping the destroy call in an error
+ * handler. */
+
+ XSync(dpy, GL_FALSE);
+ oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIDestroyDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIDestroyDrawable;
+ req->screen = screen;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ XSetErrorHandler(oldXErrorHandler);
+
+ TRACE("DestroyDrawable... return True");
+ return True;
+}
+
+Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
+ unsigned int* index, unsigned int* stamp,
+ int* X, int* Y, int* W, int* H,
+ int* numClipRects, drm_clip_rect_t ** pClipRects,
+ int* backX, int* backY,
+ int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIGetDrawableInfoReply rep;
+ xXF86DRIGetDrawableInfoReq *req=NULL;
+ int total_rects;
+
+ TRACE("GetDrawableInfo...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetDrawableInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetDrawableInfo;
+ req->screen = screen;
+ req->drawable = drawable;
+
+ if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
+ {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return False");
+ return False;
+ }
+ *index = rep.drawableTableIndex;
+ *stamp = rep.drawableTableStamp;
+ *X = (int)rep.drawableX;
+ *Y = (int)rep.drawableY;
+ *W = (int)rep.drawableWidth;
+ *H = (int)rep.drawableHeight;
+ *numClipRects = rep.numClipRects;
+ total_rects = *numClipRects;
+
+ *backX = rep.backX;
+ *backY = rep.backY;
+ *numBackClipRects = rep.numBackClipRects;
+ total_rects += *numBackClipRects;
+
+#if 0
+ /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
+ * backwards compatibility (Because of the >> 2 shift) but the fix
+ * enables multi-threaded apps to work.
+ */
+ if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply) +
+ total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
+ _XEatData(dpy, rep.length);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return False");
+ return False;
+ }
+#endif
+
+ if (*numClipRects) {
+ int len = sizeof(drm_clip_rect_t) * (*numClipRects);
+
+ *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+ if (*pClipRects)
+ _XRead(dpy, (char*)*pClipRects, len);
+ } else {
+ *pClipRects = NULL;
+ }
+
+ if (*numBackClipRects) {
+ int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
+
+ *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+ if (*pBackClipRects)
+ _XRead(dpy, (char*)*pBackClipRects, len);
+ } else {
+ *pBackClipRects = NULL;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return True");
+ return True;
+}
+
+Bool
+XF86DRIGetDeviceInfo (Display *dpy, int screen, drm_handle_t *hFrameBuffer,
+ int *fbOrigin, int *fbSize, int *fbStride,
+ int *devPrivateSize, void **pDevPrivate)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86DRIGetDeviceInfoReply rep;
+ xXF86DRIGetDeviceInfoReq *req;
+
+ TRACE("GetDeviceInfo...");
+ XF86DRICheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetDeviceInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetDeviceInfo;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return False");
+ return False;
+ }
+
+ *hFrameBuffer = rep.hFrameBufferLow;
+ if (sizeof(drm_handle_t) == 8) {
+ int shift = 32; /* var to prevent warning on next line */
+ *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
+ }
+
+ *fbOrigin = rep.framebufferOrigin;
+ *fbSize = rep.framebufferSize;
+ *fbStride = rep.framebufferStride;
+ *devPrivateSize = rep.devPrivateSize;
+
+ if (rep.length) {
+ if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
+ _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return False");
+ return False;
+ }
+ _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
+ } else {
+ *pDevPrivate = NULL;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return True");
+ return True;
+}
+
+Bool
+XF86DRIOpenFullScreen(Display *dpy, int screen, Drawable drawable)
+{
+ /* This function and the underlying X protocol are deprecated.
+ */
+ (void) dpy;
+ (void) screen;
+ (void) drawable;
+ return False;
+}
+
+Bool
+XF86DRICloseFullScreen(Display *dpy, int screen, Drawable drawable)
+{
+ /* This function and the underlying X protocol are deprecated.
+ */
+ (void) dpy;
+ (void) screen;
+ (void) drawable;
+ return True;
+}
+#endif /*EPHYR_DRI*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
new file mode 100644
index 000000000..b02f9903c
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -0,0 +1,1155 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "ephyrlog.h"
+
+#ifdef XEPHYR_DRI
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "ephyrglxext.h"
+#endif /*XEPHYR_DRI*/
+
+extern int KdTsPhyScreen;
+#ifdef GLXEXT
+extern Bool noGlxVisualInit;
+#endif
+
+KdKeyboardInfo *ephyrKbd;
+KdPointerInfo *ephyrMouse;
+EphyrKeySyms ephyrKeySyms;
+Bool ephyrNoDRI=FALSE ;
+Bool ephyrNoXV=FALSE ;
+
+static int mouseState = 0;
+
+typedef struct _EphyrInputPrivate {
+ Bool enabled;
+} EphyrKbdPrivate, EphyrPointerPrivate;
+
+Bool EphyrWantGrayScale = 0;
+
+
+Bool
+ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
+{
+ OsSignal(SIGUSR1, hostx_handle_signal);
+
+ priv->base = 0;
+ priv->bytes_per_line = 0;
+ return TRUE;
+}
+
+Bool
+ephyrCardInit (KdCardInfo *card)
+{
+ EphyrPriv *priv;
+
+ priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!ephyrInitialize (card, priv))
+ {
+ xfree (priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
+{
+ int width = 640, height = 480;
+ unsigned long redMask, greenMask, blueMask;
+
+ if (hostx_want_screen_size(screen, &width, &height)
+ || !screen->width || !screen->height)
+ {
+ screen->width = width;
+ screen->height = height;
+ }
+
+ if (EphyrWantGrayScale)
+ screen->fb[0].depth = 8;
+
+ if (screen->fb[0].depth && screen->fb[0].depth != hostx_get_depth())
+ {
+ if (screen->fb[0].depth < hostx_get_depth()
+ && (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
+ || screen->fb[0].depth == 8))
+ {
+ hostx_set_server_depth(screen, screen->fb[0].depth);
+ }
+ else
+ ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
+ }
+
+ screen->fb[0].depth = hostx_get_server_depth(screen);
+ screen->rate = 72;
+
+ if (screen->fb[0].depth <= 8)
+ {
+ if (EphyrWantGrayScale)
+ screen->fb[0].visuals = ((1 << StaticGray) | (1 << GrayScale));
+ else
+ screen->fb[0].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+
+ screen->fb[0].redMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].depth = 8;
+ screen->fb[0].bitsPerPixel = 8;
+ }
+ else
+ {
+ screen->fb[0].visuals = (1 << TrueColor);
+
+ if (screen->fb[0].depth <= 15)
+ {
+ screen->fb[0].depth = 15;
+ screen->fb[0].bitsPerPixel = 16;
+ }
+ else if (screen->fb[0].depth <= 16)
+ {
+ screen->fb[0].depth = 16;
+ screen->fb[0].bitsPerPixel = 16;
+ }
+ else
+ {
+ screen->fb[0].depth = 24;
+ screen->fb[0].bitsPerPixel = 32;
+ }
+
+ hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
+
+ screen->fb[0].redMask = (Pixel) redMask;
+ screen->fb[0].greenMask = (Pixel) greenMask;
+ screen->fb[0].blueMask = (Pixel) blueMask;
+
+ }
+
+ scrpriv->randr = screen->randr;
+
+ return ephyrMapFramebuffer (screen);
+}
+
+Bool
+ephyrScreenInit (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv;
+
+ scrpriv = xalloc (sizeof (EphyrScrPriv));
+
+ if (!scrpriv)
+ return FALSE;
+
+ memset (scrpriv, 0, sizeof (EphyrScrPriv));
+ screen->driver = scrpriv;
+
+ if (!ephyrScreenInitialize (screen, scrpriv))
+ {
+ screen->driver = 0;
+ xfree (scrpriv);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void*
+ephyrWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ EphyrPriv *priv = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ *size = priv->bytes_per_line;
+ return priv->base + row * priv->bytes_per_line + offset;
+}
+
+Bool
+ephyrMapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrPriv *priv = screen->card->driver;
+ KdPointerMatrix m;
+ int buffer_height;
+
+ EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
+ screen->width, screen->height, screen->mynum);
+
+ KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
+ KdSetPointerMatrix (&m);
+
+ priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2;
+
+ /* point the framebuffer to the data in an XImage */
+ /* If fakexa is enabled, allocate a larger buffer so that fakexa has space to
+ * put offscreen pixmaps.
+ */
+ if (ephyrFuncs.initAccel == NULL)
+ buffer_height = screen->height;
+ else
+ buffer_height = 3 * screen->height;
+
+ priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
+
+ screen->memory_base = (CARD8 *) (priv->base);
+ screen->memory_size = priv->bytes_per_line * buffer_height;
+ screen->off_screen_base = priv->bytes_per_line * screen->height;
+
+ if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
+ {
+ scrpriv->shadow = FALSE;
+
+ screen->fb[0].byteStride = priv->bytes_per_line;
+ screen->fb[0].pixelStride = screen->width;
+ screen->fb[0].frameBuffer = (CARD8 *) (priv->base);
+ }
+ else
+ {
+ /* Rotated/Reflected so we need to use shadow fb */
+ scrpriv->shadow = TRUE;
+
+ EPHYR_LOG("allocing shadow");
+
+ KdShadowFbAlloc (screen, 0,
+ scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
+ }
+
+ return TRUE;
+}
+
+void
+ephyrSetScreenSizes (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ }
+ else
+ {
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ }
+}
+
+Bool
+ephyrUnmapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->shadow)
+ KdShadowFbFree (screen, 0);
+
+ /* Note, priv->base will get freed when XImage recreated */
+
+ return TRUE;
+}
+
+void
+ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG("slow paint");
+
+ /* FIXME: Slow Rotated/Reflected updates could be much
+ * much faster efficiently updating via tranforming
+ * pBuf->pDamage regions
+ */
+ shadowUpdateRotatePacked(pScreen, pBuf);
+ hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
+}
+
+static void
+ephyrInternalDamageRedisplay (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RegionPtr pRegion;
+
+ if (!scrpriv || !scrpriv->pDamage)
+ return;
+
+ pRegion = DamageRegion (scrpriv->pDamage);
+
+ if (REGION_NOTEMPTY (pScreen, pRegion))
+ {
+ int nbox;
+ BoxPtr pbox;
+
+ nbox = REGION_NUM_RECTS (pRegion);
+ pbox = REGION_RECTS (pRegion);
+
+ while (nbox--)
+ {
+ hostx_paint_rect(screen,
+ pbox->x1, pbox->y1,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ DamageEmpty (scrpriv->pDamage);
+ }
+}
+
+static void
+ephyrInternalDamageBlockHandler (pointer data,
+ OSTimePtr pTimeout,
+ pointer pRead)
+{
+ ScreenPtr pScreen = (ScreenPtr) data;
+
+ ephyrInternalDamageRedisplay (pScreen);
+}
+
+static void
+ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask)
+{
+ /* FIXME: Not needed ? */
+}
+
+Bool
+ephyrSetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
+ (DamageDestroyFunc) 0,
+ DamageReportNone,
+ TRUE,
+ pScreen,
+ pScreen);
+
+ if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen))
+ return FALSE;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+
+ DamageRegister (&pPixmap->drawable, scrpriv->pDamage);
+
+ return TRUE;
+}
+
+void
+ephyrUnsetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ DamageUnregister (&pPixmap->drawable, scrpriv->pDamage);
+ DamageDestroy (scrpriv->pDamage);
+
+ RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen);
+}
+
+#ifdef RANDR
+Bool
+ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RRScreenSizePtr pSize;
+ Rotation randr;
+ int n = 0;
+
+ EPHYR_LOG("mark");
+
+ struct { int width, height; } sizes[] =
+ {
+ { 1600, 1200 },
+ { 1400, 1050 },
+ { 1280, 960 },
+ { 1280, 1024 },
+ { 1152, 864 },
+ { 1024, 768 },
+ { 832, 624 },
+ { 800, 600 },
+ { 720, 400 },
+ { 480, 640 },
+ { 640, 480 },
+ { 640, 400 },
+ { 320, 240 },
+ { 240, 320 },
+ { 160, 160 },
+ { 0, 0 }
+ };
+
+ *rotations = RR_Rotate_All|RR_Reflect_All;
+
+ if (!hostx_want_preexisting_window (screen)
+ && !hostx_want_fullscreen ()) /* only if no -parent switch */
+ {
+ while (sizes[n].width != 0 && sizes[n].height != 0)
+ {
+ RRRegisterSize (pScreen,
+ sizes[n].width,
+ sizes[n].height,
+ (sizes[n].width * screen->width_mm)/screen->width,
+ (sizes[n].height *screen->height_mm)/screen->height
+ );
+ n++;
+ }
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm);
+
+ randr = KdSubRotation (scrpriv->randr, screen->randr);
+
+ RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+ return TRUE;
+}
+
+Bool
+ephyrRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ Bool wasEnabled = pScreenPriv->enabled;
+ EphyrScrPriv oldscr;
+ int oldwidth, oldheight, oldmmwidth, oldmmheight;
+ Bool oldshadow;
+ int newwidth, newheight;
+
+ if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ oldscr = *scrpriv;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+ oldshadow = scrpriv->shadow;
+
+ /*
+ * Set new configuration
+ */
+
+ scrpriv->randr = KdAddRotation (screen->randr, randr);
+
+ KdOffscreenSwapOut (screen->pScreen);
+
+ ephyrUnmapFramebuffer (screen);
+
+ screen->width = newwidth;
+ screen->height = newheight;
+
+ if (!ephyrMapFramebuffer (screen))
+ goto bail4;
+
+ /* FIXME below should go in own call */
+
+ if (oldshadow)
+ KdShadowUnset (screen->pScreen);
+ else
+ ephyrUnsetInternalDamage(screen->pScreen);
+
+ if (scrpriv->shadow)
+ {
+ if (!KdShadowSet (screen->pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear))
+ goto bail4;
+ }
+ else
+ {
+ /* Without shadow fb ( non rotated ) we need
+ * to use damage to efficiently update display
+ * via signal regions what to copy from 'fb'.
+ */
+ if (!ephyrSetInternalDamage(screen->pScreen))
+ goto bail4;
+ }
+
+ ephyrSetScreenSizes (screen->pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb[0].depth,
+ screen->fb[0].bitsPerPixel,
+ screen->fb[0].byteStride,
+ screen->fb[0].frameBuffer);
+
+ /* set the subpixel order */
+
+ KdSetSubpixelOrder (pScreen, scrpriv->randr);
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+ bail4:
+ EPHYR_LOG("bailed");
+
+ ephyrUnmapFramebuffer (screen);
+ *scrpriv = oldscr;
+ (void) ephyrMapFramebuffer (screen);
+
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+}
+
+Bool
+ephyrRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = ephyrRandRGetInfo;
+ pScrPriv->rrSetConfig = ephyrRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+ephyrCreateColormap (ColormapPtr pmap)
+{
+ return fbInitializeColormap (pmap);
+}
+
+Bool
+ephyrInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
+ hostx_set_screen_number (screen, pScreen->myNum);
+ hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
+ pScreen->CreateColormap = ephyrCreateColormap;
+
+#ifdef XV
+ if (!ephyrNoXV) {
+ if (!ephyrInitVideo (pScreen)) {
+ EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
+ } else {
+ EPHYR_LOG ("initialized xvideo okay\n") ;
+ }
+ }
+#endif /*XV*/
+
+#ifdef XEPHYR_DRI
+ if (!ephyrNoDRI && !hostx_has_dri ()) {
+ EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
+ ephyrNoDRI = TRUE ;
+#ifdef GLXEXT
+ noGlxVisualInit = FALSE ;
+#endif
+ }
+ if (!ephyrNoDRI) {
+ ephyrDRIExtensionInit (pScreen) ;
+ ephyrHijackGLXExtension () ;
+ }
+#endif
+
+#ifdef GLXEXT
+ if (ephyrNoDRI) {
+ noGlxVisualInit = FALSE ;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrFinishInitScreen (ScreenPtr pScreen)
+{
+ /* FIXME: Calling this even if not using shadow.
+ * Seems harmless enough. But may be safer elsewhere.
+ */
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+#ifdef RANDR
+ if (!ephyrRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrCreateResources (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
+ pScreen, pScreen->myNum, scrpriv->shadow);
+
+ if (scrpriv->shadow)
+ return KdShadowSet (pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear);
+ else
+ return ephyrSetInternalDamage(pScreen);
+}
+
+void
+ephyrPreserve (KdCardInfo *card)
+{
+}
+
+Bool
+ephyrEnable (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+ephyrDPMS (ScreenPtr pScreen, int mode)
+{
+ return TRUE;
+}
+
+void
+ephyrDisable (ScreenPtr pScreen)
+{
+}
+
+void
+ephyrRestore (KdCardInfo *card)
+{
+}
+
+void
+ephyrScreenFini (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ if (scrpriv->shadow) {
+ KdShadowFbFree (screen, 0);
+ }
+ xfree(screen->driver);
+ screen->driver = NULL;
+}
+
+/*
+ * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
+ */
+void
+ephyrUpdateModifierState(unsigned int state)
+{
+ DeviceIntPtr pkeydev;
+ KeyClassPtr keyc;
+ int i;
+ CARD8 mask;
+
+ pkeydev = inputInfo.keyboard;
+
+ if (!pkeydev)
+ return;
+
+ keyc = pkeydev->key;
+
+ state = state & 0xff;
+
+ if (keyc->state == state)
+ return;
+
+ for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
+ {
+ int key;
+
+ /* Modifier is down, but shouldn't be */
+ if ((keyc->state & mask) && !(state & mask))
+ {
+ int count = keyc->modifierKeyCount[i];
+
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->modifierMap[key] & mask)
+ {
+ int bit;
+ BYTE *kptr;
+
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (*kptr & bit && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
+
+ if (--count == 0)
+ break;
+ }
+ }
+
+ /* Modifier shoud be down, but isn't */
+ if (!(keyc->state & mask) && (state & mask))
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->modifierMap[key] & mask)
+ {
+ if (keyc->modifierMap[key] & mask && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
+ break;
+ }
+ }
+}
+
+static void
+ephyrBlockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+}
+
+static void
+ephyrUnblockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+}
+
+static Bool
+ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+int ephyrCurScreen; /*current event screen*/
+
+static void
+ephyrWarpCursor (ScreenPtr pScreen, int x, int y)
+{
+ ephyrBlockSigio ();
+ ephyrCurScreen = pScreen->myNum;
+ miPointerWarpCursor (pScreen, x, y);
+ ephyrUnblockSigio ();
+}
+
+miPointerScreenFuncRec ephyrPointerScreenFuncs =
+{
+ ephyrCursorOffScreen,
+ ephyrCrossScreen,
+ ephyrWarpCursor
+};
+
+#ifdef XEPHYR_DRI
+/**
+ * find if the remote window denoted by a_remote
+ * is paired with an internal Window within the Xephyr server.
+ * If the remove window is paired with an internal window, send an
+ * expose event to the client insterested in the internal window expose event.
+ *
+ * Pairing happens when a drawable inside Xephyr is associated with
+ * a GL surface in a DRI environment.
+ * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
+ * know a paired window is created.
+ *
+ * This is useful to make GL drawables (only windows for now) handle
+ * expose events and send those events to clients.
+ */
+static void
+ephyrExposePairedWindow (int a_remote)
+{
+ EphyrWindowPair *pair = NULL;
+ RegionRec reg;
+ ScreenPtr screen;
+
+ if (!findWindowPairFromRemote (a_remote, &pair)) {
+ EPHYR_LOG ("did not find a pair for this window\n");
+ return;
+ }
+ screen = pair->local->drawable.pScreen;
+ REGION_NULL (screen, &reg);
+ REGION_COPY (screen, &reg, &pair->local->clipList);
+ screen->WindowExposures (pair->local, &reg, NullRegion);
+ REGION_UNINIT (screen, &reg);
+}
+#endif /*XEPHYR_DRI*/
+
+void
+ephyrPoll(void)
+{
+ EphyrHostXEvent ev;
+
+ while (hostx_get_event(&ev))
+ {
+ switch (ev.type)
+ {
+ case EPHYR_EV_MOUSE_MOTION:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ {
+ if (ev.data.mouse_motion.screen >=0
+ && (ephyrCurScreen != ev.data.mouse_motion.screen))
+ {
+ EPHYR_LOG ("warping mouse cursor. "
+ "cur_screen%d, motion_screen:%d\n",
+ ephyrCurScreen, ev.data.mouse_motion.screen) ;
+ if (ev.data.mouse_motion.screen >= 0)
+ {
+ ephyrWarpCursor
+ (screenInfo.screens[ev.data.mouse_motion.screen],
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y );
+ }
+ }
+ else
+ {
+ int x=0, y=0;
+#ifdef XEPHYR_DRI
+ EphyrWindowPair *pair = NULL;
+#endif
+ EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+ x = ev.data.mouse_motion.x;
+ y = ev.data.mouse_motion.y;
+ EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ;
+#ifdef XEPHYR_DRI
+ EPHYR_LOG ("is this window peered by a gl drawable ?\n") ;
+ if (findWindowPairFromRemote (ev.data.mouse_motion.window,
+ &pair))
+ {
+ EPHYR_LOG ("yes, it is peered\n") ;
+ x += pair->local->drawable.x;
+ y += pair->local->drawable.y;
+ }
+ else
+ {
+ EPHYR_LOG ("no, it is not peered\n") ;
+ }
+ EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ;
+#endif
+ KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
+ }
+ }
+ break;
+
+ case EPHYR_EV_MOUSE_PRESS:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState |= ev.data.mouse_down.button_num;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_MOUSE_RELEASE:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState &= ~ev.data.mouse_up.button_num;
+ EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_KEY_PRESS:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE);
+ break;
+
+ case EPHYR_EV_KEY_RELEASE:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
+ break;
+
+#ifdef XEPHYR_DRI
+ case EPHYR_EV_EXPOSE:
+ /*
+ * We only receive expose events when the expose event have
+ * be generated for a drawable that is a host X window managed
+ * by Xephyr. Host X windows managed by Xephyr exists for instance
+ * when Xephyr is asked to create a GL drawable in a DRI environment.
+ */
+ ephyrExposePairedWindow (ev.data.expose.window);
+ break;
+#endif /*XEPHYR_DRI*/
+
+ default:
+ break;
+ }
+ }
+}
+
+void
+ephyrCardFini (KdCardInfo *card)
+{
+ EphyrPriv *priv = card->driver;
+ xfree (priv);
+}
+
+void
+ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
+{
+ /* XXX Not sure if this is right */
+
+ EPHYR_LOG("mark");
+
+ while (n--)
+ {
+ pdefs->red = 0;
+ pdefs->green = 0;
+ pdefs->blue = 0;
+ pdefs++;
+ }
+
+}
+
+void
+ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
+{
+ int min, max, p;
+
+ /* XXX Not sure if this is right */
+
+ min = 256;
+ max = 0;
+
+ while (n--)
+ {
+ p = pdefs->pixel;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+
+ hostx_set_cmap_entry(p,
+ pdefs->red >> 8,
+ pdefs->green >> 8,
+ pdefs->blue >> 8);
+ pdefs++;
+ }
+}
+
+/* Mouse calls */
+
+static Status
+MouseInit (KdPointerInfo *pi)
+{
+ pi->driverPrivate = (EphyrPointerPrivate *)
+ xcalloc(sizeof(EphyrPointerPrivate), 1);
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ pi->nAxes = 3;
+ pi->nButtons = 32;
+ pi->name = KdSaveString("Xephyr virtual mouse");
+ ephyrMouse = pi;
+ return Success;
+}
+
+static Status
+MouseEnable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE;
+ return Success;
+}
+
+static void
+MouseDisable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ return;
+}
+
+static void
+MouseFini (KdPointerInfo *pi)
+{
+ ephyrMouse = NULL;
+ return;
+}
+
+KdPointerDriver EphyrMouseDriver = {
+ "ephyr",
+ MouseInit,
+ MouseEnable,
+ MouseDisable,
+ MouseFini,
+ NULL,
+};
+
+/* Keyboard */
+
+static Status
+EphyrKeyboardInit (KdKeyboardInfo *ki)
+{
+ ki->driverPrivate = (EphyrKbdPrivate *)
+ xcalloc(sizeof(EphyrKbdPrivate), 1);
+ hostx_load_keymap();
+ if (!ephyrKeySyms.map) {
+ ErrorF("Couldn't load keymap from host\n");
+ return BadAlloc;
+ }
+ ki->keySyms.minKeyCode = ephyrKeySyms.minKeyCode;
+ ki->keySyms.maxKeyCode = ephyrKeySyms.maxKeyCode;
+ ki->minScanCode = ki->keySyms.minKeyCode;
+ ki->maxScanCode = ki->keySyms.maxKeyCode;
+ ki->keySyms.mapWidth = ephyrKeySyms.mapWidth;
+ xfree(ki->keySyms.map);
+ ki->keySyms.map = ephyrKeySyms.map;
+ ki->name = KdSaveString("Xephyr virtual keyboard");
+ ephyrKbd = ki;
+ return Success;
+}
+
+static Status
+EphyrKeyboardEnable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE;
+
+ return Success;
+}
+
+static void
+EphyrKeyboardDisable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE;
+}
+
+static void
+EphyrKeyboardFini (KdKeyboardInfo *ki)
+{
+ /* not xfree: we call malloc from hostx.c. */
+ free(ki->keySyms.map);
+ ephyrKbd = NULL;
+ return;
+}
+
+static void
+EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds)
+{
+}
+
+static void
+EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
+{
+}
+
+
+KdKeyboardDriver EphyrKeyboardDriver = {
+ "ephyr",
+ EphyrKeyboardInit,
+ EphyrKeyboardEnable,
+ EphyrKeyboardLeds,
+ EphyrKeyboardBell,
+ EphyrKeyboardDisable,
+ EphyrKeyboardFini,
+ NULL,
+};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h
new file mode 100644
index 000000000..5d58a216c
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.h
@@ -0,0 +1,202 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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 _EPHYR_H_
+#define _EPHYR_H_
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <libgen.h>
+
+#include "os.h" /* for OsSignal() */
+#include "kdrive.h"
+#include "hostx.h"
+#include "exa.h"
+
+#ifdef RANDR
+#include "randrstr.h"
+#endif
+
+#include "damage.h"
+
+typedef struct _ephyrPriv {
+ CARD8 *base;
+ int bytes_per_line;
+} EphyrPriv;
+
+typedef struct _ephyrFakexaPriv {
+ ExaDriverPtr exa;
+ Bool is_synced;
+
+ /* The following are arguments and other information from Prepare* calls
+ * which are stored for use in the inner calls.
+ */
+ int op;
+ PicturePtr pSrcPicture, pMaskPicture, pDstPicture;
+ void *saved_ptrs[3];
+ PixmapPtr pDst, pSrc, pMask;
+ GCPtr pGC;
+} EphyrFakexaPriv;
+
+typedef struct _ephyrScrPriv {
+ Rotation randr;
+ Bool shadow;
+ PixmapPtr pShadow;
+ DamagePtr pDamage;
+ EphyrFakexaPriv *fakexa;
+} EphyrScrPriv;
+
+extern KdCardFuncs ephyrFuncs;
+extern KdKeyboardInfo *ephyrKbd;
+extern KdPointerInfo *ephyrMouse;
+
+extern miPointerScreenFuncRec ephyrPointerScreenFuncs;
+
+Bool
+ephyrInitialize (KdCardInfo *card, EphyrPriv *priv);
+
+Bool
+ephyrCardInit (KdCardInfo *card);
+
+Bool
+ephyrScreenInit (KdScreenInfo *screen);
+
+Bool
+ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv);
+
+Bool
+ephyrInitScreen (ScreenPtr pScreen);
+
+Bool
+ephyrFinishInitScreen (ScreenPtr pScreen);
+
+Bool
+ephyrCreateResources (ScreenPtr pScreen);
+
+void
+ephyrPreserve (KdCardInfo *card);
+
+Bool
+ephyrEnable (ScreenPtr pScreen);
+
+Bool
+ephyrDPMS (ScreenPtr pScreen, int mode);
+
+void
+ephyrDisable (ScreenPtr pScreen);
+
+void
+ephyrRestore (KdCardInfo *card);
+
+void
+ephyrScreenFini (KdScreenInfo *screen);
+
+void
+ephyrCardFini (KdCardInfo *card);
+
+void
+ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
+
+void
+ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
+
+Bool
+ephyrMapFramebuffer (KdScreenInfo *screen);
+
+void *
+ephyrWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure);
+
+void
+ephyrSetScreenSizes (ScreenPtr pScreen);
+
+Bool
+ephyrUnmapFramebuffer (KdScreenInfo *screen);
+
+void
+ephyrUnsetInternalDamage (ScreenPtr pScreen);
+
+Bool
+ephyrSetInternalDamage (ScreenPtr pScreen);
+
+Bool
+ephyrCreateColormap (ColormapPtr pmap);
+
+void
+ephyrPoll(void);
+
+#ifdef RANDR
+Bool
+ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations);
+
+Bool
+ephyrRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize);
+Bool
+ephyrRandRInit (ScreenPtr pScreen);
+
+void
+ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+
+#endif
+
+void
+ephyrUpdateModifierState(unsigned int state);
+
+extern KdPointerDriver EphyrMouseDriver;
+
+extern KdKeyboardDriver EphyrKeyboardDriver;
+
+extern KdOsFuncs EphyrOsFuncs;
+
+extern Bool ephyrCursorInit(ScreenPtr pScreen);
+
+extern void ephyrCursorEnable(ScreenPtr pScreen);
+
+/* ephyr_draw.c */
+
+Bool
+ephyrDrawInit(ScreenPtr pScreen);
+
+void
+ephyrDrawEnable(ScreenPtr pScreen);
+
+void
+ephyrDrawDisable(ScreenPtr pScreen);
+
+void
+ephyrDrawFini(ScreenPtr pScreen);
+
+/*ephyvideo.c*/
+
+Bool ephyrInitVideo(ScreenPtr pScreen) ;
+
+#endif
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_draw.c b/xorg-server/hw/kdrive/ephyr/ephyr_draw.c
new file mode 100644
index 000000000..422b7c6b6
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_draw.c
@@ -0,0 +1,524 @@
+/*
+ * Copyright © 2006 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>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#undef NDEBUG /* No, really. The whole point of this module is to crash. */
+
+#include "ephyr.h"
+#include "exa_priv.h"
+#include "fbpict.h"
+
+#define EPHYR_TRACE_DRAW 0
+
+#if EPHYR_TRACE_DRAW
+#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__);
+#else
+#define TRACE_DRAW() do { } while (0)
+#endif
+
+/* Use some oddball alignments, to expose issues in alignment handling in EXA. */
+#define EPHYR_OFFSET_ALIGN 24
+#define EPHYR_PITCH_ALIGN 24
+
+#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
+#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
+
+/**
+ * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to
+ * fb functions.
+ */
+static void
+ephyrPreparePipelinedAccess(PixmapPtr pPix, int index)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ assert(fakexa->saved_ptrs[index] == NULL);
+ fakexa->saved_ptrs[index] = pPix->devPrivate.ptr;
+
+ if (pPix->devPrivate.ptr != NULL)
+ return;
+
+ pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix);
+}
+
+/**
+ * Restores the original devPrivate.ptr of the pixmap from before we messed with
+ * it.
+ */
+static void
+ephyrFinishPipelinedAccess(PixmapPtr pPix, int index)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ pPix->devPrivate.ptr = fakexa->saved_ptrs[index];
+ fakexa->saved_ptrs[index] = NULL;
+}
+
+/**
+ * Sets up a scratch GC for fbFill, and saves other parameters for the
+ * ephyrSolid implementation.
+ */
+static Bool
+ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ CARD32 tmpval[3];
+
+ ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST);
+
+ fakexa->pDst = pPix;
+ fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+
+ tmpval[0] = alu;
+ tmpval[1] = pm;
+ tmpval[2] = fg;
+ ChangeGC(fakexa->pGC, GCFunction | GCPlaneMask | GCForeground,
+ tmpval);
+
+ ValidateGC(&pPix->drawable, fakexa->pGC);
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbFill of the rectangle to be drawn.
+ */
+static void
+ephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1);
+}
+
+/**
+ * Cleans up the scratch GC created in ephyrPrepareSolid.
+ */
+static void
+ephyrDoneSolid(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ FreeScratchGC(fakexa->pGC);
+
+ ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST);
+}
+
+/**
+ * Sets up a scratch GC for fbCopyArea, and saves other parameters for the
+ * ephyrCopy implementation.
+ */
+static Bool
+ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu,
+ Pixel pm)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ CARD32 tmpval[2];
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ fakexa->pSrc = pSrc;
+ fakexa->pDst = pDst;
+ fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen);
+
+ tmpval[0] = alu;
+ tmpval[1] = pm;
+ ChangeGC (fakexa->pGC, GCFunction | GCPlaneMask, tmpval);
+
+ ValidateGC(&pDst->drawable, fakexa->pGC);
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbCopyArea to take care of the requested copy.
+ */
+static void
+ephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC,
+ srcX, srcY, w, h, dstX, dstY);
+}
+
+/**
+ * Cleans up the scratch GC created in ephyrPrepareCopy.
+ */
+static void
+ephyrDoneCopy(PixmapPtr pDst)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ FreeScratchGC (fakexa->pGC);
+
+ ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
+ ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
+}
+
+/**
+ * Reports that we can always accelerate the given operation. This may not be
+ * desirable from an EXA testing standpoint -- testing the fallback paths would
+ * be useful, too.
+ */
+static Bool
+ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ /* Exercise the component alpha helper, so fail on this case like a normal
+ * driver
+ */
+ if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Saves off the parameters for ephyrComposite.
+ */
+static Bool
+ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask,
+ PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+ if (pMask != NULL)
+ ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK);
+
+ fakexa->op = op;
+ fakexa->pSrcPicture = pSrcPicture;
+ fakexa->pMaskPicture = pMaskPicture;
+ fakexa->pDstPicture = pDstPicture;
+ fakexa->pSrc = pSrc;
+ fakexa->pMask = pMask;
+ fakexa->pDst = pDst;
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbComposite to complete the requested drawing operation.
+ */
+static void
+ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int w, int h)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture,
+ fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY,
+ w, h);
+}
+
+static void
+ephyrDoneComposite(PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ if (fakexa->pMask != NULL)
+ ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK);
+ ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
+ ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
+}
+
+/**
+ * Does fake acceleration of DownloadFromScren using memcpy.
+ */
+static Bool
+ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
+ int dst_pitch)
+{
+ KdScreenPriv(pSrc->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ unsigned char *src;
+ int src_pitch, cpp;
+
+ if (pSrc->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ cpp = pSrc->drawable.bitsPerPixel / 8;
+ src_pitch = exaGetPixmapPitch(pSrc);
+ src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
+ src += y * src_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pSrc->drawable.pScreen);
+
+ ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ return TRUE;
+}
+
+/**
+ * Does fake acceleration of UploadToScreen using memcpy.
+ */
+static Bool
+ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ unsigned char *dst;
+ int dst_pitch, cpp;
+
+ if (pDst->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+
+ cpp = pDst->drawable.bitsPerPixel / 8;
+ dst_pitch = exaGetPixmapPitch(pDst);
+ dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
+ dst += y * dst_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pDst->drawable.pScreen);
+
+ ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST);
+
+ return TRUE;
+}
+
+static Bool
+ephyrPrepareAccess(PixmapPtr pPix, int index)
+{
+ /* Make sure we don't somehow end up with a pointer that is in framebuffer
+ * and hasn't been readied for us.
+ */
+ assert(pPix->devPrivate.ptr != NULL);
+
+ return TRUE;
+}
+
+/**
+ * In fakexa, we currently only track whether we have synced to the latest
+ * "accelerated" drawing that has happened or not. It's not used for anything
+ * yet.
+ */
+static int
+ephyrMarkSync(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fakexa->is_synced = FALSE;
+
+ return 0;
+}
+
+/**
+ * Assumes that we're waiting on the latest marker. When EXA gets smarter and
+ * starts using markers in a fine-grained way (for example, waiting on drawing
+ * to required pixmaps to complete, rather than waiting for all drawing to
+ * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker
+ * implementation fine-grained as well.
+ */
+static void
+ephyrWaitMarker(ScreenPtr pScreen, int marker)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fakexa->is_synced = TRUE;
+}
+
+/**
+ * This function initializes EXA to use the fake acceleration implementation
+ * which just falls through to software. The purpose is to have a reliable,
+ * correct driver with which to test changes to the EXA core.
+ */
+Bool
+ephyrDrawInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa;
+ Bool success;
+
+ fakexa = xcalloc(1, sizeof(*fakexa));
+ if (fakexa == NULL)
+ return FALSE;
+
+ fakexa->exa = exaDriverAlloc();
+ if (fakexa->exa == NULL) {
+ xfree(fakexa);
+ return FALSE;
+ }
+
+ fakexa->exa->memoryBase = screen->memory_base;
+ fakexa->exa->memorySize = screen->memory_size;
+ fakexa->exa->offScreenBase = screen->off_screen_base;
+
+ /* Since we statically link against EXA, we shouldn't have to be smart about
+ * versioning.
+ */
+ fakexa->exa->exa_major = 2;
+ fakexa->exa->exa_minor = 0;
+
+ fakexa->exa->PrepareSolid = ephyrPrepareSolid;
+ fakexa->exa->Solid = ephyrSolid;
+ fakexa->exa->DoneSolid = ephyrDoneSolid;
+
+ fakexa->exa->PrepareCopy = ephyrPrepareCopy;
+ fakexa->exa->Copy = ephyrCopy;
+ fakexa->exa->DoneCopy = ephyrDoneCopy;
+
+ fakexa->exa->CheckComposite = ephyrCheckComposite;
+ fakexa->exa->PrepareComposite = ephyrPrepareComposite;
+ fakexa->exa->Composite = ephyrComposite;
+ fakexa->exa->DoneComposite = ephyrDoneComposite;
+
+ fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen;
+ fakexa->exa->UploadToScreen = ephyrUploadToScreen;
+
+ fakexa->exa->MarkSync = ephyrMarkSync;
+ fakexa->exa->WaitMarker = ephyrWaitMarker;
+
+ fakexa->exa->PrepareAccess = ephyrPrepareAccess;
+
+ fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN;
+ fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN;
+
+ fakexa->exa->maxX = 1023;
+ fakexa->exa->maxY = 1023;
+
+ fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS;
+
+ success = exaDriverInit(pScreen, fakexa->exa);
+ if (success) {
+ ErrorF("Initialized fake EXA acceleration\n");
+ scrpriv->fakexa = fakexa;
+ } else {
+ ErrorF("Failed to initialize EXA\n");
+ xfree(fakexa->exa);
+ xfree(fakexa);
+ }
+
+ return success;
+}
+
+void
+ephyrDrawEnable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyrDrawDisable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyrDrawFini(ScreenPtr pScreen)
+{
+}
+
+/**
+ * exaDDXDriverInit is required by the top-level EXA module, and is used by
+ * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since
+ * we won't be enabling/disabling the FB.
+ */
+void
+exaDDXDriverInit(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+
+ pExaScr->migration = ExaMigrationSmart;
+ pExaScr->checkDirtyCorrectness = TRUE;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdri.c b/xorg-server/hw/kdrive/ephyr/ephyrdri.c
new file mode 100644
index 000000000..53a96ba11
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrdri.c
@@ -0,0 +1,291 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#ifdef XEPHYR_DRI
+
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+/*#define _XF86DRI_SERVER_*/
+#include <GL/glx.h>
+#include <X11/dri/xf86dri.h>
+#include "hostx.h"
+#include "ephyrdri.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+Bool
+ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable)
+{
+ Display *dpy=hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_is_capable, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIQueryDirectRenderingCapable (dpy, DefaultScreen (dpy),
+ a_is_capable) ;
+ EPHYR_LOG ("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok) ;
+
+ return is_ok ;
+}
+
+Bool
+ephyrDRIOpenConnection (int a_screen,
+ drm_handle_t *a_sarea,
+ char **a_bus_id_string)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_bus_id_string, FALSE) ;
+ EPHYR_LOG ("enter. screen:%d\n", a_screen) ;
+ is_ok = XF86DRIOpenConnection (dpy, DefaultScreen (dpy),
+ a_sarea,
+ a_bus_id_string) ;
+ if (*a_bus_id_string) {
+ EPHYR_LOG ("leave. bus_id_string:%s, is_ok:%d\n",
+ *a_bus_id_string, is_ok) ;
+ } else {
+ EPHYR_LOG ("leave. bus_id_string:null, is_ok:%d\n",
+ is_ok) ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIAuthConnection (dpy, DefaultScreen (dpy), a_magic) ;
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRICloseConnection (int a_screen)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRICloseConnection (dpy, DefaultScreen (dpy)) ;
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIGetClientDriverName (int a_screen,
+ int *a_ddx_driver_major_version,
+ int *a_ddx_driver_minor_version,
+ int *a_ddx_driver_patch_version,
+ char ** a_client_driver_name)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_ddx_driver_major_version
+ && a_ddx_driver_minor_version
+ && a_ddx_driver_patch_version
+ && a_client_driver_name,
+ FALSE);
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIGetClientDriverName (dpy, DefaultScreen (dpy),
+ a_ddx_driver_major_version,
+ a_ddx_driver_minor_version,
+ a_ddx_driver_patch_version,
+ a_client_driver_name) ;
+ EPHYR_LOG ("major:%d, minor:%d, patch:%d, name:%s\n",
+ *a_ddx_driver_major_version,
+ *a_ddx_driver_minor_version,
+ *a_ddx_driver_patch_version,
+ *a_client_driver_name) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRICreateContext (int a_screen,
+ int a_visual_id,
+ unsigned long int *a_returned_ctxt_id,
+ drm_context_t *a_hw_ctxt)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+ Visual v;
+
+ EPHYR_LOG ("enter. screen:%d, visual:%d\n", a_screen, a_visual_id) ;
+ memset (&v, 0, sizeof (v)) ;
+ v.visualid = a_visual_id ;
+ is_ok = XF86DRICreateContext (dpy,
+ DefaultScreen (dpy),
+ &v,
+ a_returned_ctxt_id,
+ a_hw_ctxt) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIDestroyContext (int a_screen,
+ int a_context_id)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIDestroyContext (dpy, DefaultScreen (dpy), a_context_id) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRICreateDrawable (int a_screen,
+ int a_drawable,
+ drm_drawable_t *a_hw_drawable)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRICreateDrawable (dpy, DefaultScreen (dpy),
+ a_drawable, a_hw_drawable) ;
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIDestroyDrawable (int a_screen, int a_drawable)
+{
+ EPHYR_LOG ("enter\n") ;
+ EPHYR_LOG_ERROR ("not implemented yet\n") ;
+ EPHYR_LOG ("leave\n") ;
+ return FALSE ;
+}
+
+Bool
+ephyrDRIGetDrawableInfo (int a_screen,
+ int a_drawable,
+ unsigned int *a_index,
+ unsigned int *a_stamp,
+ int *a_x,
+ int *a_y,
+ int *a_w,
+ int *a_h,
+ int *a_num_clip_rects,
+ drm_clip_rect_t **a_clip_rects,
+ int *a_back_x,
+ int *a_back_y,
+ int *a_num_back_clip_rects,
+ drm_clip_rect_t **a_back_clip_rects)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+ EphyrHostWindowAttributes attrs ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_x && a_y && a_w && a_h
+ && a_num_clip_rects,
+ FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&attrs, 0, sizeof (attrs)) ;
+ if (!hostx_get_window_attributes (a_drawable, &attrs)) {
+ EPHYR_LOG_ERROR ("failed to query host window attributes\n") ;
+ goto out;
+ }
+ if (!XF86DRIGetDrawableInfo (dpy, DefaultScreen (dpy), a_drawable,
+ a_index, a_stamp,
+ a_x, a_y,
+ a_w, a_h,
+ a_num_clip_rects, a_clip_rects,
+ a_back_x, a_back_y,
+ a_num_back_clip_rects,
+ a_back_clip_rects)) {
+ EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h) ;
+ if (*a_num_clip_rects) {
+ free (*a_back_clip_rects) ;
+ *a_back_clip_rects = calloc (*a_num_clip_rects,
+ sizeof (drm_clip_rect_t)) ;
+ memmove (*a_back_clip_rects,
+ *a_clip_rects,
+ *a_num_clip_rects * sizeof (drm_clip_rect_t)) ;
+ *a_num_back_clip_rects = *a_num_clip_rects;
+ }
+ EPHYR_LOG ("num back clip rects:%d, num clip rects:%d\n",
+ *a_num_clip_rects, *a_num_back_clip_rects) ;
+ *a_back_x = *a_x ;
+ *a_back_y = *a_y ;
+ *a_w = attrs.width;
+ *a_h = attrs.height;
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
+ *a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h) ;
+ return is_ok ;
+}
+
+Bool
+ephyrDRIGetDeviceInfo (int a_screen,
+ drm_handle_t *a_frame_buffer,
+ int *a_fb_origin,
+ int *a_fb_size,
+ int *a_fb_stride,
+ int *a_dev_private_size,
+ void **a_dev_private)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+ is_ok = XF86DRIGetDeviceInfo (dpy, DefaultScreen (dpy), a_frame_buffer,
+ a_fb_origin, a_fb_size, a_fb_stride,
+ a_dev_private_size, a_dev_private) ;
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok ;
+}
+#endif /*EPHYR_DRI*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdri.h b/xorg-server/hw/kdrive/ephyr/ephyrdri.h
new file mode 100644
index 000000000..af8bb11fd
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrdri.h
@@ -0,0 +1,75 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifndef __EPHYRDRI_H__
+#define __EPHYRDRI_H__
+
+#include <xf86drm.h>
+
+Bool ephyrDRIQueryDirectRenderingCapable (int a_screen, Bool *a_is_capable) ;
+Bool ephyrDRIOpenConnection (int screen, drm_handle_t *a_sarea, char **a_bus_id_string) ;
+Bool ephyrDRIAuthConnection (int a_screen, drm_magic_t a_magic) ;
+Bool ephyrDRICloseConnection (int a_screen) ;
+Bool ephyrDRIGetClientDriverName (int a_screen,
+ int *a_ddx_driver_major_version,
+ int *a_ddx_driver_minor_version,
+ int *a_ddx_driver_patch_version,
+ char ** a_client_driver_name) ;
+Bool ephyrDRICreateContext (int a_screen,
+ int a_visual_id,
+ unsigned long int *a_returned_ctx_id,
+ drm_context_t *a_hw_ctx) ;
+Bool ephyrDRIDestroyContext (int a_screen,
+ int a_context_id) ;
+Bool ephyrDRICreateDrawable (int a_screen,
+ int a_drawable,
+ drm_drawable_t *a_hw_drawable) ;
+Bool ephyrDRIDestroyDrawable (int a_screen, int a_drawable) ;
+Bool ephyrDRIGetDrawableInfo (int a_screen,
+ int /*Drawable*/a_drawable,
+ unsigned int *a_index,
+ unsigned int *a_stamp,
+ int *a_x,
+ int *a_y,
+ int *a_w,
+ int *a_h,
+ int *a_num_clip_rects,
+ drm_clip_rect_t **a_clip_rects,
+ int *a_back_x,
+ int *a_back_y,
+ int *num_back_clip_rects,
+ drm_clip_rect_t **a_back_clip_rects) ;
+Bool ephyrDRIGetDeviceInfo (int a_screen,
+ drm_handle_t *a_frame_buffer,
+ int *a_fb_origin,
+ int *a_fb_size,
+ int *a_fb_stride,
+ int *a_dev_private_size,
+ void **a_dev_private) ;
+#endif /*__EPHYRDRI_H__*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c
new file mode 100644
index 000000000..fafe56d1f
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c
@@ -0,0 +1,1443 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * This file is heavily copied from hw/xfree86/dri/xf86dri.c
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#ifdef XEPHYR_DRI
+
+#include <string.h>
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86dristr.h>
+#include "misc.h"
+#include "privates.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "hostx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+
+
+typedef struct {
+ int foo;
+} EphyrDRIWindowPrivRec;
+typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
+
+typedef struct {
+ CreateWindowProcPtr CreateWindow ;
+ DestroyWindowProcPtr DestroyWindow ;
+ MoveWindowProcPtr MoveWindow ;
+ PositionWindowProcPtr PositionWindow ;
+ ClipNotifyProcPtr ClipNotify ;
+} EphyrDRIScreenPrivRec;
+typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
+
+static int DRIErrorBase;
+
+static DISPATCH_PROC(ProcXF86DRIQueryVersion);
+static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(ProcXF86DRIOpenConnection);
+static DISPATCH_PROC(ProcXF86DRICloseConnection);
+static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
+static DISPATCH_PROC(ProcXF86DRICreateContext);
+static DISPATCH_PROC(ProcXF86DRIDestroyContext);
+static DISPATCH_PROC(ProcXF86DRICreateDrawable);
+static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
+static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
+static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
+static DISPATCH_PROC(ProcXF86DRIDispatch);
+static DISPATCH_PROC(ProcXF86DRIAuthConnection);
+
+static DISPATCH_PROC(SProcXF86DRIQueryVersion);
+static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(SProcXF86DRIDispatch);
+
+static void XF86DRIResetProc(ExtensionEntry* extEntry);
+
+static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
+static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
+static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
+static void ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind);
+static Bool ephyrDRIPositionWindow (WindowPtr a_win,
+ int x, int y) ;
+static void ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y) ;
+
+static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
+static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
+static Bool findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair);
+
+static unsigned char DRIReqCode = 0;
+
+static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKey;
+static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKey;
+
+#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \
+ dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey))
+#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \
+ dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey))
+
+
+Bool
+ephyrDRIExtensionInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ ExtensionEntry* extEntry=NULL;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_has_dri ()) {
+ EPHYR_LOG ("host does not have DRI extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have DRI extension\n") ;
+ if (!hostx_has_xshape ()) {
+ EPHYR_LOG ("host does not have XShape extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have XShape extension\n") ;
+
+#ifdef XF86DRI_EVENTS
+ EventType = CreateNewResourceType (XF86DRIFreeEvents);
+#endif
+
+ if ((extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ XF86DRIResetProc,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ } else {
+ EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
+ goto out ;
+ }
+ screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ;
+ if (!screen_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
+ goto out ;
+ }
+ dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv);
+
+ if (!ephyrDRIScreenInit (a_screen)) {
+ EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
+ goto out ;
+ }
+ EphyrMirrorHostVisuals (a_screen) ;
+ is_ok=TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIScreenInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
+
+ screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
+
+ screen_priv->CreateWindow = a_screen->CreateWindow ;
+ screen_priv->DestroyWindow = a_screen->DestroyWindow ;
+ screen_priv->MoveWindow = a_screen->MoveWindow ;
+ screen_priv->PositionWindow = a_screen->PositionWindow ;
+ screen_priv->ClipNotify = a_screen->ClipNotify ;
+
+ a_screen->CreateWindow = ephyrDRICreateWindow ;
+ a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
+ a_screen->MoveWindow = ephyrDRIMoveWindow ;
+ a_screen->PositionWindow = ephyrDRIPositionWindow ;
+ a_screen->ClipNotify = ephyrDRIClipNotify ;
+
+ is_ok = TRUE ;
+
+ return is_ok ;
+}
+
+static Bool
+ephyrDRICreateWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->CreateWindow,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. win:%#x\n",
+ (unsigned int)a_win) ;
+
+ screen->CreateWindow = screen_priv->CreateWindow ;
+ is_ok = (*screen->CreateWindow) (a_win) ;
+ screen->CreateWindow = ephyrDRICreateWindow ;
+
+ if (is_ok) {
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ }
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIDestroyWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->DestroyWindow,
+ FALSE) ;
+
+ screen->DestroyWindow = screen_priv->DestroyWindow ;
+ if (screen->DestroyWindow) {
+ is_ok = (*screen->DestroyWindow) (a_win) ;
+ }
+ screen->DestroyWindow = ephyrDRIDestroyWindow ;
+
+ if (is_ok) {
+ EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (win_priv) {
+ destroyHostPeerWindow (a_win) ;
+ xfree (win_priv) ;
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ EPHYR_LOG ("destroyed the remote peer window\n") ;
+ }
+ }
+ return is_ok ;
+}
+
+static void
+ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+ int x=0,y=0;/*coords relative to parent window*/
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv
+ && screen_priv->MoveWindow) ;
+
+ screen->MoveWindow = screen_priv->MoveWindow ;
+ if (screen->MoveWindow) {
+ (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+ }
+ screen->MoveWindow = ephyrDRIMoveWindow ;
+
+ EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
+ if (!a_win->parent) {
+ EPHYR_LOG ("cannot move root window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*compute position relative to parent window*/
+ x = a_win->drawable.x - a_win->parent->drawable.x ;
+ y = a_win->drawable.y - a_win->parent->drawable.y ;
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = x ;
+ geo.y = y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+static Bool
+ephyrDRIPositionWindow (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->PositionWindow,
+ FALSE) ;
+
+ screen->PositionWindow = screen_priv->PositionWindow ;
+ if (screen->PositionWindow) {
+ (*screen->PositionWindow) (a_win, a_x, a_y) ;
+ }
+ screen->PositionWindow = ephyrDRIPositionWindow ;
+
+ EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_x ;
+ geo.y = a_y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+ return is_ok ;
+}
+
+static void
+ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrRect *rects=NULL;
+ int i=0 ;
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
+
+ screen->ClipNotify = screen_priv->ClipNotify ;
+ if (screen->ClipNotify) {
+ (*screen->ClipNotify) (a_win, a_x, a_y) ;
+ }
+ screen->ClipNotify = ephyrDRIClipNotify ;
+
+ EPHYR_LOG ("window: %#x\n", (unsigned int)a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ rects = xcalloc (REGION_NUM_RECTS (&a_win->clipList),
+ sizeof (EphyrRect)) ;
+ for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
+ memmove (&rects[i],
+ &REGION_RECTS (&a_win->clipList)[i],
+ sizeof (EphyrRect)) ;
+ rects[i].x1 -= a_win->drawable.x;
+ rects[i].x2 -= a_win->drawable.x;
+ rects[i].y1 -= a_win->drawable.y;
+ rects[i].y2 -= a_win->drawable.y;
+ }
+ /*
+ * push the clipping region of this window
+ * to the peer window in the host
+ */
+ is_ok = hostx_set_window_bounding_rectangles
+ (pair->remote,
+ rects,
+ REGION_NUM_RECTS (&a_win->clipList)) ;
+ is_ok = TRUE ;
+
+out:
+ if (rects) {
+ xfree (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+/**
+ * Duplicates a visual of a_screen
+ * In screen a_screen, for depth a_depth, find a visual which
+ * bitsPerRGBValue and colormap size equal
+ * a_bits_per_rgb_values and a_colormap_entries.
+ * The ID of that duplicated visual is set to a_new_id.
+ * That duplicated visual is then added to the list of visuals
+ * of the screen.
+ */
+static Bool
+EphyrDuplicateVisual (unsigned int a_screen,
+ short a_depth,
+ short a_class,
+ short a_bits_per_rgb_values,
+ short a_colormap_entries,
+ unsigned int a_red_mask,
+ unsigned int a_green_mask,
+ unsigned int a_blue_mask,
+ unsigned int a_new_id)
+{
+ Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
+ ScreenPtr screen=NULL ;
+ VisualRec new_visual, *new_visuals=NULL ;
+ int i=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (a_screen > screenInfo.numScreens) {
+ EPHYR_LOG_ERROR ("bad screen number\n") ;
+ goto out;
+ }
+ memset (&new_visual, 0, sizeof (VisualRec)) ;
+
+ /*get the screen pointed to by a_screen*/
+ screen = screenInfo.screens[a_screen] ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+
+ /*
+ * In that screen, first look for an existing visual that has the
+ * same characteristics as those passed in parameter
+ * to this function and copy it.
+ */
+ for (i=0; i < screen->numVisuals; i++) {
+ if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
+ screen->visuals[i].ColormapEntries == a_colormap_entries ) {
+ /*copy the visual found*/
+ memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
+ new_visual.vid = a_new_id ;
+ new_visual.class = a_class ;
+ new_visual.redMask = a_red_mask ;
+ new_visual.greenMask = a_green_mask ;
+ new_visual.blueMask = a_blue_mask ;
+ found_visual = TRUE ;
+ EPHYR_LOG ("found a visual that matches visual id: %d\n",
+ a_new_id) ;
+ break;
+ }
+ }
+ if (!found_visual) {
+ EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
+ goto out ;
+ }
+ /*
+ * be prepare to extend screen->visuals to add new_visual to it
+ */
+ new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
+ memmove (new_visuals,
+ screen->visuals,
+ screen->numVisuals*sizeof (VisualRec)) ;
+ memmove (&new_visuals[screen->numVisuals],
+ &new_visual,
+ sizeof (VisualRec)) ;
+ /*
+ * Now, in that same screen, update the screen->allowedDepths member.
+ * In that array, each element represents the visuals applicable to
+ * a given depth. So we need to add an entry matching the new visual
+ * that we are going to add to screen->visuals
+ */
+ for (i=0; i<screen->numDepths; i++) {
+ VisualID *vids=NULL;
+ DepthPtr cur_depth=NULL ;
+ /*find the entry matching a_depth*/
+ if (screen->allowedDepths[i].depth != a_depth)
+ continue ;
+ cur_depth = &screen->allowedDepths[i];
+ /*
+ * extend the list of visual IDs in that entry,
+ * so to add a_new_id in there.
+ */
+ vids = xrealloc (cur_depth->vids,
+ (cur_depth->numVids+1)*sizeof (VisualID));
+ if (!vids) {
+ EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
+ goto out ;
+ }
+ vids[cur_depth->numVids] = a_new_id ;
+ /*
+ * Okay now commit our change.
+ * Do really update screen->allowedDepths[i]
+ */
+ cur_depth->numVids++ ;
+ cur_depth->vids = vids ;
+ found_depth=TRUE;
+ }
+ if (!found_depth) {
+ EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
+ a_screen) ;
+ goto out ;
+ }
+ /*
+ * Commit our change to screen->visuals
+ */
+ xfree (screen->visuals) ;
+ screen->visuals = new_visuals ;
+ screen->numVisuals++ ;
+ new_visuals = NULL ;
+
+ is_ok = TRUE ;
+out:
+ if (new_visuals) {
+ xfree (new_visuals) ;
+ new_visuals = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+/**
+ * Duplicates the visuals of the host X server.
+ * This is necessary to have visuals that have the same
+ * ID as those of the host X. It is important to have that for
+ * GLX.
+ */
+static Bool
+EphyrMirrorHostVisuals (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE;
+ EphyrHostVisualInfo *visuals=NULL;
+ int nb_visuals=0, i=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
+ EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
+ goto out ;
+ }
+ for (i=0; i<nb_visuals; i++) {
+ if (!EphyrDuplicateVisual (a_screen->myNum,
+ visuals[i].depth,
+ visuals[i].class,
+ visuals[i].bits_per_rgb,
+ visuals[i].colormap_size,
+ visuals[i].red_mask,
+ visuals[i].green_mask,
+ visuals[i].blue_mask,
+ visuals[i].visualid)) {
+ EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
+ (int)visuals[i].visualid) ;
+ }
+ }
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+
+/*ARGSUSED*/
+static void
+XF86DRIResetProc (
+ ExtensionEntry* extEntry
+)
+{
+}
+
+static int
+ProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+
+ EPHYR_LOG ("enter\n") ;
+
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = XF86DRI_MINOR_VERSION;
+ rep.patchVersion = XF86DRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+ register int n;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client) || client->swapped)
+ rep.isCapable = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIOpenConnection (register ClientPtr client)
+{
+ xXF86DRIOpenConnectionReply rep;
+ drm_handle_t hSAREA;
+ char* busIdString;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIOpenConnection(stuff->screen,
+ &hSAREA,
+ &busIdString)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.busIdStringLength = 0;
+ if (busIdString)
+ rep.busIdStringLength = strlen(busIdString);
+ rep.length = (SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ ((rep.busIdStringLength + 3) & ~3)) >> 2;
+
+ rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+ rep.hSAREAHigh = 0;
+#endif
+
+ WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+ if (rep.busIdStringLength)
+ WriteToClient(client, rep.busIdStringLength, busIdString);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIAuthConnection (register ClientPtr client)
+{
+ xXF86DRIAuthConnectionReply rep;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
+ ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRICloseConnection (register ClientPtr client)
+{
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ /*
+ DRICloseConnection( screenInfo.screens[stuff->screen]);
+ */
+
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIGetClientDriverName (register ClientPtr client)
+{
+ xXF86DRIGetClientDriverNameReply rep;
+ char* clientDriverName;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ ephyrDRIGetClientDriverName (stuff->screen,
+ (int *)&rep.ddxDriverMajorVersion,
+ (int *)&rep.ddxDriverMinorVersion,
+ (int *)&rep.ddxDriverPatchVersion,
+ &clientDriverName);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.clientDriverNameLength = 0;
+ if (clientDriverName)
+ rep.clientDriverNameLength = strlen(clientDriverName);
+ rep.length = (SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ ((rep.clientDriverNameLength + 3) & ~3)) >> 2;
+
+ WriteToClient(client,
+ sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+ if (rep.clientDriverNameLength)
+ WriteToClient(client,
+ rep.clientDriverNameLength,
+ clientDriverName);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRICreateContext (register ClientPtr client)
+{
+ xXF86DRICreateContextReply rep;
+ ScreenPtr pScreen;
+ VisualPtr visual;
+ int i=0;
+ unsigned long context_id=0;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ pScreen = screenInfo.screens[stuff->screen];
+ visual = pScreen->visuals;
+
+ /* Find the requested X visual */
+ for (i = 0; i < pScreen->numVisuals; i++, visual++)
+ if (visual->vid == stuff->visual)
+ break;
+ if (i == pScreen->numVisuals) {
+ /* No visual found */
+ return BadValue;
+ }
+
+ context_id = stuff->context ;
+ if (!ephyrDRICreateContext (stuff->screen,
+ stuff->visual,
+ &context_id,
+ (drm_context_t *)&rep.hHWContext)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDestroyContext (register ClientPtr client)
+{
+ EPHYR_LOG ("enter\n") ;
+
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
+ return BadValue;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static Bool
+getWindowVisual (const WindowPtr a_win,
+ VisualPtr *a_visual)
+{
+ int i=0, visual_id=0 ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win
+ && a_win->drawable.pScreen
+ && a_win->drawable.pScreen->visuals,
+ FALSE) ;
+
+ visual_id = wVisual (a_win) ;
+ for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
+ if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
+ *a_visual = &a_win->drawable.pScreen->visuals[i] ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+
+#define NUM_WINDOW_PAIRS 256
+static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
+
+static Bool
+appendWindowPairToList (WindowPtr a_local,
+ int a_remote)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
+
+ EPHYR_LOG ("(local,remote):(%#x, %d)\n", (unsigned int)a_local, a_remote) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == NULL) {
+ window_pairs[i].local = a_local ;
+ window_pairs[i].remote = a_remote ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == a_local) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%#x, %d)\n",
+ (unsigned int)(*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+Bool
+findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].remote == a_remote) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+createHostPeerWindow (const WindowPtr a_win,
+ int *a_peer_win)
+{
+ Bool is_ok=FALSE ;
+ VisualPtr visual=NULL;
+ EphyrBox geo ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. a_win '%#x'\n", (unsigned int)a_win) ;
+ if (!getWindowVisual (a_win, &visual)) {
+ EPHYR_LOG_ERROR ("failed to get window visual\n") ;
+ goto out ;
+ }
+ if (!visual) {
+ EPHYR_LOG_ERROR ("failed to create visual\n") ;
+ goto out ;
+ }
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_win->drawable.x ;
+ geo.y = a_win->drawable.y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ if (!hostx_create_window (a_win->drawable.pScreen->myNum,
+ &geo, visual->vid, a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ goto out ;
+ }
+ if (!appendWindowPairToList (a_win, *a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
+ return is_ok ;
+}
+
+static Bool
+destroyHostPeerWindow (const WindowPtr a_win)
+{
+ Bool is_ok = FALSE ;
+ EphyrWindowPair *pair=NULL ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
+ goto out;
+ }
+ hostx_destroy_window (pair->remote) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+static int
+ProcXF86DRICreateDrawable (ClientPtr client)
+{
+ xXF86DRICreateDrawableReply rep;
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrDRIWindowPrivPtr win_priv=NULL;
+ int rc=0, remote_win=0;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ EPHYR_LOG ("lookedup drawable %#x\n", (unsigned int)drawable) ;
+ window = (WindowPtr)drawable;
+ if (findWindowPairFromLocal (window, &pair) && pair) {
+ remote_win = pair->remote ;
+ EPHYR_LOG ("found window '%#x' paire with remote '%d'\n",
+ (unsigned int)window, remote_win) ;
+ } else if (!createHostPeerWindow (window, &remote_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ return BadAlloc ;
+ }
+
+ if (!ephyrDRICreateDrawable (stuff->screen,
+ remote_win,
+ (drm_drawable_t *)&rep.hHWDrawable)) {
+ EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
+ return BadValue;
+ }
+
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
+ if (!win_priv) {
+ win_priv = xcalloc (1, sizeof (EphyrDRIWindowPrivRec)) ;
+ if (!win_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
+ return BadAlloc ;
+ }
+ dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv);
+ EPHYR_LOG ("paired window '%#x' with remote '%d'\n",
+ (unsigned int)window, remote_win) ;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDestroyDrawable (register ClientPtr client)
+{
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+ int rc=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rc = dixLookupDrawable(&drawable,
+ stuff->drawable,
+ client,
+ 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable;
+ if (!findWindowPairFromLocal (window, &pair) && pair) {
+ EPHYR_LOG_ERROR ("failed to find pair window\n") ;
+ return BadImplementation;
+ }
+ if (!ephyrDRIDestroyDrawable(stuff->screen,
+ pair->remote/*drawable in host x*/)) {
+ EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
+ return BadImplementation;
+ }
+ pair->local=NULL ;
+ pair->remote=0;
+
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIGetDrawableInfo (register ClientPtr client)
+{
+ xXF86DRIGetDrawableInfoReply rep;
+ DrawablePtr drawable;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
+ drm_clip_rect_t *clipRects=NULL;
+ drm_clip_rect_t *backClipRects=NULL;
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&rep, 0, sizeof (rep)) ;
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success || !drawable) {
+ EPHYR_LOG_ERROR ("could not get drawable\n") ;
+ return rc;
+ }
+
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable ;
+ memset (&pair, 0, sizeof (pair)) ;
+ if (!findWindowPairFromLocal (window, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
+ return BadMatch ;
+ }
+ EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
+ for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ REGION_RECTS (&window->clipList)[i].x1,
+ REGION_RECTS (&window->clipList)[i].y1,
+ REGION_RECTS (&window->clipList)[i].x2,
+ REGION_RECTS (&window->clipList)[i].y2) ;
+ }
+
+ if (!ephyrDRIGetDrawableInfo (stuff->screen,
+ pair->remote/*the drawable in hostx*/,
+ (unsigned int*)&rep.drawableTableIndex,
+ (unsigned int*)&rep.drawableTableStamp,
+ (int*)&X,
+ (int*)&Y,
+ (int*)&W,
+ (int*)&H,
+ (int*)&rep.numClipRects,
+ &clipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &backClipRects)) {
+ return BadValue;
+ }
+ EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
+ (int)rep.numClipRects, (int)rep.numBackClipRects) ;
+
+ rep.drawableX = X;
+ rep.drawableY = Y;
+ rep.drawableWidth = W;
+ rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+
+ if (rep.numClipRects) {
+ if (clipRects) {
+ ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+ int i=0;
+ EPHYR_LOG ("clip list of host gl drawable:\n") ;
+ for (i = 0; i < rep.numClipRects; i++) {
+ clipRects[i].x1 = max (clipRects[i].x1, 0);
+ clipRects[i].y1 = max (clipRects[i].y1, 0);
+ clipRects[i].x2 = min (clipRects[i].x2,
+ pScreen->width + clipRects[i].x1) ;
+ clipRects[i].y2 = min (clipRects[i].y2,
+ pScreen->width + clipRects[i].y1) ;
+
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ clipRects[i].x1, clipRects[i].y1,
+ clipRects[i].x2, clipRects[i].y2) ;
+ }
+ } else {
+ rep.numClipRects = 0;
+ }
+ } else {
+ EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
+ }
+ rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+ backClipRects = clipRects ;
+ rep.numBackClipRects = rep.numClipRects ;
+ if (rep.numBackClipRects)
+ rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+ EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
+ EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
+
+ rep.length = ((rep.length + 3) & ~3) >> 2;
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+ if (rep.numClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numClipRects,
+ (char *)clipRects);
+ }
+
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+ (char *)backClipRects);
+ }
+ if (clipRects) {
+ xfree(clipRects);
+ clipRects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIGetDeviceInfo (register ClientPtr client)
+{
+ xXF86DRIGetDeviceInfoReply rep;
+ drm_handle_t hFrameBuffer;
+ void *pDevPrivate;
+
+ EPHYR_LOG ("enter\n") ;
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIGetDeviceInfo (stuff->screen,
+ &hFrameBuffer,
+ (int*)&rep.framebufferOrigin,
+ (int*)&rep.framebufferSize,
+ (int*)&rep.framebufferStride,
+ (int*)&rep.devPrivateSize,
+ &pDevPrivate)) {
+ return BadValue;
+ }
+
+ rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+ rep.hFrameBufferHigh = 0;
+#endif
+
+ rep.length = 0;
+ if (rep.devPrivateSize) {
+ rep.length = (SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ ((rep.devPrivateSize + 3) & ~3)) >> 2;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+ if (rep.length) {
+ WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+ }
+ EPHYR_LOG ("leave\n") ;
+ return (client->noClientException);
+}
+
+static int
+ProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+ EPHYR_LOG ("enter\n") ;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + XF86DRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIOpenConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIOpenConnection(client);
+ }
+ case X_XF86DRICloseConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICloseConnection(client);
+ }
+ case X_XF86DRIGetClientDriverName: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetClientDriverName(client);
+ }
+ case X_XF86DRICreateContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateContext(client);
+ }
+ case X_XF86DRIDestroyContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyContext(client);
+ }
+ case X_XF86DRICreateDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateDrawable(client);
+ }
+ case X_XF86DRIDestroyDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyDrawable(client);
+ }
+ case X_XF86DRIGetDrawableInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDrawableInfo(client);
+ }
+ case X_XF86DRIGetDeviceInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDeviceInfo(client);
+ }
+ case X_XF86DRIAuthConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIAuthConnection(client);
+ }
+ /* {Open,Close}FullScreen are deprecated now */
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return BadRequest;
+ }
+ }
+}
+
+static int
+SProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+
+ EPHYR_LOG ("enter\n") ;
+ /*
+ * Only local clients are allowed DRI access, but remote clients still need
+ * these requests to find out cleanly.
+ */
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return DRIErrorBase + XF86DRIClientNotLocal;
+ }
+ }
+}
+
+#endif /*XEPHYR_DRI*/
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.h b/xorg-server/hw/kdrive/ephyr/ephyrdriext.h
new file mode 100644
index 000000000..01c9421fb
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.h
@@ -0,0 +1,42 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef __EPHYRDRIEXT_H__
+#define __EPHYRDRIEXT_H__
+
+typedef struct {
+ WindowPtr local ;
+ int remote ;
+} EphyrWindowPair;
+
+Bool ephyrDRIExtensionInit (ScreenPtr a_screen) ;
+
+Bool findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair);
+
+#endif /*__EPHYRDRIEXT_H__*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrglxext.c b/xorg-server/hw/kdrive/ephyr/ephyrglxext.c
new file mode 100644
index 000000000..2cc14517b
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrglxext.c
@@ -0,0 +1,732 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "extnsionst.h"
+#include "ephyrglxext.h"
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include <GL/glxproto.h>
+#include "glx/glxserver.h"
+#include "glx/indirect_table.h"
+#include "glx/indirect_util.h"
+#include "glx/unpack.h"
+#include "hostx.h"
+
+
+#ifdef XEPHYR_DRI
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+
+Bool
+ephyrHijackGLXExtension (void)
+{
+ const void *(*dispatch_functions)[2];
+
+ if (!hostx_has_glx ()) {
+ EPHYR_LOG ("host X does not have GLX\n") ;
+ return FALSE ;
+ }
+ EPHYR_LOG ("host X does have GLX\n") ;
+
+ if (!Single_dispatch_info.dispatch_functions) {
+ EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
+ return FALSE ;
+ }
+ /*
+ * hijack some single entry point dispatch functions
+ */
+ dispatch_functions = Single_dispatch_info.dispatch_functions ;
+ EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
+
+ dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
+ dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
+
+ dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
+ dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
+ dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
+ dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
+
+ dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
+ dispatch_functions[X_GLXQueryServerString][1] =
+ ephyrGLXQueryServerStringSwap ;
+
+ dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
+ dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
+
+ dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
+ dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
+
+ dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
+ dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
+
+ dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
+ dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
+
+ dispatch_functions[73][0] = ephyrGLXGetString ;
+ dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
+
+ dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
+ dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
+
+ /*
+ * hijack some vendor priv entry point dispatch functions
+ */
+ dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
+ dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
+ dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
+ EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
+
+ return TRUE ;
+}
+
+/*********************
+ * implementation of
+ * hijacked GLX entry
+ * points
+ ********************/
+
+int
+ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ ClientPtr client = a_cl->client;
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+ xGLXQueryVersionReply reply;
+ int major, minor;
+ int res = BadImplementation ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ major = req->majorVersion ;
+ minor = req->minorVersion ;
+
+ if (!ephyrHostGLXQueryVersion (&major, &minor)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major:%d, minor:%d\n",
+ major, minor);
+ reply.majorVersion = major ;
+ reply.minorVersion = minor ;
+ reply.length = 0 ;
+ reply.type = X_Reply ;
+ reply.sequenceNumber = client->sequence ;
+
+ if (client->swapped) {
+ __glXSwapQueryVersionReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res;
+}
+
+int
+ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT (&req->length);
+ __GLX_SWAP_INT (&req->majorVersion);
+ __GLX_SWAP_INT (&req->minorVersion);
+ return ephyrGLXQueryVersion (a_cl, a_pc) ;
+}
+
+static int
+ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
+ ClientPtr client = a_cl->client;
+ xGLXGetVisualConfigsReply reply;
+ int32_t *props_buf=NULL, num_visuals=0,
+ num_props=0, res=BadImplementation, i=0,
+ props_per_visual_size=0,
+ props_buf_size=0;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXGetVisualConfigs (req->screen,
+ &num_visuals,
+ &num_props,
+ &props_buf_size,
+ &props_buf)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+ reply.numVisuals = num_visuals;
+ reply.numProps = num_props;
+ reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+ }
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+ props_per_visual_size = props_buf_size/num_visuals ;
+ for (i=0; i < num_visuals; i++) {
+ WriteToClient (client,
+ props_per_visual_size,
+ (char*)props_buf +i*props_per_visual_size);
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ if (props_buf) {
+ xfree (props_buf) ;
+ props_buf = NULL ;
+ }
+ return res ;
+}
+
+static int
+ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
+ ClientPtr client = a_cl->client;
+ xGLXGetVisualConfigsReply reply;
+ int32_t *props_buf=NULL, num_visuals=0,
+ num_props=0, res=BadImplementation, i=0,
+ props_per_visual_size=0,
+ props_buf_size=0;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
+ &num_visuals,
+ &num_props,
+ &props_buf_size,
+ &props_buf)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+ reply.numVisuals = num_visuals;
+ reply.numProps = num_props;
+ reply.length = props_buf_size >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+ }
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+ props_per_visual_size = props_buf_size/num_visuals ;
+ for (i=0; i < num_visuals; i++) {
+ WriteToClient (client,
+ props_per_visual_size,
+ &((char*)props_buf)[i*props_per_visual_size]);
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ if (props_buf) {
+ xfree (props_buf) ;
+ props_buf = NULL ;
+ }
+ return res ;
+}
+
+int
+ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
+}
+
+
+int
+ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ int res=BadImplementation ;
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
+ EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
+ goto out ;
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT (&req->length);
+ __GLX_SWAP_INT (&req->major);
+ __GLX_SWAP_INT (&req->minor);
+ __GLX_SWAP_INT (&req->numbytes);
+
+ return ephyrGLXClientInfo (a_cl, a_pc) ;
+}
+
+int
+ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ int res = BadImplementation ;
+ ClientPtr client = a_cl->client;
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
+ xGLXQueryServerStringReply reply;
+ char *server_string=NULL, *buf=NULL;
+ int length=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetStringFromServer (req->screen,
+ req->name,
+ EPHYR_HOST_GLX_QueryServerString,
+ &server_string)) {
+ EPHYR_LOG_ERROR ("failed to query string from host\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("string: %s\n", server_string) ;
+ length= strlen (server_string) + 1;
+ reply.type = X_Reply ;
+ reply.sequenceNumber = client->sequence ;
+ reply.length = __GLX_PAD (length) >> 2 ;
+ reply.n = length ;
+ buf = xcalloc (reply.length << 2, 1);
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to allocate string\n;");
+ return BadAlloc;
+ }
+ memcpy (buf, server_string, length);
+
+ WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
+ WriteToClient(client, (int)(reply.length << 2), server_string);
+
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ if (server_string) {
+ xfree (server_string) ;
+ server_string = NULL;
+ }
+ if (buf) {
+ xfree (buf);
+ buf = NULL;
+ }
+ return res ;
+}
+
+int
+ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ EPHYR_LOG_ERROR ("not yet implemented\n") ;
+ return BadImplementation ;
+}
+
+
+int
+ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ EphyrHostWindowAttributes host_w_attrs ;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&a_req->length);
+ __GLX_SWAP_INT(&a_req->context);
+ __GLX_SWAP_INT(&a_req->visual);
+ __GLX_SWAP_INT(&a_req->screen);
+ __GLX_SWAP_INT(&a_req->shareList);
+ }
+
+ EPHYR_LOG ("context creation requested. localid:%d, "
+ "screen:%d, visual:%d, direct:%d\n",
+ (int)a_req->context, (int)a_req->screen,
+ (int)a_req->visual, (int)a_req->isDirect) ;
+
+ memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
+ if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
+ &host_w_attrs)) {
+ EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
+ goto out ;
+ }
+
+ EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
+
+ if (!ephyrHostGLXCreateContext (a_req->screen,
+ host_w_attrs.visualid,
+ a_req->context,
+ a_req->shareList,
+ a_req->isDirect)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
+ goto out ;
+ }
+ res = Success;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+
+ return ephyrGLXCreateContextReal (req, FALSE) ;
+}
+
+int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+ return ephyrGLXCreateContextReal (req, TRUE) ;
+}
+
+static int
+ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ int res=BadImplementation;
+ ClientPtr client = a_cl->client;
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
+
+ EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
+ if (!ephyrHostDestroyContext (req->context)) {
+ EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
+ client->errorValue = req->context ;
+ goto out ;
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
+ xGLXMakeCurrentReply reply ;
+ DrawablePtr drawable=NULL;
+ int rc=0;
+
+ EPHYR_LOG ("enter\n") ;
+ rc = dixLookupDrawable (&drawable,
+ req->drawable,
+ a_cl->client,
+ 0,
+ DixReadAccess);
+ EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
+ EPHYR_LOG ("screen nummber requested:%d\n",
+ drawable->pScreen->myNum) ;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
+ req->context,
+ req->oldContextTag,
+ (int*)&reply.contextTag)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
+ goto out;
+ }
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = a_cl->client->sequence;
+ if (a_do_swap) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.contextTag);
+ }
+ WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ ClientPtr client=NULL ;
+ int context_tag=0, name=0, res=BadImplementation, length=0 ;
+ char *string=NULL;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ client = a_cl->client ;
+
+ if (a_do_swap) {
+ __GLX_SWAP_INT (a_pc + 4);
+ __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
+ }
+ context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
+ a_pc += __GLX_SINGLE_HDR_SIZE;
+ name = *(GLenum*)(a_pc + 0);
+ EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
+ if (!ephyrHostGLXGetStringFromServer (context_tag,
+ name,
+ EPHYR_HOST_GLX_GetString,
+ &string)) {
+ EPHYR_LOG_ERROR ("failed to get string from server\n") ;
+ goto out ;
+ }
+ if (string) {
+ length = strlen (string) + 1;
+ EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
+ } else {
+ EPHYR_LOG ("got string: string (null)\n") ;
+ }
+ __GLX_BEGIN_REPLY (length);
+ __GLX_PUT_SIZE (length);
+ __GLX_SEND_HEADER ();
+ if (a_do_swap) {
+ __GLX_SWAP_REPLY_SIZE ();
+ __GLX_SWAP_REPLY_HEADER ();
+ }
+ WriteToClient (client, length, (char *)string);
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
+ GLenum int_name ;
+ int value=0 ;
+ GLint answer_buf_room[200];
+ GLint *buf=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ a_pc += __GLX_SINGLE_HDR_SIZE;
+
+ int_name = *(GLenum*) (a_pc+0) ;
+ if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
+ EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
+ goto out ;
+ }
+ buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
+ answer_buf_room,
+ sizeof (answer_buf_room),
+ 4) ;
+
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
+ res = BadAlloc ;
+ goto out ;
+ }
+ __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ ClientPtr client = a_cl->client;
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
+ xGLXIsDirectReply reply;
+ int is_direct=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
+ EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
+ goto out ;
+ }
+ reply.isDirect = is_direct ;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrglxext.h b/xorg-server/hw/kdrive/ephyr/ephyrglxext.h
new file mode 100644
index 000000000..22ea605d7
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrglxext.h
@@ -0,0 +1,35 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef __EPHYR_GLXEXT_H__
+#define __EPHYR_GLXEXT_H__
+
+#include <X11/Xdefs.h>
+Bool ephyrHijackGLXExtension (void) ;
+
+#endif /*__EPHYR_GLXEXT_H__*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostglx.c b/xorg-server/hw/kdrive/ephyr/ephyrhostglx.c
new file mode 100644
index 000000000..1eec4e02b
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrhostglx.c
@@ -0,0 +1,703 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * a lots of the content of this file has been adapted from the mesa source
+ * code.
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+/*
+ * including some server headers (like kdrive-config.h)
+ * might define the macro _XSERVER64
+ * on 64 bits machines. That macro must _NOT_ be defined for Xlib
+ * client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+
+#include <X11/Xlibint.h>
+#include <GL/glx.h>
+#include <GL/internal/glcore.h>
+#include <GL/glxproto.h>
+#include <GL/glxint.h>
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "hostx.h"
+
+#ifdef XEPHYR_DRI
+enum VisualConfRequestType {
+ EPHYR_GET_FB_CONFIG,
+ EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
+ EPHYR_GET_VISUAL_CONFIGS
+
+};
+
+static Bool ephyrHostGLXGetVisualConfigsInternal
+ (enum VisualConfRequestType a_type,
+ int32_t a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf);
+Bool
+ephyrHostGLXGetMajorOpcode (int *a_opcode)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy=hostx_get_display () ;
+ static int opcode ;
+ int first_event_return=0, first_error_return=0;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+ if (!opcode) {
+ if (!XQueryExtension (dpy, GLX_EXTENSION_NAME, &opcode,
+ &first_event_return, &first_error_return)) {
+ EPHYR_LOG_ERROR ("XQueryExtension() failed\n") ;
+ goto out ;
+ }
+ }
+ *a_opcode = opcode ;
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("release\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXQueryVersion (int *a_major, int *a_minor)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+ int major_opcode=0;
+ xGLXQueryVersionReq *req=NULL;
+ xGLXQueryVersionReply reply;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_major && a_minor, FALSE) ;
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
+
+ /* Send the glXQueryVersion request */
+ memset (&reply, 0, sizeof (reply)) ;
+ LockDisplay (dpy);
+ GetReq (GLXQueryVersion, req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXQueryVersion;
+ req->majorVersion = 2;
+ req->minorVersion = 1;
+ _XReply(dpy, (xReply*) &reply, 0, False);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ *a_major = reply.majorVersion ;
+ *a_minor = reply.minorVersion ;
+
+ EPHYR_LOG ("major:%d, minor:%d\n", *a_major, *a_minor) ;
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+/**
+ * GLX protocol structure for the ficticious "GXLGenericGetString" request.
+ *
+ * This is a non-existant protocol packet. It just so happens that all of
+ * the real protocol packets used to request a string from the server have
+ * an identical binary layout. The only difference between them is the
+ * meaning of the \c for_whom field and the value of the \c glxCode.
+ * (this has been copied from the mesa source code)
+ */
+typedef struct GLXGenericGetString {
+ CARD8 reqType;
+ CARD8 glxCode;
+ CARD16 length B16;
+ CARD32 for_whom B32;
+ CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+/* These defines are only needed to make the GetReq macro happy.
+ */
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+Bool
+ephyrHostGLXGetStringFromServer (int a_screen_number,
+ int a_string_name,
+ enum EphyrHostGLXGetStringOps a_op,
+ char **a_string)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+ int default_screen = DefaultScreen (dpy);
+ xGLXGenericGetStringReq *req=NULL;
+ xGLXSingleReply reply;
+ int length=0, numbytes=0, major_opcode=0, get_string_op=0;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_string, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ switch (a_op) {
+ case EPHYR_HOST_GLX_QueryServerString:
+ get_string_op = X_GLXQueryServerString;
+ break ;
+ case EPHYR_HOST_GLX_GetString:
+ get_string_op = X_GLsop_GetString;
+ EPHYR_LOG ("Going to glXGetString. strname:%#x, ctxttag:%d\n",
+ a_string_name, a_screen_number) ;
+ break ;
+ default:
+ EPHYR_LOG_ERROR ("unknown EphyrHostGLXGetStringOp:%d\n", a_op) ;
+ goto out ;
+ }
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major opcode: %d\n", major_opcode) ;
+
+ LockDisplay (dpy);
+
+ /* All of the GLX protocol requests for getting a string from the server
+ * look the same. The exact meaning of the a_for_whom field is usually
+ * either the screen number (for glXQueryServerString) or the context tag
+ * (for GLXSingle).
+ */
+ GetReq (GLXGenericGetString, req);
+ req->reqType = major_opcode;
+ req->glxCode = get_string_op;
+ req->for_whom = default_screen;
+ req->name = a_string_name;
+
+ _XReply (dpy, (xReply *)&reply, 0, False);
+
+ length = reply.length * 4;
+ if (!length) {
+ numbytes = 0;
+ } else {
+ numbytes = reply.size;
+ }
+ EPHYR_LOG ("going to get a string of size:%d\n", numbytes) ;
+
+ *a_string = (char *) Xmalloc (numbytes +1);
+ if (!a_string) {
+ EPHYR_LOG_ERROR ("allocation failed\n") ;
+ goto out;
+ }
+
+ memset (*a_string, 0, numbytes+1) ;
+ if (_XRead (dpy, *a_string, numbytes)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ EPHYR_LOG_ERROR ("read failed\n") ;
+ goto out ;
+ }
+ length -= numbytes;
+ _XEatData (dpy, length) ;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ EPHYR_LOG ("strname:%#x, strvalue:'%s', strlen:%d\n",
+ a_string_name, *a_string, numbytes) ;
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrHostGLXGetVisualConfigsInternal (enum VisualConfRequestType a_type,
+ int32_t a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+ xGLXGetVisualConfigsReq *req;
+ xGLXGetFBConfigsReq *fb_req;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXGetFBConfigsSGIXReq *sgi_req;
+ xGLXGetVisualConfigsReply reply;
+ char *server_glx_version=NULL,
+ *server_glx_extensions=NULL ;
+ int j=0,
+ screens=0,
+ major_opcode=0,
+ num_props=0,
+ num_visuals=0,
+ props_buf_size=0,
+ props_per_visual_size=0;
+ int32_t *props_buf=NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ screens = ScreenCount (dpy);
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get opcode\n") ;
+ goto out ;
+ }
+
+ LockDisplay(dpy);
+ switch (a_type) {
+ case EPHYR_GET_FB_CONFIG:
+ GetReq(GLXGetFBConfigs,fb_req);
+ fb_req->reqType = major_opcode;
+ fb_req->glxCode = X_GLXGetFBConfigs;
+ fb_req->screen = DefaultScreen (dpy);
+ break;
+
+ case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXGetFBConfigsSGIXReq
+ -
+ sz_xGLXVendorPrivateWithReplyReq,
+ vpreq);
+ sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+ sgi_req->reqType = major_opcode;
+ sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+ sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+ sgi_req->screen = DefaultScreen (dpy);
+ break;
+
+ case EPHYR_GET_VISUAL_CONFIGS:
+ GetReq(GLXGetVisualConfigs,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXGetVisualConfigs;
+ req->screen = DefaultScreen (dpy);
+ break;
+ }
+
+ if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
+ EPHYR_LOG_ERROR ("unknown error\n") ;
+ UnlockDisplay(dpy);
+ goto out ;
+ }
+ if (!reply.numVisuals) {
+ EPHYR_LOG_ERROR ("screen does not support GL rendering\n") ;
+ UnlockDisplay(dpy);
+ goto out ;
+ }
+ num_visuals = reply.numVisuals ;
+
+ /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
+ * FIXME: FBconfigs?
+ */
+ /* Check number of properties */
+ num_props = reply.numProps;
+ if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
+ (num_props > __GLX_MAX_CONFIG_PROPS)) {
+ /* Huh? Not in protocol defined limits. Punt */
+ EPHYR_LOG_ERROR ("got a bad reply to request\n") ;
+ UnlockDisplay(dpy);
+ goto out ;
+ }
+
+ if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
+ num_props *= 2;
+ }
+ props_per_visual_size = num_props * __GLX_SIZE_INT32;
+ props_buf_size = props_per_visual_size * reply.numVisuals;
+ props_buf = malloc (props_buf_size) ;
+ for (j = 0; j < reply.numVisuals; j++) {
+ if (_XRead (dpy,
+ &((char*)props_buf)[j*props_per_visual_size],
+ props_per_visual_size) != Success) {
+ EPHYR_LOG_ERROR ("read failed\n") ;
+ }
+ }
+ UnlockDisplay(dpy);
+
+ *a_num_visuals = num_visuals ;
+ *a_num_props = reply.numProps ;
+ *a_props_buf_size = props_buf_size ;
+ *a_props_buf = props_buf ;
+ is_ok = TRUE ;
+
+out:
+ if (server_glx_version) {
+ XFree (server_glx_version) ;
+ server_glx_version = NULL ;
+ }
+ if (server_glx_extensions) {
+ XFree (server_glx_extensions) ;
+ server_glx_extensions = NULL ;
+ }
+ SyncHandle () ;
+ return is_ok;
+}
+
+Bool
+ephyrHostGLXGetVisualConfigs (int32_t a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf)
+{
+ Bool is_ok = FALSE;
+
+ EPHYR_LOG ("enter\n") ;
+ is_ok = ephyrHostGLXGetVisualConfigsInternal (EPHYR_GET_VISUAL_CONFIGS,
+ a_screen,
+ a_num_visuals,
+ a_num_props,
+ a_props_buf_size,
+ a_props_buf) ;
+
+ EPHYR_LOG ("leave:%d\n", is_ok) ;
+ return is_ok;
+}
+
+Bool
+ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf)
+{
+ Bool is_ok=FALSE ;
+ EPHYR_LOG ("enter\n") ;
+ is_ok = ephyrHostGLXGetVisualConfigsInternal
+ (EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
+ a_screen,
+ a_num_visuals,
+ a_num_props,
+ a_props_buf_size,
+ a_props_buf) ;
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
+ const char* a_extension_list)
+{
+ Bool is_ok = FALSE ;
+ Display *dpy = hostx_get_display () ;
+ xGLXClientInfoReq *req;
+ int size;
+ int32_t major_opcode=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_extension_list, FALSE) ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+
+ LockDisplay (dpy);
+
+ GetReq (GLXClientInfo,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXClientInfo;
+ req->major = a_major;
+ req->minor = a_minor;
+
+ size = strlen (a_extension_list) + 1;
+ req->length += (size + 3) >> 2;
+ req->numbytes = size;
+ Data (dpy, a_extension_list, size);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ is_ok=TRUE ;
+
+out:
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXCreateContext (int a_screen,
+ int a_visual_id,
+ int a_context_id,
+ int a_share_list_ctxt_id,
+ Bool a_direct)
+{
+ Bool is_ok = FALSE;
+ Display *dpy = hostx_get_display ();
+ int major_opcode=0, remote_context_id=0;
+ xGLXCreateContextReq *req;
+
+ EPHYR_LOG ("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
+ a_screen, a_visual_id, a_context_id, a_direct) ;
+
+ if (!hostx_allocate_resource_id_peer (a_context_id, &remote_context_id)) {
+ EPHYR_LOG_ERROR ("failed to peer the context id %d host X",
+ remote_context_id) ;
+ goto out ;
+ }
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+
+ LockDisplay (dpy) ;
+
+ /* Send the glXCreateContext request */
+ GetReq(GLXCreateContext,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXCreateContext;
+ req->context = remote_context_id;
+ req->visual = a_visual_id;
+ req->screen = DefaultScreen (dpy);
+ req->shareList = a_share_list_ctxt_id;
+ req->isDirect = a_direct;
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostDestroyContext (int a_ctxt_id)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display ();
+ int major_opcode=0, remote_ctxt_id=0 ;
+ xGLXDestroyContextReq *req=NULL;
+
+ EPHYR_LOG ("enter:%d\n", a_ctxt_id) ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_ctxt_id)) {
+ EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host context id:%d\n", remote_ctxt_id) ;
+
+ LockDisplay (dpy);
+ GetReq (GLXDestroyContext,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXDestroyContext;
+ req->context = remote_ctxt_id;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostGLXMakeCurrent (int a_drawable,
+ int a_glx_ctxt_id,
+ int a_old_ctxt_tag,
+ int *a_ctxt_tag)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+ int32_t major_opcode=0 ;
+ int remote_glx_ctxt_id=0 ;
+ xGLXMakeCurrentReq *req;
+ xGLXMakeCurrentReply reply;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_ctxt_tag, FALSE) ;
+
+ EPHYR_LOG ("enter. drawable:%d, context:%d, oldtag:%d\n",
+ a_drawable, a_glx_ctxt_id, a_old_ctxt_tag) ;
+
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ if (!hostx_get_resource_id_peer (a_glx_ctxt_id, &remote_glx_ctxt_id)) {
+ EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+ goto out ;
+ }
+
+ LockDisplay (dpy);
+
+ GetReq (GLXMakeCurrent,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXMakeCurrent;
+ req->drawable = a_drawable;
+ req->context = remote_glx_ctxt_id;
+ req->oldContextTag = a_old_ctxt_tag;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!_XReply (dpy, (xReply*)&reply, 0, False)) {
+ EPHYR_LOG_ERROR ("failed to get reply from host\n") ;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ goto out ;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *a_ctxt_tag = reply.contextTag ;
+ EPHYR_LOG ("context tag:%d\n", *a_ctxt_tag) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+#define X_GLXSingle 0
+
+#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
+ *((INT8 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
+ *((INT16 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
+ *((INT32 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
+ *((FLOAT32 *) (pc + offset)) = a
+
+#define EPHYR_GLX_SINGLE_READ_XREPLY() \
+ (void) _XReply(dpy, (xReply*) &reply, 0, False)
+
+#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
+ a = (cast) reply.retval
+
+#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
+ a = (GLint) reply.size
+
+#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
+ *p = *(GLbyte *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
+ *p = *(GLshort *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_LONG(p) \
+ *p = *(GLint *)&reply.pad3;
+
+#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
+ *p = *(GLfloat *)&reply.pad3;
+
+Bool
+ephyrHostGetIntegerValue (int a_current_context_tag, int a_int, int *a_val)
+{
+ Bool is_ok=FALSE;
+ Display *dpy = hostx_get_display () ;
+ int major_opcode=0, size=0;
+ xGLXSingleReq *req=NULL;
+ xGLXSingleReply reply;
+ unsigned char* pc=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_val, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ LockDisplay (dpy) ;
+ GetReqExtra (GLXSingle, 4, req) ;
+ req->reqType = major_opcode ;
+ req->glxCode = X_GLsop_GetIntegerv ;
+ req->contextTag = a_current_context_tag;
+ pc = ((unsigned char *)(req) + sz_xGLXSingleReq) ;
+ EPHYR_GLX_SINGLE_PUT_LONG (0, a_int) ;
+ EPHYR_GLX_SINGLE_READ_XREPLY () ;
+ EPHYR_GLX_SINGLE_GET_SIZE (size) ;
+ if (!size) {
+ UnlockDisplay (dpy) ;
+ SyncHandle () ;
+ EPHYR_LOG_ERROR ("X_GLsop_GetIngerv failed\n") ;
+ goto out ;
+ }
+ EPHYR_GLX_SINGLE_GET_LONG (a_val) ;
+ UnlockDisplay (dpy) ;
+ SyncHandle () ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostIsContextDirect (int a_ctxt_id,
+ int *a_is_direct)
+{
+ Bool is_ok=FALSE;
+ Display *dpy = hostx_get_display () ;
+ xGLXIsDirectReq *req=NULL;
+ xGLXIsDirectReply reply;
+ int major_opcode=0, remote_glx_ctxt_id=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetMajorOpcode (&major_opcode)) {
+ EPHYR_LOG_ERROR ("failed to get major opcode\n") ;
+ goto out ;
+ }
+ if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
+ EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n") ;
+ goto out ;
+ }
+ memset (&reply, 0, sizeof (reply)) ;
+
+ /* Send the glXIsDirect request */
+ LockDisplay (dpy);
+ GetReq (GLXIsDirect,req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXIsDirect;
+ req->context = remote_glx_ctxt_id;
+ if (!_XReply (dpy, (xReply*) &reply, 0, False)) {
+ EPHYR_LOG_ERROR ("fail in reading reply from host\n") ;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ goto out ;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *a_is_direct = reply.isDirect ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostglx.h b/xorg-server/hw/kdrive/ephyr/ephyrhostglx.h
new file mode 100644
index 000000000..6db362f30
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrhostglx.h
@@ -0,0 +1,76 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef __EPHYRHOSTGLX_H__
+#define __EPHYRHOSTGLX_H__
+
+enum EphyrHostGLXGetStringOps {
+ EPHYR_HOST_GLX_UNDEF,
+ EPHYR_HOST_GLX_QueryServerString,
+ EPHYR_HOST_GLX_GetString,
+};
+
+Bool ephyrHostGLXQueryVersion (int *a_maj, int *a_min) ;
+Bool ephyrHostGLXGetStringFromServer (int a_screen_number,
+ int a_string_name,
+ enum EphyrHostGLXGetStringOps a_op,
+ char **a_string) ;
+Bool ephyrHostGLXGetVisualConfigs (int a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf) ;
+Bool
+ephyrHostGLXVendorPrivGetFBConfigsSGIX (int a_screen,
+ int32_t *a_num_visuals,
+ int32_t *a_num_props,
+ int32_t *a_props_buf_size,
+ int32_t **a_props_buf);
+Bool ephyrHostGLXGetMajorOpcode (int32_t *a_opcode) ;
+Bool ephyrHostGLXSendClientInfo (int32_t a_major, int32_t a_minor,
+ const char* a_extension_list) ;
+Bool ephyrHostGLXCreateContext (int a_screen,
+ int a_visual_id,
+ int a_context_id,
+ int a_shared_list_ctx_id,
+ Bool a_direct) ;
+
+Bool ephyrHostDestroyContext (int a_ctxt_id) ;
+
+Bool ephyrHostGLXMakeCurrent (int a_drawable, int a_glx_ctxt_id,
+ int a_olg_ctxt_tag, int *a_ctxt_tag) ;
+
+Bool ephyrHostGetIntegerValue (int a_current_context_tag,
+ int a_int,
+ int *a_val) ;
+
+Bool ephyrHostIsContextDirect (int a_ctxt_id,
+ int *a_is_direct) ;
+
+
+#endif /*__EPHYRHOSTGLX_H__*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c
new file mode 100644
index 000000000..41c0b755b
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -0,0 +1,1014 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+/*
+ * including some server headers (like kdrive-config.h)
+ * might define the macro _XSERVER64
+ * on 64 bits machines. That macro must _NOT_ be defined for Xlib
+ * client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/Xvproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#define _HAVE_XALLOC_DECLS
+
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+#include "ephyrlog.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+static XExtensionInfo _xv_info_data;
+static XExtensionInfo *xv_info = &_xv_info_data;
+static char *xv_extension_name = XvName;
+static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
+ char * buf, int n);
+static int xv_close_display(Display *dpy, XExtCodes *codes);
+static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
+
+static XExtensionHooks xv_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ xv_close_display, /* close_display */
+ xv_wire_to_event, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ xv_error_string /* error_string */
+};
+
+
+static char *xv_error_list[] =
+{
+ "BadPort", /* XvBadPort */
+ "BadEncoding", /* XvBadEncoding */
+ "BadControl" /* XvBadControl */
+};
+
+
+#define XvCheckExtension(dpy, i, val) \
+ XextCheckExtension(dpy, i, xv_extension_name, val)
+#define XvGetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = info->codes->major_opcode;\
+ req->xvReqType = xv_##name; \
+ req->length = (SIZEOF(xv##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(xv##name##Req);\
+ dpy->request++
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
+
+
+static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
+ xv_extension_name,
+ &xv_extension_hooks,
+ XvNumEvents, NULL)
+
+static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
+ XvNumErrors, xv_error_list)
+
+struct _EphyrHostXVAdaptorArray {
+ XvAdaptorInfo *adaptors ;
+ unsigned int nb_adaptors ;
+};
+
+/*heavily copied from libx11*/
+#define BUFSIZE 2048
+static void
+ephyrHostXVLogXErrorEvent (Display *a_display,
+ XErrorEvent *a_err_event,
+ FILE *a_fp)
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ const char *mtype = "XlibMessage";
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ Display *dpy = a_display ;
+
+ XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(a_fp, mesg, a_err_event->request_code);
+ if (a_err_event->request_code < 128) {
+ sprintf(number, "%d", a_err_event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != a_err_event->request_code);
+ ext = ext->next)
+ ;
+ if (ext)
+ strcpy(buffer, ext->name);
+ else
+ buffer[0] = '\0';
+ }
+ (void) fprintf(a_fp, " (%s)\n", buffer);
+ if (a_err_event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->minor_code);
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(a_fp, " (%s)", buffer);
+ }
+ fputs("\n", a_fp);
+ }
+ if (a_err_event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < (int)a_err_event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ a_err_event->error_code - bext->codes.first_error);
+ else
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+ fputs("\n", a_fp);
+ }
+ /* let extensions try to print the values */
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, a_err_event, a_fp);
+ }
+ } else if ((a_err_event->error_code == BadWindow) ||
+ (a_err_event->error_code == BadPixmap) ||
+ (a_err_event->error_code == BadCursor) ||
+ (a_err_event->error_code == BadFont) ||
+ (a_err_event->error_code == BadDrawable) ||
+ (a_err_event->error_code == BadColor) ||
+ (a_err_event->error_code == BadGC) ||
+ (a_err_event->error_code == BadIDChoice) ||
+ (a_err_event->error_code == BadValue) ||
+ (a_err_event->error_code == BadAtom)) {
+ if (a_err_event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (a_err_event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+ fputs("\n", a_fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", a_fp);
+ (void) fprintf(a_fp, mesg, dpy->request);
+ fputs("\n", a_fp);
+}
+
+static int
+ephyrHostXVErrorHandler (Display *a_display,
+ XErrorEvent *a_error_event)
+{
+ EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
+ ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
+ return Success ;
+}
+
+void
+ephyrHostXVInit (void)
+{
+ static Bool s_initialized ;
+
+ if (s_initialized)
+ return ;
+ XSetErrorHandler (ephyrHostXVErrorHandler) ;
+ s_initialized = TRUE ;
+}
+
+Bool
+ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
+{
+ EphyrHostXVAdaptorArray *result=NULL ;
+ int ret=0 ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
+ if (!result)
+ goto out ;
+
+ ret = XvQueryAdaptors (hostx_get_display (),
+ DefaultRootWindow (hostx_get_display ()),
+ &result->nb_adaptors,
+ &result->adaptors) ;
+ if (ret != Success) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
+ goto out ;
+ }
+ *a_adaptors = result ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+void
+ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
+{
+ if (!a_adaptors)
+ return ;
+ if (a_adaptors->adaptors) {
+ XvFreeAdaptorInfo (a_adaptors->adaptors) ;
+ a_adaptors->adaptors = NULL ;
+ a_adaptors->nb_adaptors = 0 ;
+ }
+ XFree (a_adaptors) ;
+}
+
+int
+ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+ return a_this->nb_adaptors ;
+}
+
+EphyrHostXVAdaptor*
+ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+ int a_index)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ if (a_index >= a_this->nb_adaptors)
+ return NULL ;
+ return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
+}
+
+char
+ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+ return ((XvAdaptorInfo*)a_this)->type ;
+}
+
+const char*
+ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ return ((XvAdaptorInfo*)a_this)->name ;
+}
+
+EphyrHostVideoFormat*
+ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
+ int *a_nb_formats)
+{
+ EphyrHostVideoFormat *formats=NULL ;
+ int nb_formats=0, i=0 ;
+ XVisualInfo *visual_info, visual_info_template ;
+ int nb_visual_info ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
+ formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
+ for (i=0; i < nb_formats; i++) {
+ memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
+ visual_info_template.visualid =
+ ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
+ visual_info = XGetVisualInfo (hostx_get_display (),
+ VisualIDMask,
+ &visual_info_template,
+ &nb_visual_info) ;
+ formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
+ formats[i].visual_class = visual_info->class ;
+ XFree (visual_info) ;
+ }
+ if (a_nb_formats)
+ *a_nb_formats = nb_formats ;
+ return formats ;
+}
+
+int
+ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+ return ((XvAdaptorInfo*)a_this)->num_ports ;
+}
+
+int
+ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+ return ((XvAdaptorInfo*)a_this)->base_id ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVQueryEncodings (int a_port_id,
+ EphyrHostEncoding **a_encodings,
+ unsigned int *a_num_encodings)
+{
+ EphyrHostEncoding *encodings=NULL ;
+ XvEncodingInfo *encoding_info=NULL ;
+ unsigned int num_encodings=0, i;
+ int ret=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
+
+ ret = XvQueryEncodings (hostx_get_display (),
+ a_port_id,
+ &num_encodings,
+ &encoding_info) ;
+ if (num_encodings && encoding_info) {
+ encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
+ for (i=0; i<num_encodings; i++) {
+ encodings[i].id = encoding_info[i].encoding_id ;
+ encodings[i].name = strdup (encoding_info[i].name) ;
+ encodings[i].width = encoding_info[i].width ;
+ encodings[i].height = encoding_info[i].height ;
+ encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
+ encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
+ }
+ }
+ if (encoding_info) {
+ XvFreeEncodingInfo (encoding_info) ;
+ encoding_info = NULL ;
+ }
+ *a_encodings = encodings ;
+ *a_num_encodings = num_encodings ;
+
+ if (ret != Success)
+ return FALSE ;
+ return TRUE ;
+}
+
+void
+ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+
+ if (!a_encodings)
+ return ;
+ for (i=0; i < a_num_encodings; i++) {
+ if (a_encodings[i].name) {
+ xfree (a_encodings[i].name) ;
+ a_encodings[i].name = NULL ;
+ }
+ }
+ xfree (a_encodings) ;
+}
+
+void
+ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
+{
+ if (!a_attributes)
+ return ;
+ XFree (a_attributes) ;
+}
+
+Bool
+ephyrHostXVQueryPortAttributes (int a_port_id,
+ EphyrHostAttribute **a_attributes,
+ int *a_num_attributes)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
+
+ *a_attributes =
+ (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
+ a_port_id,
+ a_num_attributes);
+
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVQueryImageFormats (int a_port_id,
+ EphyrHostImageFormat **a_formats,
+ int *a_num_format)
+{
+ XvImageFormatValues *result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
+
+ result = XvListImageFormats (hostx_get_display (),
+ a_port_id,
+ a_num_format) ;
+ *a_formats = (EphyrHostImageFormat*) result ;
+ return TRUE ;
+
+}
+
+Bool
+ephyrHostXVSetPortAttribute (int a_port_id,
+ int a_atom,
+ int a_attr_value)
+{
+ int res=Success ;
+
+ EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
+ a_atom,
+ XGetAtomName (hostx_get_display (), a_atom),
+ a_attr_value) ;
+
+ res = XvSetPortAttribute (hostx_get_display (),
+ a_port_id,
+ a_atom,
+ a_attr_value) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
+ return FALSE ;
+ }
+ XFlush (hostx_get_display ()) ;
+ EPHYR_LOG ("leave\n") ;
+
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVGetPortAttribute (int a_port_id,
+ int a_atom,
+ int *a_attr_value)
+{
+ int res=Success ;
+ Bool ret=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
+
+ EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
+ a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
+
+ res = XvGetPortAttribute (hostx_get_display (),
+ a_port_id,
+ a_atom,
+ a_attr_value) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
+ goto out ;
+ }
+ EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
+
+ ret = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return ret ;
+}
+
+Bool
+ephyrHostXVQueryBestSize (int a_port_id,
+ Bool a_motion,
+ unsigned int a_frame_w,
+ unsigned int a_frame_h,
+ unsigned int a_drw_w,
+ unsigned int a_drw_h,
+ unsigned int *a_actual_w,
+ unsigned int *a_actual_h)
+{
+ int res=0 ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
+
+ EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
+ a_frame_w, a_frame_h,
+ a_drw_w, a_drw_h) ;
+
+ res = XvQueryBestSize (hostx_get_display (),
+ a_port_id,
+ a_motion,
+ a_frame_w, a_frame_h,
+ a_drw_w, a_drw_h,
+ a_actual_w, a_actual_h) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
+ goto out ;
+ }
+ XSync (hostx_get_display (), FALSE) ;
+
+ EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
+{
+ XExtDisplayInfo *info = xv_find_display (dpy);
+ XvEvent *re = (XvEvent *)host;
+ xvEvent *event = (xvEvent *)wire;
+
+ XvCheckExtension(dpy, info, False);
+
+ switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
+ case XvVideoNotify:
+ re->xvvideo.type = event->u.u.type & 0x7f;
+ re->xvvideo.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvvideo.display = dpy;
+ re->xvvideo.time = event->u.videoNotify.time;
+ re->xvvideo.reason = event->u.videoNotify.reason;
+ re->xvvideo.drawable = event->u.videoNotify.drawable;
+ re->xvvideo.port_id = event->u.videoNotify.port;
+ break;
+ case XvPortNotify:
+ re->xvport.type = event->u.u.type & 0x7f;
+ re->xvport.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvport.display = dpy;
+ re->xvport.time = event->u.portNotify.time;
+ re->xvport.port_id = event->u.portNotify.port;
+ re->xvport.attribute = event->u.portNotify.attribute;
+ re->xvport.value = event->u.portNotify.value;
+ break;
+ default:
+ return False;
+ }
+
+ return True ;
+}
+
+Bool
+ephyrHostXVQueryImageAttributes (int a_port_id,
+ int a_image_id /*image fourcc code*/,
+ unsigned short *a_width,
+ unsigned short *a_height,
+ int *a_image_size,
+ int *a_pitches,
+ int *a_offsets)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool ret=FALSE ;
+ XExtDisplayInfo *info = xv_find_display (dpy);
+ xvQueryImageAttributesReq *req=NULL;
+ xvQueryImageAttributesReply rep;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
+
+ XvCheckExtension (dpy, info, FALSE);
+
+ LockDisplay (dpy);
+
+ XvGetReq (QueryImageAttributes, req);
+ req->id = a_image_id;
+ req->port = a_port_id;
+ req->width = *a_width;
+ req->height = *a_height;
+ /*
+ * read the reply
+ */
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
+ EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
+ goto out ;
+ }
+ if (a_pitches && a_offsets) {
+ _XRead (dpy,
+ (char*)a_pitches,
+ rep.num_planes << 2);
+ _XRead (dpy,
+ (char*)a_offsets,
+ rep.num_planes << 2);
+ } else {
+ _XEatData(dpy, rep.length << 2);
+ }
+ *a_width = rep.width ;
+ *a_height = rep.height ;
+ *a_image_size = rep.data_size ;
+
+ ret = TRUE ;
+
+out:
+ UnlockDisplay (dpy) ;
+ SyncHandle ();
+ return ret ;
+}
+
+Bool
+ephyrHostGetAtom (const char* a_name,
+ Bool a_create_if_not_exists,
+ int *a_atom)
+{
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
+
+ atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
+ if (atom == None) {
+ return FALSE ;
+ }
+ *a_atom = atom ;
+ return TRUE ;
+}
+
+char*
+ephyrHostGetAtomName (int a_atom)
+{
+ return XGetAtomName (hostx_get_display (), a_atom) ;
+}
+
+void
+ephyrHostFree (void *a_pointer)
+{
+ if (a_pointer)
+ XFree (a_pointer) ;
+}
+
+Bool
+ephyrHostXVPutImage (int a_screen_num,
+ int a_port_id,
+ int a_image_id,
+ int a_drw_x,
+ int a_drw_y,
+ int a_drw_w,
+ int a_drw_h,
+ int a_src_x,
+ int a_src_y,
+ int a_src_w,
+ int a_src_h,
+ int a_image_width,
+ int a_image_height,
+ unsigned char *a_buf,
+ EphyrHostBox *a_clip_rects,
+ int a_clip_rect_nums )
+{
+ Bool is_ok=TRUE ;
+ XvImage *xv_image=NULL ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy = hostx_get_display () ;
+ XRectangle *rects=NULL ;
+ int res = 0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
+
+ EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
+
+ memset (&gc_values, 0, sizeof (gc_values)) ;
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
+ a_port_id, a_image_id,
+ NULL, a_image_width, a_image_height) ;
+ if (!xv_image) {
+ EPHYR_LOG_ERROR ("failed to create image\n") ;
+ goto out ;
+ }
+ xv_image->data = (char*)a_buf ;
+ if (a_clip_rect_nums) {
+ int i=0 ;
+ rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
+ for (i=0; i < a_clip_rect_nums; i++) {
+ rects[i].x = a_clip_rects[i].x1 ;
+ rects[i].y = a_clip_rects[i].y1 ;
+ rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
+ rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
+ EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
+ /*this always returns 1*/
+ }
+ res = XvPutImage (dpy, a_port_id,
+ hostx_get_window (a_screen_num),
+ gc, xv_image,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (xv_image) {
+ XFree (xv_image) ;
+ xv_image = NULL ;
+ }
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVPutStill (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVGetStill (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
+{
+ int ret=0 ;
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
+ if (ret != Success) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.h b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.h
new file mode 100644
index 000000000..05ee38a03
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.h
@@ -0,0 +1,238 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef __EPHYRHOSTVIDEO_H__
+#define __EPHYRHOSTVIDEO_H__
+
+typedef void* EphyrHostXVAdaptor ;
+typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray ;
+
+typedef struct _EphyrHostVideoFormat {
+ char depth ;
+ short visual_class;
+} EphyrHostVideoFormat ;
+
+typedef struct _EphyrHostRational {
+ int numerator ;
+ int denominator ;
+} EphyrHostRational;
+
+typedef struct _EphyrHostEncoding {
+ int id ;
+ char *name ;
+ unsigned short width, height ;
+ EphyrHostRational rate ;
+} EphyrHostEncoding ;
+
+typedef struct _EphyrHostAttribute {
+ int flags;
+ int min_value;
+ int max_value;
+ char *name;
+} EphyrHostAttribute ;
+
+typedef struct _EphyrHostImageFormat {
+ int id; /* Unique descriptor for the format */
+ int type; /* XvRGB, XvYUV */
+ int byte_order; /* LSBFirst, MSBFirst */
+ char guid[16]; /* Globally Unique IDentifier */
+ int bits_per_pixel;
+ int format; /* XvPacked, XvPlanar */
+ int num_planes;
+
+ /* for RGB formats only */
+ int depth;
+ unsigned int red_mask;
+ unsigned int green_mask;
+ unsigned int blue_mask;
+
+ /* for YUV formats only */
+ unsigned int y_sample_bits;
+ unsigned int u_sample_bits;
+ unsigned int v_sample_bits;
+ unsigned int horz_y_period;
+ unsigned int horz_u_period;
+ unsigned int horz_v_period;
+ unsigned int vert_y_period;
+ unsigned int vert_u_period;
+ unsigned int vert_v_period;
+ char component_order[32]; /* eg. UYVY */
+ int scanline_order; /* XvTopToBottom, XvBottomToTop */
+} EphyrHostImageFormat ;
+
+typedef struct {
+ unsigned short x1, y1, x2, y2 ;
+} EphyrHostBox ;
+
+void ephyrHostXVInit (void) ;
+
+void ephyrHostFree (void *a_pointer) ;
+
+/*
+ * host adaptor array
+ */
+Bool ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
+void ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
+int ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
+EphyrHostXVAdaptor* ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+ int a_index) ;
+
+/*
+ * host adaptor
+ */
+
+char ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
+const char* ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
+EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats
+ (const EphyrHostXVAdaptor *a_this,
+ int *a_nb_formats) ;
+int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
+int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
+
+Bool ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+Bool ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result) ;
+
+/*
+ * encoding
+ */
+Bool ephyrHostXVQueryEncodings (int a_port_id,
+ EphyrHostEncoding **a_encodings,
+ unsigned int *a_num_encodings) ;
+
+void ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+ int a_num_encodings) ;
+
+/*
+ * attribute
+ */
+Bool ephyrHostXVQueryPortAttributes (int a_port_id,
+ EphyrHostAttribute **a_attributes,
+ int *a_num_attributes) ;
+
+void ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
+/*
+ * image format
+ */
+
+Bool ephyrHostXVQueryImageFormats (int a_port_id,
+ EphyrHostImageFormat **a_formats,
+ int *a_num_format) ;
+/*
+ * Port Attribute Get/Set
+ */
+Bool ephyrHostXVSetPortAttribute (int a_port_id,
+ int a_atom,
+ int a_attr_value) ;
+Bool ephyrHostXVGetPortAttribute (int a_port_id,
+ int a_atom,
+ int *a_attr_value) ;
+/*
+ *size query
+ */
+Bool ephyrHostXVQueryBestSize (int a_port_id,
+ Bool a_motion,
+ unsigned int a_frame_w,
+ unsigned int a_frame_h,
+ unsigned int a_drw_w,
+ unsigned int a_drw_h,
+ unsigned int *a_actual_w,
+ unsigned int *a_actual_h) ;
+
+Bool ephyrHostXVQueryImageAttributes (int a_port_id,
+ int a_image_id /*image fourcc code*/,
+ unsigned short *a_width,
+ unsigned short *a_height,
+ int *a_image_size,
+ int *a_pitches,
+ int *a_offsets) ;
+/*
+ * atom
+ */
+Bool ephyrHostGetAtom (const char* a_name,
+ Bool a_create_if_not_exists,
+ int *a_atom) ;
+char* ephyrHostGetAtomName (int a_atom) ;
+
+/*
+ *PutImage
+ * (ignore clipping for now)
+ */
+Bool ephyrHostXVPutImage (int a_screen_num,
+ int a_port_id,
+ int a_image_id,
+ int a_drw_x,
+ int a_drw_y,
+ int a_drw_w,
+ int a_drw_h,
+ int a_src_x,
+ int a_src_y,
+ int a_src_w,
+ int a_src_h,
+ int a_image_width,
+ int a_image_height,
+ unsigned char *a_buf,
+ EphyrHostBox *a_clip_rects,
+ int a_clip_rect_nums) ;
+
+/*
+ * Putvideo/PutStill/GetVideo
+ */
+Bool ephyrHostXVPutVideo (int a_screen_num,
+ int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+Bool ephyrHostXVGetVideo (int a_screen_num,
+ int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+Bool ephyrHostXVPutStill (int a_screen_num,
+ int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+Bool ephyrHostXVGetStill (int a_screen_num,
+ int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
+
+/*
+ * StopVideo
+ */
+Bool ephyrHostXVStopVideo (int a_screen_num, int a_port_id) ;
+
+#endif /*__EPHYRHOSTVIDEO_H__*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c
new file mode 100644
index 000000000..47ddb3d82
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c
@@ -0,0 +1,345 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+#include "ephyrlog.h"
+
+extern Window EphyrPreExistingHostWin;
+extern Bool EphyrWantGrayScale;
+extern Bool kdHasPointer;
+extern Bool kdHasKbd;
+
+#ifdef GLXEXT
+extern Bool ephyrNoDRI;
+extern Bool noGlxVisualInit;
+#endif
+extern Bool ephyrNoXV;
+
+void processScreenArg (char *screen_size, char *parent_id) ;
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ EPHYR_DBG("mark");
+
+
+ KdCardInfoAdd (&ephyrFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+
+ KdAddKeyboardDriver(&EphyrKeyboardDriver);
+#ifdef linux
+ KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
+#endif
+ KdAddPointerDriver(&EphyrMouseDriver);
+#ifdef linux
+ KdAddPointerDriver(&LinuxEvdevMouseDriver);
+#endif
+
+ if (!kdHasKbd) {
+ ki = KdNewKeyboard();
+ if (!ki)
+ FatalError("Couldn't create Xephyr keyboard\n");
+ ki->driver = &EphyrKeyboardDriver;
+ KdAddKeyboard(ki);
+ }
+
+ if (!kdHasPointer) {
+ pi = KdNewPointer();
+ if (!pi)
+ FatalError("Couldn't create Xephyr pointer\n");
+ pi->driver = &EphyrMouseDriver;
+ KdAddPointer(pi);
+ }
+
+ KdInitInput();
+}
+
+void
+ddxUseMsg (void)
+{
+ KdUseMsg();
+
+ ErrorF("\nXephyr Option Usage:\n");
+ ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
+ ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
+ ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
+ ErrorF("-grayscale Simulate 8bit grayscale\n");
+ ErrorF("-fakexa Simulate acceleration using software rendering\n");
+ ErrorF("-verbosity <level> Set log verbosity level\n");
+#ifdef GLXEXT
+ ErrorF("-nodri do not use DRI\n");
+#endif
+ ErrorF("-noxv do not use XV\n");
+ ErrorF("-name [name] define the name in the WM_CLASS property\n");
+ ErrorF("\n");
+
+ exit(1);
+}
+
+void
+processScreenArg (char *screen_size, char *parent_id)
+{
+ KdCardInfo *card;
+
+ InitCard (0); /*Put each screen on a separate card*/
+ card = KdCardInfoLast ();
+
+ if (card)
+ {
+ KdScreenInfo *screen;
+ unsigned long p_id = 0;
+
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, screen_size);
+
+ if (parent_id)
+ {
+ p_id = strtol (parent_id, NULL, 0);
+ }
+ EPHYR_DBG ("screen number:%d\n", screen->mynum) ;
+ hostx_add_screen (screen, p_id, screen->mynum);
+ }
+ else
+ {
+ ErrorF("No matching card found!\n");
+ }
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
+
+ if (i == 1)
+ {
+ hostx_use_resname(basename(argv[0]), 0);
+ }
+
+ if (!strcmp (argv[i], "-parent"))
+ {
+ if(i+1 < argc)
+ {
+ processScreenArg ("100x100", argv[i+1]);
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ processScreenArg (argv[i+1], NULL);
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-host-cursor"))
+ {
+ hostx_use_host_cursor();
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-fullscreen"))
+ {
+ hostx_use_fullscreen();
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-grayscale"))
+ {
+ EphyrWantGrayScale = 1;
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-fakexa"))
+ {
+ ephyrFuncs.initAccel = ephyrDrawInit;
+ ephyrFuncs.enableAccel = ephyrDrawEnable;
+ ephyrFuncs.disableAccel = ephyrDrawDisable;
+ ephyrFuncs.finiAccel = ephyrDrawFini;
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-verbosity"))
+ {
+ if(i+1 < argc && argv[i+1][0] != '-')
+ {
+ int verbosity=atoi (argv[i+1]) ;
+ LogSetParameter (XLOG_VERBOSITY, verbosity) ;
+ EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
+ return 2 ;
+ }
+ else
+ {
+ UseMsg() ;
+ exit(1) ;
+ }
+ }
+#ifdef GLXEXT
+ else if (!strcmp (argv[i], "-nodri"))
+ {
+ noGlxVisualInit = FALSE ;
+ ephyrNoDRI = TRUE ;
+ EPHYR_LOG ("no direct rendering enabled\n") ;
+ return 1 ;
+ }
+#endif
+ else if (!strcmp (argv[i], "-noxv"))
+ {
+ ephyrNoXV = TRUE ;
+ EPHYR_LOG ("no XVideo enabled\n") ;
+ return 1 ;
+ }
+ else if (!strcmp (argv[i], "-name"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ {
+ hostx_use_resname(argv[i+1], 1);
+ return 2;
+ }
+ else
+ {
+ UseMsg();
+ return 0;
+ }
+ }
+ else if (argv[i][0] == ':')
+ {
+ hostx_set_display_name(argv[i]);
+ }
+
+ return KdProcessArgument (argc, argv, i);
+}
+
+void
+OsVendorInit (void)
+{
+ EPHYR_DBG("mark");
+
+ if (hostx_want_host_cursor())
+ {
+ ephyrFuncs.initCursor = &ephyrCursorInit;
+ ephyrFuncs.enableCursor = &ephyrCursorEnable;
+ }
+
+ KdOsInit (&EphyrOsFuncs);
+}
+
+/* 'Fake' cursor stuff, could be improved */
+
+static Bool
+ephyrRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static Bool
+ephyrUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+ephyrSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ ;
+}
+
+static void
+ephyrMoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ ;
+}
+
+miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
+ ephyrRealizeCursor,
+ ephyrUnrealizeCursor,
+ ephyrSetCursor,
+ ephyrMoveCursor,
+};
+
+
+Bool
+ephyrCursorInit(ScreenPtr pScreen)
+{
+ miPointerInitialize(pScreen,
+ &EphyrPointerSpriteFuncs,
+ &ephyrPointerScreenFuncs,
+ FALSE);
+
+ return TRUE;
+}
+
+void
+ephyrCursorEnable(ScreenPtr pScreen)
+{
+ ;
+}
+
+KdCardFuncs ephyrFuncs = {
+ ephyrCardInit, /* cardinit */
+ ephyrScreenInit, /* scrinit */
+ ephyrInitScreen, /* initScreen */
+ ephyrFinishInitScreen, /* finishInitScreen */
+ ephyrCreateResources, /* createRes */
+ ephyrPreserve, /* preserve */
+ ephyrEnable, /* enable */
+ ephyrDPMS, /* dpms */
+ ephyrDisable, /* disable */
+ ephyrRestore, /* restore */
+ ephyrScreenFini, /* scrfini */
+ ephyrCardFini, /* cardfini */
+
+ 0, /* initCursor */
+ 0, /* enableCursor */
+ 0, /* disableCursor */
+ 0, /* finiCursor */
+ 0, /* recolorCursor */
+
+ 0, /* initAccel */
+ 0, /* enableAccel */
+ 0, /* disableAccel */
+ 0, /* finiAccel */
+
+ ephyrGetColors, /* getColors */
+ ephyrPutColors, /* putColors */
+};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrlog.h b/xorg-server/hw/kdrive/ephyr/ephyrlog.h
new file mode 100644
index 000000000..71f797777
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrlog.h
@@ -0,0 +1,67 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifndef __EPHYRLOG_H__
+#define __EPHYRLOG_H__
+
+#include <assert.h>
+#include "os.h"
+
+#ifdef NDEBUG
+/*we are not in debug mode*/
+#define EPHYR_LOG(...)
+#define EPHYR_LOG_ERROR(...)
+#endif /*NDEBUG*/
+
+#define ERROR_LOG_LEVEL 3
+#define INFO_LOG_LEVEL 4
+
+#ifndef EPHYR_LOG
+#define EPHYR_LOG(...) \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\
+ __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__)
+#endif /*nomadik_log*/
+
+#ifndef EPHYR_LOG_ERROR
+#define EPHYR_LOG_ERROR(...) \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\
+ __FILE__, __LINE__, __func__) ; \
+LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__)
+#endif /*EPHYR_LOG_ERROR*/
+
+#ifndef EPHYR_RETURN_IF_FAIL
+#define EPHYR_RETURN_IF_FAIL(cond) \
+if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return;}
+#endif /*nomadik_return_if_fail*/
+
+#ifndef EPHYR_RETURN_VAL_IF_FAIL
+#define EPHYR_RETURN_VAL_IF_FAIL(cond,val) \
+if (!(cond)) {EPHYR_LOG_ERROR("condition %s failed\n", #cond);return val;}
+#endif /*nomadik_return_val_if_fail*/
+
+#endif /*__EPHYRLOG_H__*/
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
new file mode 100644
index 000000000..bfe4d7223
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
@@ -0,0 +1,1278 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <string.h>
+#include <X11/extensions/Xv.h>
+#include "ephyrlog.h"
+#include "kdrive.h"
+#include "kxv.h"
+#include "ephyr.h"
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+
+struct _EphyrXVPriv {
+ EphyrHostXVAdaptorArray *host_adaptors ;
+ KdVideoAdaptorPtr adaptors ;
+ int num_adaptors ;
+};
+typedef struct _EphyrXVPriv EphyrXVPriv ;
+
+struct _EphyrPortPriv {
+ int port_number ;
+ KdVideoAdaptorPtr current_adaptor ;
+ EphyrXVPriv *xv_priv;
+ unsigned char *image_buf ;
+ int image_buf_size ;
+ int image_id ;
+ int drw_x, drw_y, drw_w, drw_h ;
+ int src_x, src_y, src_w, src_h ;
+ int image_width, image_height ;
+};
+typedef struct _EphyrPortPriv EphyrPortPriv ;
+
+static Bool DoSimpleClip (BoxPtr a_dst_drw,
+ BoxPtr a_clipper,
+ BoxPtr a_result) ;
+
+static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
+
+/*
+static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+*/
+
+static EphyrXVPriv* ephyrXVPrivNew (void) ;
+static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen) ;
+
+static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid) ;
+
+static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size) ;
+
+static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image,
+ int a_image_len) ;
+
+static void ephyrStopVideo (KdScreenInfo *a_info,
+ pointer a_xv_priv,
+ Bool a_exit);
+
+static int ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv);
+
+static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv);
+
+static void ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv);
+
+static int ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv);
+
+static int ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets);
+static int s_base_port_id ;
+
+/**************
+ * <helpers>
+ * ************/
+
+static Bool
+DoSimpleClip (BoxPtr a_dst_box,
+ BoxPtr a_clipper,
+ BoxPtr a_result)
+{
+ BoxRec dstClippedBox ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
+
+ /*
+ * setup the clipbox inside the destination.
+ */
+ dstClippedBox.x1 = a_dst_box->x1 ;
+ dstClippedBox.x2 = a_dst_box->x2 ;
+ dstClippedBox.y1 = a_dst_box->y1 ;
+ dstClippedBox.y2 = a_dst_box->y2 ;
+
+ /*
+ * if the cliper leftmost edge is inside
+ * the destination area then the leftmost edge of the resulting
+ * clipped box is the leftmost edge of the cliper.
+ */
+ if (a_clipper->x1 > dstClippedBox.x1)
+ dstClippedBox.x1 = a_clipper->x1 ;
+
+ /*
+ * if the cliper top edge is inside the destination area
+ * then the bottom horizontal edge of the resulting clipped box
+ * is the bottom edge of the cliper
+ */
+ if (a_clipper->y1 > dstClippedBox.y1)
+ dstClippedBox.y1 = a_clipper->y1 ;
+
+ /*ditto for right edge*/
+ if (a_clipper->x2 < dstClippedBox.x2)
+ dstClippedBox.x2 = a_clipper->x2 ;
+
+ /*ditto for bottom edge*/
+ if (a_clipper->y2 < dstClippedBox.y2)
+ dstClippedBox.y2 = a_clipper->y2 ;
+
+ memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
+ return TRUE ;
+}
+
+static Bool
+ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
+{
+ char *atom_name=NULL;
+ int host_atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
+
+ if (!ValidAtom (a_local_atom))
+ return FALSE ;
+
+ atom_name = NameForAtom (a_local_atom) ;
+
+ if (!atom_name)
+ return FALSE ;
+
+ if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
+ EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
+ atom_name) ;
+ return FALSE ;
+ }
+ *a_host_atom = host_atom ;
+ return TRUE ;
+}
+
+/*
+ Not used yed.
+static Bool
+ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
+{
+ Bool is_ok=FALSE ;
+ char *atom_name=NULL ;
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
+
+ atom_name = ephyrHostGetAtomName (a_host_atom) ;
+ if (!atom_name)
+ goto out ;
+
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
+ if (atom == None)
+ goto out ;
+
+ *a_local_atom = atom ;
+ is_ok = TRUE ;
+
+out:
+ if (atom_name) {
+ ephyrHostFree (atom_name) ;
+ }
+ return is_ok ;
+}
+*/
+
+/**************
+ *</helpers>
+ * ************/
+
+Bool
+ephyrInitVideo (ScreenPtr pScreen)
+{
+ Bool is_ok = FALSE ;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ static EphyrXVPriv *xv_priv;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (screen->fb[0].bitsPerPixel == 8) {
+ EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
+ return FALSE ;
+ }
+
+ if (!xv_priv) {
+ xv_priv = ephyrXVPrivNew () ;
+ }
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+}
+
+static EphyrXVPriv*
+ephyrXVPrivNew (void)
+{
+ EphyrXVPriv *xv_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ xv_priv = xcalloc (1, sizeof (EphyrXVPriv)) ;
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
+ goto error ;
+ }
+
+ ephyrHostXVInit () ;
+
+ if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
+ goto error ;
+ }
+ if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
+ goto error ;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return xv_priv ;
+
+error:
+ if (xv_priv) {
+ ephyrXVPrivDelete (xv_priv) ;
+ xv_priv = NULL ;
+ }
+ return NULL ;
+}
+
+static void
+ephyrXVPrivDelete (EphyrXVPriv *a_this)
+{
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this)
+ return ;
+ if (a_this->host_adaptors) {
+ ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
+ a_this->host_adaptors = NULL ;
+ }
+ if (a_this->adaptors) {
+ xfree (a_this->adaptors) ;
+ a_this->adaptors = NULL ;
+ }
+ xfree (a_this) ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static KdVideoEncodingPtr
+videoEncodingDup (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ KdVideoEncodingPtr result = NULL ;
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = xcalloc (a_num_encodings, sizeof (KdVideoEncodingRec)) ;
+ for (i=0 ; i < a_num_encodings; i++) {
+ result[i].id = a_encodings[i].id ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ result[i].width = a_encodings[i].width ;
+ result[i].height = a_encodings[i].height ;
+ result[i].rate.numerator = a_encodings[i].rate.numerator ;
+ result[i].rate.denominator = a_encodings[i].rate.denominator ;
+ }
+ return result ;
+}
+
+static KdAttributePtr
+portAttributesDup (EphyrHostAttribute *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+ KdAttributePtr result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = xcalloc (a_num_encodings, sizeof (KdAttributeRec)) ;
+ if (!result) {
+ EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
+ return NULL ;
+ }
+ for (i=0; i < a_num_encodings; i++) {
+ result[i].flags = a_encodings[i].flags ;
+ result[i].min_value = a_encodings[i].min_value ;
+ result[i].max_value = a_encodings[i].max_value ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ }
+ return result ;
+}
+
+static Bool
+ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
+{
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+ EphyrHostVideoFormat *video_formats=NULL ;
+ EphyrHostEncoding *encodings=NULL ;
+ EphyrHostAttribute *attributes=NULL ;
+ EphyrHostImageFormat *image_formats=NULL ;
+ int num_video_formats=0, base_port_id=0,
+ num_attributes=0, num_formats=0, i=0,
+ port_priv_offset=0;
+ unsigned num_encodings=0 ;
+ Bool is_ok = FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
+ goto out ;
+ }
+ if (a_this->host_adaptors)
+ a_this->num_adaptors =
+ ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+ if (a_this->num_adaptors < 0) {
+ EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
+ /*
+ * copy what we can from adaptors into a_this->adaptors
+ */
+ if (a_this->num_adaptors) {
+ a_this->adaptors = xcalloc (a_this->num_adaptors,
+ sizeof (KdVideoAdaptorRec)) ;
+ if (!a_this->adaptors) {
+ EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
+ goto out ;
+ }
+ }
+ for (i=0; i < a_this->num_adaptors; i++) {
+ int j=0 ;
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor)
+ continue ;
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ if (a_this->adaptors[i].nPorts <=0) {
+ EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].type =
+ ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
+ a_this->adaptors[i].type |= XvWindowMask ;
+ a_this->adaptors[i].flags =
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
+ a_this->adaptors[i].name =
+ strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+ else
+ a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
+ base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
+ if (base_port_id < 0) {
+ EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
+ continue ;
+ }
+ if (!s_base_port_id)
+ s_base_port_id = base_port_id ;
+
+ if (!ephyrHostXVQueryEncodings (base_port_id,
+ &encodings,
+ &num_encodings)) {
+ EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
+ " adaptors %d\n",
+ base_port_id, i) ;
+ continue ;
+ }
+ a_this->adaptors[i].nEncodings = num_encodings ;
+ a_this->adaptors[i].pEncodings =
+ videoEncodingDup (encodings, num_encodings) ;
+ video_formats = (EphyrHostVideoFormat*)
+ ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
+ &num_video_formats);
+ a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
+ a_this->adaptors[i].nFormats = num_video_formats ;
+ /* got a_this->adaptors[i].nPorts already
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ */
+ a_this->adaptors[i].pPortPrivates =
+ xcalloc (a_this->adaptors[i].nPorts,
+ sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
+ port_priv_offset = a_this->adaptors[i].nPorts;
+ for (j=0; j < a_this->adaptors[i].nPorts; j++) {
+ EphyrPortPriv *port_privs_base =
+ (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
+ EphyrPortPriv *port_priv = &port_privs_base[j] ;
+ port_priv->port_number = base_port_id + j;
+ port_priv->current_adaptor = &a_this->adaptors[i] ;
+ port_priv->xv_priv = a_this ;
+ a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
+ }
+ if (!ephyrHostXVQueryPortAttributes (base_port_id,
+ &attributes,
+ &num_attributes)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pAttributes =
+ portAttributesDup (attributes, num_attributes);
+ a_this->adaptors[i].nAttributes = num_attributes ;
+ /*make sure atoms of attrs names are created in xephyr*/
+ for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
+ if (a_this->adaptors[i].pAttributes[j].name)
+ MakeAtom (a_this->adaptors[i].pAttributes[j].name,
+ strlen (a_this->adaptors[i].pAttributes[j].name),
+ TRUE) ;
+ }
+ if (!ephyrHostXVQueryImageFormats (base_port_id,
+ &image_formats,
+ &num_formats)) {
+ EPHYR_LOG_ERROR ("failed to get image formats "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
+ a_this->adaptors[i].nImages = num_formats ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (encodings) {
+ ephyrHostEncodingsDelete (encodings, num_encodings) ;
+ encodings = NULL ;
+ }
+ if (attributes) {
+ ephyrHostAttributesDelete (attributes) ;
+ attributes = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
+{
+ int i=0 ;
+ Bool has_it=FALSE ;
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ for (i=0; i < a_this->num_adaptors; i++) {
+ a_this->adaptors[i].ReputImage = ephyrReputImage ;
+ a_this->adaptors[i].StopVideo = ephyrStopVideo ;
+ a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
+ a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
+ a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
+ a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
+
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor) {
+ EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
+ continue ;
+ }
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutImage = ephyrPutImage;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutVideo = ephyrPutVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetVideo = ephyrGetVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutStill = ephyrPutStill;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetStill = ephyrGetStill;
+ }
+ }
+ EPHYR_LOG ("leave\n") ;
+ return TRUE ;
+}
+
+static Bool
+ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen)
+{
+ KdScreenPriv(a_screen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ Bool is_ok = FALSE ;
+ KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
+ int num_registered_adaptors=0, i=0, num_adaptors=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this->num_adaptors)
+ goto out ;
+ num_registered_adaptors =
+ KdXVListGenericAdaptors (screen, &registered_adaptors);
+
+ num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
+ adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
+ if (!adaptors) {
+ EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
+ goto out ;
+ }
+ memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
+ for (i=0 ; i < a_this->num_adaptors; i++) {
+ *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
+ }
+ if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n");
+ goto out ;
+ }
+ EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
+ is_ok = TRUE ;
+
+out:
+ if (registered_adaptors) {
+ xfree (registered_adaptors) ;
+ registered_adaptors = NULL ;
+ }
+ if (adaptors) {
+ xfree (adaptors) ;
+ adaptors=NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
+ FALSE) ;
+
+ for (i=0; i < a_attrs_len; i++) {
+ if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
+ continue ;
+ if (a_attrs[i].min_value > a_attr_value ||
+ a_attrs[i].max_value < a_attr_value) {
+ *a_is_valid = FALSE ;
+ EPHYR_LOG_ERROR ("attribute was not valid\n"
+ "value:%d. min:%d. max:%d\n",
+ a_attr_value,
+ a_attrs[i].min_value,
+ a_attrs[i].max_value) ;
+ } else {
+ *a_is_valid = TRUE ;
+ }
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+static Bool
+ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size)
+{
+ Bool is_ok=FALSE ;
+ unsigned short width=a_width, height=a_height ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
+ &width, &height, a_size, NULL, NULL)) {
+ EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image_buf,
+ int a_image_len)
+{
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_port_priv->image_buf_size < a_image_len) {
+ unsigned char *buf=NULL ;
+ buf = realloc (a_port_priv->image_buf, a_image_len) ;
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
+ goto out ;
+ }
+ a_port_priv->image_buf = buf ;
+ a_port_priv->image_buf_size = a_image_len;
+ }
+ memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static void
+ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
+ port_priv->port_number)) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_attr_valid=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name),
+ a_attr_value) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
+ port_priv->current_adaptor->nAttributes,
+ NameForAtom (a_attr_name),
+ a_attr_value,
+ &is_attr_valid)) {
+ EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+ if (!is_attr_valid) {
+ EPHYR_LOG_ERROR ("attribute %s is not valid\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+
+ if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static int
+ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name)) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static void
+ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv)
+{
+ int res=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ res = ephyrHostXVQueryBestSize (port_priv->port_number,
+ a_motion,
+ a_src_w, a_src_h,
+ a_drw_w, a_drw_h,
+ a_prefered_w, a_prefered_h) ;
+ if (!res) {
+ EPHYR_LOG_ERROR ("Failed to query best size\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_ok=FALSE ;
+ int result=BadImplementation, image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_id,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_width, a_height, a_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ /*
+ * Now save the image so that we can resend it to host it
+ * later, in ReputImage.
+ */
+ if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
+ a_id, a_width, a_height, &image_size)) {
+ EPHYR_LOG_ERROR ("failed to get image size\n") ;
+ /*this is a minor error so we won't get bail out abruptly*/
+ is_ok = FALSE ;
+ } else {
+ is_ok = TRUE ;
+ }
+ if (is_ok) {
+ if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
+ is_ok=FALSE ;
+ } else {
+ port_priv->image_id = a_id;
+ port_priv->drw_x = a_drw_x;
+ port_priv->drw_y = a_drw_y;
+ port_priv->drw_w = a_drw_w ;
+ port_priv->drw_h = a_drw_h ;
+ port_priv->src_x = a_src_x;
+ port_priv->src_y = a_src_y ;
+ port_priv->src_w = a_src_w ;
+ port_priv->src_h = a_src_h ;
+ port_priv->image_width = a_width ;
+ port_priv->image_height = a_height ;
+ }
+ }
+ if (!is_ok) {
+ if (port_priv->image_buf) {
+ free (port_priv->image_buf) ;
+ port_priv->image_buf = NULL ;
+ port_priv->image_buf_size = 0 ;
+ }
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ int result=BadImplementation ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!port_priv->image_buf_size || !port_priv->image_buf) {
+ EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
+ goto out ;
+ }
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ port_priv->image_id,
+ a_drw_x, a_drw_y,
+ port_priv->drw_w, port_priv->drw_h,
+ port_priv->src_x, port_priv->src_y,
+ port_priv->src_w, port_priv->src_h,
+ port_priv->image_width, port_priv->image_height,
+ port_priv->image_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets)
+{
+ int image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
+
+ EPHYR_LOG ("enter: dim (%dx%d), pitches: %#x, offsets: %#x\n",
+ *a_w, *a_h, (unsigned int)a_pitches, (unsigned int)a_offsets) ;
+
+ if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
+ a_id,
+ a_w, a_h,
+ &image_size,
+ a_pitches, a_offsets)) {
+ EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return image_size ;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
new file mode 100644
index 000000000..c870a291d
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -0,0 +1,1434 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+/*
+ * including some server headers (like kdrive-config.h)
+ * might define the macro _XSERVER64
+ * on 64 bits machines. That macro must _NOT_ be defined for Xlib
+ * client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+
+
+#include "hostx.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h> /* for memset */
+#include <time.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#ifdef XEPHYR_DRI
+#include <GL/glx.h>
+#endif /*XEPHYR_DRI*/
+#include "ephyrlog.h"
+
+#ifdef XEPHYR_DRI
+extern Bool XF86DRIQueryExtension (Display *dpy,
+ int *event_basep,
+ int *error_basep);
+#endif
+
+/*
+ * All xlib calls go here, which gets built as its own .a .
+ * Mixing kdrive and xlib headers causes all sorts of types
+ * to get clobbered.
+ */
+
+struct EphyrHostScreen
+{
+ Window win;
+ Window win_pre_existing; /* Set via -parent option like xnest */
+ XImage *ximg;
+ int win_width, win_height;
+ int server_depth;
+ unsigned char *fb_data; /* only used when host bpp != server bpp */
+ XShmSegmentInfo shminfo;
+
+ void *info; /* Pointer to the screen this is associated with */
+ int mynum; /* Screen number */
+};
+
+struct EphyrHostXVars
+{
+ char *server_dpy_name;
+ Display *dpy;
+ int screen;
+ Visual *visual;
+ Window winroot;
+ GC gc;
+ int depth;
+ Bool use_host_cursor;
+ Bool use_fullscreen;
+ Bool have_shm;
+
+ int n_screens;
+ struct EphyrHostScreen *screens;
+
+ long damage_debug_msec;
+
+ unsigned long cmap[256];
+};
+
+/* memset ( missing> ) instead of below */
+/*static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};*/
+static EphyrHostXVars HostX;
+
+static int HostXWantDamageDebug = 0;
+
+extern EphyrKeySyms ephyrKeySyms;
+
+extern int monitorResolution;
+
+char *ephyrResName = NULL;
+int ephyrResNameFromCmd = 0;
+
+static void
+hostx_set_fullscreen_hint(void);
+
+/* X Error traps */
+
+static int trapped_error_code = 0;
+static int (*old_error_handler) (Display *d, XErrorEvent *e);
+
+#define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth)
+
+static struct EphyrHostScreen *
+host_screen_from_screen_info (EphyrScreenInfo *screen)
+{
+ int i;
+
+ for (i = 0 ; i < HostX.n_screens ; i++)
+ {
+ if ( HostX.screens[i].info == screen)
+ {
+ return &HostX.screens[i];
+ }
+ }
+ return NULL;
+}
+
+static int
+error_handler(Display *display,
+ XErrorEvent *error)
+{
+ trapped_error_code = error->error_code;
+ return 0;
+}
+
+static void
+hostx_errors_trap(void)
+{
+ trapped_error_code = 0;
+ old_error_handler = XSetErrorHandler(error_handler);
+}
+
+static int
+hostx_errors_untrap(void)
+{
+ XSetErrorHandler(old_error_handler);
+ return trapped_error_code;
+}
+
+int
+hostx_want_screen_size (EphyrScreenInfo screen, int *width, int *height )
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen &&
+ (host_screen->win_pre_existing != None ||
+ HostX.use_fullscreen == True))
+ {
+ *width = host_screen->win_width;
+ *height = host_screen->win_height;
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+hostx_add_screen (EphyrScreenInfo screen,
+ unsigned long win_id,
+ int screen_num)
+{
+ int index = HostX.n_screens;
+
+ HostX.n_screens += 1;
+ HostX.screens = realloc (HostX.screens,
+ HostX.n_screens * sizeof(struct EphyrHostScreen));
+ memset (&HostX.screens[index], 0, sizeof (struct EphyrHostScreen));
+
+ HostX.screens[index].info = screen;
+ HostX.screens[index].win_pre_existing = win_id;
+}
+
+
+void
+hostx_set_display_name (char *name)
+{
+ HostX.server_dpy_name = strdup (name);
+}
+
+void
+hostx_set_screen_number(EphyrScreenInfo screen, int number)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+ if (host_screen) {
+ host_screen->mynum = number;
+ hostx_set_win_title (host_screen->info, "") ;
+ }}
+
+void
+hostx_set_win_title (EphyrScreenInfo screen, char *extra_text)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+#define BUF_LEN 256
+ char buf[BUF_LEN+1];
+
+ if (!host_screen)
+ return;
+
+ memset (buf, 0, BUF_LEN+1) ;
+ snprintf (buf, BUF_LEN, "Xephyr on %s.%d %s",
+ HostX.server_dpy_name,
+ host_screen->mynum,
+ (extra_text != NULL) ? extra_text : "");
+
+ XStoreName (HostX.dpy, host_screen->win, buf);
+}
+
+int
+hostx_want_host_cursor (void)
+{
+ return HostX.use_host_cursor;
+}
+
+void
+hostx_use_host_cursor (void)
+{
+ HostX.use_host_cursor = True;
+}
+
+int
+hostx_want_preexisting_window (EphyrScreenInfo screen)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen && host_screen->win_pre_existing)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void
+hostx_use_fullscreen (void)
+{
+ HostX.use_fullscreen = True;
+}
+
+int
+hostx_want_fullscreen (void)
+{
+ return HostX.use_fullscreen;
+}
+
+static void
+hostx_set_fullscreen_hint (void)
+{
+ Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
+ int index;
+
+ atom_WINDOW_STATE
+ = XInternAtom(HostX.dpy, "_NET_WM_STATE", False);
+ atom_WINDOW_STATE_FULLSCREEN
+ = XInternAtom(HostX.dpy, "_NET_WM_STATE_FULLSCREEN",False);
+
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ XChangeProperty (HostX.dpy, HostX.screens[index].win,
+ atom_WINDOW_STATE, XA_ATOM, 32,
+ PropModeReplace,
+ (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+ }
+}
+
+
+static void
+hostx_toggle_damage_debug (void)
+{
+ HostXWantDamageDebug ^= 1;
+}
+
+void
+hostx_handle_signal (int signum)
+{
+ hostx_toggle_damage_debug();
+ EPHYR_DBG ("Signal caught. Damage Debug:%i\n",
+ HostXWantDamageDebug);
+}
+
+void
+hostx_use_resname (char *name, int fromcmd)
+{
+ ephyrResName = name;
+ ephyrResNameFromCmd = fromcmd;
+}
+
+int
+hostx_init (void)
+{
+ XSetWindowAttributes attr;
+ Cursor empty_cursor;
+ Pixmap cursor_pxm;
+ XColor col;
+ int index;
+ char *tmpstr;
+ XClassHint *class_hint;
+
+ attr.event_mask =
+ ButtonPressMask
+ |ButtonReleaseMask
+ |PointerMotionMask
+ |KeyPressMask
+ |KeyReleaseMask
+ |ExposureMask;
+
+ EPHYR_DBG("mark");
+
+ if ((HostX.dpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+ {
+ fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
+ exit(1);
+ }
+
+ HostX.screen = DefaultScreen(HostX.dpy);
+ HostX.winroot = RootWindow(HostX.dpy, HostX.screen);
+ HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
+ HostX.depth = DefaultDepth(HostX.dpy, HostX.screen);
+ HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
+
+ class_hint = XAllocClassHint();
+
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ struct EphyrHostScreen *host_screen = &HostX.screens[index];
+
+ host_screen->server_depth = HostX.depth;
+ if (host_screen->win_pre_existing != None)
+ {
+ Status result;
+ XWindowAttributes prewin_attr;
+
+ /* Get screen size from existing window */
+
+ hostx_errors_trap();
+
+ result = XGetWindowAttributes (HostX.dpy,
+ host_screen->win_pre_existing,
+ &prewin_attr);
+
+
+ if (hostx_errors_untrap() || !result)
+ {
+ fprintf (stderr, "\nXephyr -parent window' does not exist!\n");
+ exit (1);
+ }
+
+ host_screen->win_width = prewin_attr.width;
+ host_screen->win_height = prewin_attr.height;
+
+ host_screen->win = XCreateWindow (HostX.dpy,
+ host_screen->win_pre_existing,
+ 0,0,
+ host_screen->win_width,
+ host_screen->win_height,
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWEventMask,
+ &attr);
+ }
+ else
+ {
+ host_screen->win = XCreateWindow (HostX.dpy,
+ HostX.winroot,
+ 0,0,100,100, /* will resize */
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWEventMask,
+ &attr);
+
+ hostx_set_win_title (host_screen->info,
+ "(ctrl+shift grabs mouse and keyboard)");
+
+ if (HostX.use_fullscreen)
+ {
+ host_screen->win_width = DisplayWidth(HostX.dpy, HostX.screen);
+ host_screen->win_height = DisplayHeight(HostX.dpy, HostX.screen);
+
+ hostx_set_fullscreen_hint();
+ }
+
+ if (class_hint)
+ {
+ tmpstr = getenv("RESOURCE_NAME");
+ if (tmpstr && (!ephyrResNameFromCmd))
+ ephyrResName = tmpstr;
+ class_hint->res_name = ephyrResName;
+ class_hint->res_class = "Xephyr";
+ XSetClassHint(hostx_get_display(), host_screen->win, class_hint);
+
+ }
+
+ }
+ }
+
+ if (class_hint)
+ XFree(class_hint);
+
+ XParseColor (HostX.dpy, DefaultColormap (HostX.dpy,HostX.screen),
+ "red", &col);
+ XAllocColor (HostX.dpy, DefaultColormap (HostX.dpy, HostX.screen),
+ &col);
+ XSetForeground (HostX.dpy, HostX.gc, col.pixel);
+
+ if (!hostx_want_host_cursor ())
+ {
+ /* Ditch the cursor, we provide our 'own' */
+ cursor_pxm = XCreatePixmap (HostX.dpy, HostX.winroot, 1, 1, 1);
+ memset (&col, 0, sizeof (col));
+ empty_cursor = XCreatePixmapCursor (HostX.dpy,
+ cursor_pxm, cursor_pxm,
+ &col, &col, 1, 1);
+ for ( index = 0 ; index < HostX.n_screens ; index++ )
+ {
+ XDefineCursor (HostX.dpy,
+ HostX.screens[index].win,
+ empty_cursor);
+ }
+ XFreePixmap (HostX.dpy, cursor_pxm);
+ }
+
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ HostX.screens[index].ximg = NULL;
+ }
+ /* Try to get share memory ximages for a little bit more speed */
+
+ if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM"))
+ {
+ fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
+ HostX.have_shm = False;
+ }
+ else
+ {
+ /* Really really check we have shm - better way ?*/
+ XShmSegmentInfo shminfo;
+
+ HostX.have_shm = True;
+
+ shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
+ shminfo.shmaddr=shmat(shminfo.shmid,0,0);
+ shminfo.readOnly=True;
+
+ hostx_errors_trap();
+
+ XShmAttach(HostX.dpy, &shminfo);
+ XSync(HostX.dpy, False);
+
+ if (hostx_errors_untrap())
+ {
+ fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
+ HostX.have_shm = False;
+ }
+
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+}
+
+ XFlush(HostX.dpy);
+
+ /* Setup the pause time between paints when debugging updates */
+
+ HostX.damage_debug_msec = 20000; /* 1/50 th of a second */
+
+ if (getenv ("XEPHYR_PAUSE"))
+ {
+ HostX.damage_debug_msec = strtol (getenv ("XEPHYR_PAUSE"), NULL, 0);
+ EPHYR_DBG ("pause is %li\n", HostX.damage_debug_msec);
+ }
+
+ return 1;
+}
+
+int
+hostx_get_depth (void)
+{
+ return HostX.depth;
+}
+
+int
+hostx_get_server_depth (EphyrScreenInfo screen)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ return (host_screen ? host_screen->server_depth : 0);
+}
+
+void
+hostx_set_server_depth (EphyrScreenInfo screen, int depth)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen)
+ host_screen->server_depth = depth;
+}
+
+int
+hostx_get_bpp (EphyrScreenInfo screen)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (!host_screen)
+ return 0;
+
+ if (host_depth_matches_server (host_screen))
+ return HostX.visual->bits_per_rgb;
+ else
+ return host_screen->server_depth; /*XXX correct ?*/
+}
+
+void
+hostx_get_visual_masks (EphyrScreenInfo screen,
+ CARD32 *rmsk,
+ CARD32 *gmsk,
+ CARD32 *bmsk)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (!host_screen)
+ return;
+
+ if (host_depth_matches_server(host_screen))
+ {
+ *rmsk = HostX.visual->red_mask;
+ *gmsk = HostX.visual->green_mask;
+ *bmsk = HostX.visual->blue_mask;
+ }
+ else if (host_screen->server_depth == 16)
+ {
+ /* Assume 16bpp 565 */
+ *rmsk = 0xf800;
+ *gmsk = 0x07e0;
+ *bmsk = 0x001f;
+ }
+ else
+ {
+ *rmsk = 0x0;
+ *gmsk = 0x0;
+ *bmsk = 0x0;
+ }
+}
+
+void
+hostx_set_cmap_entry(unsigned char idx,
+ unsigned char r,
+ unsigned char g,
+ unsigned char b)
+{
+ /* XXX Will likely break for 8 on 16, not sure if this is correct */
+ HostX.cmap[idx] = (r << 16) | (g << 8) | (b);
+}
+
+/**
+ * hostx_screen_init creates the XImage that will contain the front buffer of
+ * the ephyr screen, and possibly offscreen memory.
+ *
+ * @param width width of the screen
+ * @param height height of the screen
+ * @param buffer_height height of the rectangle to be allocated.
+ *
+ * hostx_screen_init() creates an XImage, using MIT-SHM if it's available.
+ * buffer_height can be used to create a larger offscreen buffer, which is used
+ * by fakexa for storing offscreen pixmap data.
+ */
+void*
+hostx_screen_init (EphyrScreenInfo screen,
+ int width, int height,
+ int buffer_height)
+{
+ int bitmap_pad;
+ Bool shm_success = False;
+ XSizeHints *size_hints;
+
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+ if (!host_screen)
+ {
+ fprintf (stderr, "%s: Error in accessing hostx data\n", __func__ );
+ exit(1);
+ }
+
+ EPHYR_DBG ("host_screen=%p wxh=%dx%d, buffer_height=%d",
+ host_screen, width, height, buffer_height);
+
+ if (host_screen->ximg != NULL)
+ {
+ /* Free up the image data if previously used
+ * i.ie called by server reset
+ */
+
+ if (HostX.have_shm)
+ {
+ XShmDetach(HostX.dpy, &host_screen->shminfo);
+ XDestroyImage (host_screen->ximg);
+ shmdt(host_screen->shminfo.shmaddr);
+ shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
+ }
+ else
+ {
+ if (host_screen->ximg->data)
+ {
+ free(host_screen->ximg->data);
+ host_screen->ximg->data = NULL;
+ }
+
+ XDestroyImage(host_screen->ximg);
+ }
+ }
+
+ if (HostX.have_shm)
+ {
+ host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth,
+ ZPixmap, NULL, &host_screen->shminfo,
+ width, buffer_height );
+
+ host_screen->shminfo.shmid =
+ shmget(IPC_PRIVATE,
+ host_screen->ximg->bytes_per_line * buffer_height,
+ IPC_CREAT|0777);
+ host_screen->ximg->data = shmat(host_screen->shminfo.shmid, 0, 0);
+ host_screen->shminfo.shmaddr = host_screen->ximg->data;
+
+ if (host_screen->ximg->data == (char *)-1)
+ {
+ EPHYR_DBG("Can't attach SHM Segment, falling back to plain XImages");
+ HostX.have_shm = False;
+ XDestroyImage(host_screen->ximg);
+ shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
+ }
+ else
+ {
+ EPHYR_DBG("SHM segment attached %p", host_screen->shminfo.shmaddr);
+ host_screen->shminfo.readOnly = False;
+ XShmAttach(HostX.dpy, &host_screen->shminfo);
+ shm_success = True;
+ }
+ }
+
+ if (!shm_success)
+ {
+ bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 );
+
+ EPHYR_DBG("Creating image %dx%d for screen host_screen=%p\n",
+ width, buffer_height, host_screen );
+ host_screen->ximg = XCreateImage (HostX.dpy,
+ HostX.visual,
+ HostX.depth,
+ ZPixmap, 0, 0,
+ width,
+ buffer_height,
+ bitmap_pad,
+ 0);
+
+ host_screen->ximg->data =
+ malloc (host_screen->ximg->bytes_per_line * buffer_height);
+ }
+
+ XResizeWindow (HostX.dpy, host_screen->win, width, height);
+
+ /* Ask the WM to keep our size static */
+ size_hints = XAllocSizeHints();
+ size_hints->max_width = size_hints->min_width = width;
+ size_hints->max_height = size_hints->min_height = height;
+ size_hints->flags = PMinSize|PMaxSize;
+ XSetWMNormalHints(HostX.dpy, host_screen->win, size_hints);
+ XFree(size_hints);
+
+ XMapWindow(HostX.dpy, host_screen->win);
+
+ XSync(HostX.dpy, False);
+
+ host_screen->win_width = width;
+ host_screen->win_height = height;
+
+ if (host_depth_matches_server(host_screen))
+ {
+ EPHYR_DBG("Host matches server");
+ return host_screen->ximg->data;
+ }
+ else
+ {
+ EPHYR_DBG("server bpp %i", host_screen->server_depth>>3);
+ host_screen->fb_data = malloc(width*buffer_height*(host_screen->server_depth>>3));
+ return host_screen->fb_data;
+ }
+}
+
+static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+ int x, int y,
+ int width, int height);
+
+void
+hostx_paint_rect (EphyrScreenInfo screen,
+ int sx, int sy,
+ int dx, int dy,
+ int width, int height)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ;
+
+ /*
+ * Copy the image data updated by the shadow layer
+ * on to the window
+ */
+
+ if (HostXWantDamageDebug)
+ {
+ hostx_paint_debug_rect(host_screen, dx, dy, width, height);
+ }
+
+ /*
+ * If the depth of the ephyr server is less than that of the host,
+ * the kdrive fb does not point to the ximage data but to a buffer
+ * ( fb_data ), we shift the various bits from this onto the XImage
+ * so they match the host.
+ *
+ * Note, This code is pretty new ( and simple ) so may break on
+ * endian issues, 32 bpp host etc.
+ * Not sure if 8bpp case is right either.
+ * ... and it will be slower than the matching depth case.
+ */
+
+ if (!host_depth_matches_server(host_screen))
+ {
+ int x,y,idx, bytes_per_pixel = (host_screen->server_depth>>3);
+ unsigned char r,g,b;
+ unsigned long host_pixel;
+
+ EPHYR_DBG("Unmatched host depth host_screen=%p\n", host_screen);
+ for (y=sy; y<sy+height; y++)
+ for (x=sx; x<sx+width; x++)
+ {
+ idx = (host_screen->win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
+
+ switch (host_screen->server_depth)
+ {
+ case 16:
+ {
+ unsigned short pixel = *(unsigned short*)(host_screen->fb_data+idx);
+
+ r = ((pixel & 0xf800) >> 8);
+ g = ((pixel & 0x07e0) >> 3);
+ b = ((pixel & 0x001f) << 3);
+
+ host_pixel = (r << 16) | (g << 8) | (b);
+
+ XPutPixel(host_screen->ximg, x, y, host_pixel);
+ break;
+ }
+ case 8:
+ {
+ unsigned char pixel = *(unsigned char*)(host_screen->fb_data+idx);
+ XPutPixel(host_screen->ximg, x, y, HostX.cmap[pixel]);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ if (HostX.have_shm)
+ {
+ XShmPutImage (HostX.dpy, host_screen->win,
+ HostX.gc, host_screen->ximg,
+ sx, sy, dx, dy, width, height, False);
+ }
+ else
+ {
+ XPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg,
+ sx, sy, dx, dy, width, height);
+ }
+
+ XSync (HostX.dpy, False);
+}
+
+static void
+hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+ int x, int y,
+ int width, int height)
+{
+ struct timespec tspec;
+
+ tspec.tv_sec = HostX.damage_debug_msec / (1000000);
+ tspec.tv_nsec = (HostX.damage_debug_msec % 1000000) * 1000;
+
+ EPHYR_DBG("msec: %li tv_sec %li, tv_msec %li",
+ HostX.damage_debug_msec, tspec.tv_sec, tspec.tv_nsec);
+
+ /* fprintf(stderr, "Xephyr updating: %i+%i %ix%i\n", x, y, width, height); */
+
+ XFillRectangle (HostX.dpy, host_screen->win, HostX.gc, x, y, width,height);
+ XSync (HostX.dpy, False);
+
+ /* nanosleep seems to work better than usleep for me... */
+ nanosleep(&tspec, NULL);
+}
+
+void
+hostx_load_keymap(void)
+{
+ XID *keymap;
+ int host_width, min_keycode, max_keycode, width;
+ int i,j;
+
+ XDisplayKeycodes (HostX.dpy, &min_keycode, &max_keycode);
+
+ EPHYR_DBG ("min: %d, max: %d", min_keycode, max_keycode);
+
+ keymap = XGetKeyboardMapping (HostX.dpy,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &host_width);
+
+ /* Try and copy the hosts keymap into our keymap to avoid loads
+ * of messing around.
+ *
+ * kdrive cannot can have more than 4 keysyms per keycode
+ * so we only copy at most the first 4 ( xorg has 6 per keycode, XVNC 2 )
+ */
+ width = (host_width > 4) ? 4 : host_width;
+
+ ephyrKeySyms.map = (CARD32 *)calloc(sizeof(CARD32),
+ (max_keycode - min_keycode + 1) *
+ width);
+ if (!ephyrKeySyms.map)
+ return;
+
+ for (i=0; i<(max_keycode - min_keycode+1); i++)
+ for (j=0; j<width; j++)
+ ephyrKeySyms.map[(i*width)+j] = (CARD32) keymap[(i*host_width) + j];
+
+ EPHYR_DBG("keymap width, host:%d kdrive:%d", host_width, width);
+
+ ephyrKeySyms.minKeyCode = min_keycode;
+ ephyrKeySyms.maxKeyCode = max_keycode;
+ ephyrKeySyms.mapWidth = width;
+
+ XFree(keymap);
+}
+
+static struct EphyrHostScreen *
+host_screen_from_window (Window w)
+{
+ int index = 0;
+ struct EphyrHostScreen *result = NULL;
+#if 0
+ unsigned int num_children = 0;
+ Window root = None, parent = None, *children = NULL;
+#endif
+
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ if (HostX.screens[index].win == w)
+ {
+ result = &HostX.screens[index];
+ goto out;
+ }
+ }
+#if 0
+ XQueryTree (hostx_get_display (), w, &root, &parent,
+ &children, &num_children);
+ if (parent == root || parent == None)
+ goto out;
+ result = host_screen_from_window (parent);
+#endif
+
+out:
+#if 0
+ if (children)
+ {
+ XFree (children);
+ children = NULL;
+ }
+#endif
+ return result;
+}
+
+int
+hostx_get_event(EphyrHostXEvent *ev)
+{
+ XEvent xev;
+ static int grabbed_screen = -1;
+
+ if (XPending(HostX.dpy))
+ {
+ XNextEvent(HostX.dpy, &xev);
+
+ switch (xev.type)
+ {
+ case Expose:
+ /* Not so great event compression, but works ok */
+ while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window,
+ Expose, &xev));
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xexpose.window);
+ if (host_screen)
+ {
+ hostx_paint_rect (host_screen->info, 0, 0, 0, 0,
+ host_screen->win_width,
+ host_screen->win_height);
+ }
+ else
+ {
+ EPHYR_LOG_ERROR ("failed to get host screen\n");
+ ev->type = EPHYR_EV_EXPOSE;
+ ev->data.expose.window = xev.xexpose.window;
+ return 1;
+ }
+ }
+ return 0;
+
+ case MotionNotify:
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xmotion.window);
+
+ ev->type = EPHYR_EV_MOUSE_MOTION;
+ ev->data.mouse_motion.x = xev.xmotion.x;
+ ev->data.mouse_motion.y = xev.xmotion.y;
+ ev->data.mouse_motion.window = xev.xmotion.window;
+ ev->data.mouse_motion.screen = (host_screen ? host_screen->mynum : -1);
+ }
+ return 1;
+
+ case ButtonPress:
+ ev->type = EPHYR_EV_MOUSE_PRESS;
+ ev->key_state = xev.xkey.state;
+ /*
+ * This is a bit hacky. will break for button 5 ( defined as 0x10 )
+ * Check KD_BUTTON defines in kdrive.h
+ */
+ ev->data.mouse_down.button_num = 1<<(xev.xbutton.button-1);
+ return 1;
+
+ case ButtonRelease:
+ ev->type = EPHYR_EV_MOUSE_RELEASE;
+ ev->key_state = xev.xkey.state;
+ ev->data.mouse_up.button_num = 1<<(xev.xbutton.button-1);
+ return 1;
+
+ case KeyPress:
+ {
+ ev->type = EPHYR_EV_KEY_PRESS;
+ ev->key_state = xev.xkey.state;
+ ev->data.key_down.scancode = xev.xkey.keycode;
+ return 1;
+ }
+ case KeyRelease:
+
+ if ((XKeycodeToKeysym(HostX.dpy,xev.xkey.keycode,0) == XK_Shift_L
+ || XKeycodeToKeysym(HostX.dpy,xev.xkey.keycode,0) == XK_Shift_R)
+ && (xev.xkey.state & ControlMask))
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xexpose.window);
+
+ if (grabbed_screen != -1)
+ {
+ XUngrabKeyboard (HostX.dpy, CurrentTime);
+ XUngrabPointer (HostX.dpy, CurrentTime);
+ grabbed_screen = -1;
+ hostx_set_win_title (host_screen->info,
+ "(ctrl+shift grabs mouse and keyboard)");
+ }
+ else
+ {
+ /* Attempt grab */
+ if (XGrabKeyboard (HostX.dpy, host_screen->win, True,
+ GrabModeAsync,
+ GrabModeAsync,
+ CurrentTime) == 0)
+ {
+ if (XGrabPointer (HostX.dpy, host_screen->win, True,
+ NoEventMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ host_screen->win, None, CurrentTime) == 0)
+ {
+ grabbed_screen = host_screen->mynum;
+ hostx_set_win_title
+ (host_screen->info,
+ "(ctrl+shift releases mouse and keyboard)");
+ }
+ else /* Failed pointer grabm ungrab keyboard */
+ XUngrabKeyboard (HostX.dpy, CurrentTime);
+ }
+ }
+ }
+
+ /* Still send the release event even if above has happened
+ * server will get confused with just an up event.
+ * Maybe it would be better to just block shift+ctrls getting to
+ * kdrive all togeather.
+ */
+ ev->type = EPHYR_EV_KEY_RELEASE;
+ ev->key_state = xev.xkey.state;
+ ev->data.key_up.scancode = xev.xkey.keycode;
+ return 1;
+
+ default:
+ break;
+
+ }
+ }
+ return 0;
+}
+
+void*
+hostx_get_display(void)
+{
+ return HostX.dpy ;
+}
+
+int
+hostx_get_window (int a_screen_number)
+{
+ if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) {
+ EPHYR_LOG_ERROR ("bad screen number:%d\n", a_screen_number) ;
+ return 0;
+ }
+ return HostX.screens[a_screen_number].win ;
+}
+
+int
+hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attrs)
+{
+ XWindowAttributes attrs ;
+
+ memset (&attrs, 0, sizeof (attrs)) ;
+
+ if (!XGetWindowAttributes (hostx_get_display (),
+ a_window,
+ &attrs)) {
+ return FALSE ;
+ }
+ a_attrs->x = attrs.x ;
+ a_attrs->y = attrs.y ;
+ a_attrs->width = attrs.width ;
+ a_attrs->height = attrs.height ;
+ if (attrs.visual)
+ a_attrs->visualid = attrs.visual->visualid ;
+ return TRUE ;
+}
+
+int
+hostx_get_extension_info (const char *a_ext_name,
+ int *a_major_opcode,
+ int *a_first_event,
+ int *a_first_error)
+{
+ if (!a_ext_name || !a_major_opcode || !a_first_event || !a_first_error)
+ return 0 ;
+ if (!XQueryExtension (HostX.dpy,
+ a_ext_name,
+ a_major_opcode,
+ a_first_event,
+ a_first_error))
+ {
+ return 0 ;
+ }
+ return 1 ;
+}
+
+int
+hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
+ int *a_num_entries)
+{
+ Display *dpy=hostx_get_display () ;
+ Bool is_ok=False ;
+ XVisualInfo templ, *visuals=NULL;
+ EphyrHostVisualInfo *host_visuals=NULL ;
+ int nb_items=0, i=0;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_visuals && a_num_entries && dpy,
+ False) ;
+ EPHYR_LOG ("enter\n") ;
+ memset (&templ, 0, sizeof (templ)) ;
+ visuals = XGetVisualInfo (dpy, VisualNoMask, &templ, &nb_items) ;
+ if (!visuals) {
+ EPHYR_LOG_ERROR ("host does not advertise any visual\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host advertises %d visuals\n", nb_items) ;
+ host_visuals = calloc (nb_items, sizeof (EphyrHostVisualInfo)) ;
+ for (i=0; i<nb_items; i++) {
+ host_visuals[i].visualid = visuals[i].visualid ;
+ host_visuals[i].screen = visuals[i].screen ;
+ host_visuals[i].depth = visuals[i].depth ;
+ host_visuals[i].class = visuals[i].class ;
+ host_visuals[i].red_mask = visuals[i].red_mask ;
+ host_visuals[i].green_mask = visuals[i].green_mask ;
+ host_visuals[i].blue_mask = visuals[i].blue_mask ;
+ host_visuals[i].colormap_size = visuals[i].colormap_size ;
+ host_visuals[i].bits_per_rgb = visuals[i].bits_per_rgb ;
+ }
+ *a_visuals = host_visuals ;
+ *a_num_entries = nb_items;
+ host_visuals=NULL;
+
+ is_ok = TRUE;
+out:
+ if (visuals) {
+ XFree (visuals) ;
+ visuals = NULL;
+ }
+ if (host_visuals) {
+ free (host_visuals) ;
+ host_visuals = NULL;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+
+}
+
+int
+hostx_create_window (int a_screen_number,
+ EphyrBox *a_geometry,
+ int a_visual_id,
+ int *a_host_peer /*out parameter*/)
+{
+ Bool is_ok=FALSE ;
+ Display *dpy=hostx_get_display () ;
+ XVisualInfo *visual_info=NULL, visual_info_templ;
+ int visual_mask=VisualIDMask ;
+ Window win=None ;
+ int nb_visuals=0, winmask=0;
+ XSetWindowAttributes attrs;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geometry, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ /*get visual*/
+ memset (&visual_info, 0, sizeof (visual_info)) ;
+ visual_info_templ.visualid = a_visual_id ;
+ visual_info = XGetVisualInfo (dpy, visual_mask,
+ &visual_info_templ,
+ &nb_visuals) ;
+ if (!visual_info) {
+ EPHYR_LOG_ERROR ("argh, could not find a remote visual with id:%d\n",
+ a_visual_id) ;
+ goto out ;
+ }
+ memset (&attrs, 0, sizeof (attrs)) ;
+ attrs.colormap = XCreateColormap (dpy,
+ RootWindow (dpy,
+ visual_info->screen),
+ visual_info->visual,
+ AllocNone) ;
+ attrs.event_mask = ButtonPressMask
+ |ButtonReleaseMask
+ |PointerMotionMask
+ |KeyPressMask
+ |KeyReleaseMask
+ |ExposureMask;
+ winmask = CWColormap|CWEventMask;
+
+ win = XCreateWindow (dpy, hostx_get_window (a_screen_number),
+ a_geometry->x, a_geometry->y,
+ a_geometry->width, a_geometry->height, 0,
+ visual_info->depth, CopyFromParent,
+ visual_info->visual, winmask, &attrs) ;
+ if (win == None) {
+ EPHYR_LOG_ERROR ("failed to create peer window\n") ;
+ goto out ;
+ }
+ XFlush (dpy) ;
+ XMapWindow (dpy, win) ;
+ *a_host_peer = win ;
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+int
+hostx_destroy_window (int a_win)
+{
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+ XDestroyWindow (dpy, a_win) ;
+ XFlush (dpy) ;
+ return TRUE ;
+}
+
+int
+hostx_set_window_geometry (int a_win, EphyrBox *a_geo)
+{
+ Display *dpy=hostx_get_display ();
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_geo, FALSE) ;
+
+ EPHYR_LOG ("enter. x,y,w,h:(%d,%d,%d,%d)\n",
+ a_geo->x, a_geo->y,
+ a_geo->width, a_geo->height) ;
+
+ XMoveWindow (dpy, a_win, a_geo->x, a_geo->y) ;
+ XResizeWindow (dpy, a_win, a_geo->width, a_geo->height) ;
+ EPHYR_LOG ("leave\n") ;
+ return TRUE;
+}
+
+int
+hostx_set_window_bounding_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+ int i=0 ;
+ XRectangle *rects=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
+
+ EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
+
+ rects = calloc (a_num_rects, sizeof (XRectangle)) ;
+ for (i=0; i<a_num_rects; i++) {
+ rects[i].x = a_rects[i].x1 ;
+ rects[i].y = a_rects[i].y1 ;
+ rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
+ rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
+ EPHYR_LOG ("borders clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ /*this aways returns 1*/
+ XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0,
+ rects, a_num_rects, ShapeSet, YXBanded) ;
+ is_ok = TRUE ;
+
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+int
+hostx_set_window_clipping_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects)
+{
+ Bool is_ok=FALSE;
+ Display *dpy=hostx_get_display () ;
+ int i=0 ;
+ XRectangle *rects=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy && a_rects, FALSE) ;
+
+ EPHYR_LOG ("enter. num rects:%d\n", a_num_rects) ;
+
+ rects = calloc (a_num_rects, sizeof (XRectangle)) ;
+ for (i=0; i<a_num_rects; i++) {
+ rects[i].x = a_rects[i].x1 ;
+ rects[i].y = a_rects[i].y1 ;
+ rects[i].width = abs (a_rects[i].x2 - a_rects[i].x1);
+ rects[i].height = abs (a_rects[i].y2 - a_rects[i].y1) ;
+ EPHYR_LOG ("clipped to rect[x:%d,y:%d,w:%d,h:%d]\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ /*this aways returns 1*/
+ XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0,
+ rects, a_num_rects, ShapeSet, YXBanded) ;
+ is_ok = TRUE ;
+
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+int
+hostx_has_xshape (void)
+{
+ int event_base=0, error_base=0 ;
+ Display *dpy=hostx_get_display () ;
+ if (!XShapeQueryExtension (dpy,
+ &event_base,
+ &error_base)) {
+ return FALSE ;
+ }
+ return TRUE;
+}
+
+#ifdef XEPHYR_DRI
+typedef struct {
+ int is_valid ;
+ int local_id ;
+ int remote_id ;
+} ResourcePair ;
+
+#define RESOURCE_PEERS_SIZE 1024*10
+static ResourcePair resource_peers[RESOURCE_PEERS_SIZE] ;
+
+
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id)
+{
+ int i=0 ;
+ ResourcePair *peer=NULL ;
+ Display *dpy=hostx_get_display ();
+
+ /*
+ * first make sure a resource peer
+ * does not exist already for
+ * a_local_resource_id
+ */
+ for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+ if (resource_peers[i].is_valid
+ && resource_peers[i].local_id == a_local_resource_id) {
+ peer = &resource_peers[i] ;
+ break ;
+ }
+ }
+ /*
+ * find one free peer entry, an feed it with
+ */
+ if (!peer) {
+ for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+ if (!resource_peers[i].is_valid) {
+ peer = &resource_peers[i] ;
+ break ;
+ }
+ }
+ if (peer) {
+ peer->remote_id = XAllocID (dpy);
+ peer->local_id = a_local_resource_id ;
+ peer->is_valid = TRUE ;
+ }
+ }
+ if (peer) {
+ *a_remote_resource_id = peer->remote_id ;
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id)
+{
+ int i=0 ;
+ ResourcePair *peer=NULL ;
+ for (i=0; i<RESOURCE_PEERS_SIZE; i++) {
+ if (resource_peers[i].is_valid
+ && resource_peers[i].local_id == a_local_resource_id) {
+ peer = &resource_peers[i] ;
+ break ;
+ }
+ }
+ if (peer) {
+ *a_remote_resource_id = peer->remote_id ;
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+int
+hostx_has_dri (void)
+{
+ int event_base=0, error_base=0 ;
+ Display *dpy=hostx_get_display () ;
+
+ if (!dpy)
+ return FALSE ;
+
+ if (!XF86DRIQueryExtension (dpy,
+ &event_base,
+ &error_base)) {
+ return FALSE ;
+ }
+ return TRUE ;
+}
+
+int
+hostx_has_glx (void)
+{
+ Display *dpy=hostx_get_display () ;
+ int event_base=0, error_base=0 ;
+
+ if (!glXQueryExtension (dpy, &event_base, &error_base)) {
+ return FALSE ;
+ }
+ return TRUE ;
+}
+
+#endif /*XEPHYR_DRI*/
+
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h
new file mode 100644
index 000000000..47ba61b5b
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/hostx.h
@@ -0,0 +1,261 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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 _XLIBS_STUFF_H_
+#define _XLIBS_STUFF_H_
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+
+#define EPHYR_WANT_DEBUG 0
+
+#if (EPHYR_WANT_DEBUG)
+#define EPHYR_DBG(x, a...) \
+ fprintf(stderr, __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
+#else
+#define EPHYR_DBG(x, a...) do {} while (0)
+#endif
+
+typedef struct EphyrHostXVars EphyrHostXVars;
+typedef struct EphyrHostXEvent EphyrHostXEvent;
+typedef void* EphyrScreenInfo ;
+typedef enum EphyrHostXEventType
+{
+ EPHYR_EV_MOUSE_MOTION,
+ EPHYR_EV_MOUSE_PRESS,
+ EPHYR_EV_MOUSE_RELEASE,
+ EPHYR_EV_KEY_PRESS,
+ EPHYR_EV_KEY_RELEASE,
+ EPHYR_EV_EXPOSE
+}
+EphyrHostXEventType;
+
+/* I can't believe it's not a KeySymsRec. */
+typedef struct {
+ int minKeyCode;
+ int maxKeyCode;
+ int mapWidth;
+ CARD32 *map;
+} EphyrKeySyms;
+
+struct EphyrHostXEvent
+{
+ EphyrHostXEventType type;
+
+ union
+ {
+ struct mouse_motion {
+ int x;
+ int y;
+ int screen;
+ int window;
+ } mouse_motion;
+
+ struct mouse_down {
+ int button_num;
+ } mouse_down;
+
+ struct mouse_up {
+ int button_num;
+ } mouse_up;
+
+ struct key_up {
+ int scancode;
+ } key_up;
+
+ struct key_down {
+ int scancode;
+ } key_down;
+
+ struct expose {
+ int window;
+ } expose;
+
+ } data;
+
+ int key_state;
+};
+
+typedef struct {
+ VisualID visualid;
+ int screen;
+ int depth;
+ int class;
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int colormap_size;
+ int bits_per_rgb;
+} EphyrHostVisualInfo;
+
+typedef struct {
+ int x, y;
+ int width, height ;
+ int visualid ;
+} EphyrHostWindowAttributes;
+
+typedef struct {
+ int x,y,width,height;
+} EphyrBox;
+
+typedef struct {
+ short x1,y1,x2,y2;
+} EphyrRect;
+
+int
+hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
+
+int
+hostx_want_host_cursor(void);
+
+void
+hostx_use_host_cursor(void);
+
+void
+hostx_use_fullscreen(void);
+
+int
+hostx_want_fullscreen(void);
+
+int
+hostx_want_preexisting_window(EphyrScreenInfo screen);
+
+void
+hostx_use_preexisting_window(unsigned long win_id);
+
+void
+hostx_use_resname (char *name, int fromcmd);
+
+void
+hostx_handle_signal(int signum);
+
+int
+hostx_init(void);
+
+void
+hostx_add_screen(EphyrScreenInfo screen, unsigned long win_id, int screen_num);
+
+void
+hostx_set_display_name(char *name);
+
+void
+hostx_set_screen_number(EphyrScreenInfo screen, int number);
+
+void
+hostx_set_win_title(EphyrScreenInfo screen, char *extra_text);
+
+int
+hostx_get_depth (void);
+
+int
+hostx_get_server_depth (EphyrScreenInfo screen);
+
+void
+hostx_set_server_depth(EphyrScreenInfo screen, int depth);
+
+int
+hostx_get_bpp(void *info);
+
+void
+hostx_get_visual_masks (void *info,
+ CARD32 *rmsk,
+ CARD32 *gmsk,
+ CARD32 *bmsk);
+void
+hostx_set_cmap_entry(unsigned char idx,
+ unsigned char r,
+ unsigned char g,
+ unsigned char b);
+
+void*
+hostx_screen_init (EphyrScreenInfo screen,
+ int width, int height,
+ int buffer_height);
+
+void
+hostx_paint_rect(EphyrScreenInfo screen,
+ int sx, int sy,
+ int dx, int dy,
+ int width, int height);
+
+
+void
+hostx_load_keymap (void);
+
+int
+hostx_get_event (EphyrHostXEvent *ev);
+
+void*
+hostx_get_display (void) ;
+
+int
+hostx_get_window (int a_screen_number) ;
+
+int
+hostx_get_window_attributes (int a_window, EphyrHostWindowAttributes *a_attr) ;
+
+int
+hostx_get_extension_info (const char *a_ext_name,
+ int *a_major_opcode,
+ int *a_first_even,
+ int *a_first_error) ;
+int
+hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
+ int *a_num_entries) ;
+
+int hostx_create_window (int a_screen_number,
+ EphyrBox *a_geometry,
+ int a_visual_id,
+ int *a_host_win /*out parameter*/) ;
+
+int hostx_destroy_window (int a_win) ;
+
+int hostx_set_window_geometry (int a_win, EphyrBox *a_geo) ;
+
+
+int hostx_set_window_bounding_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects) ;
+
+int hostx_set_window_clipping_rectangles (int a_window,
+ EphyrRect *a_rects,
+ int a_num_rects) ;
+int hostx_has_xshape (void) ;
+
+#ifdef XEPHYR_DRI
+int hostx_lookup_peer_window (void *a_local_window,
+ int *a_host_peer /*out parameter*/) ;
+int
+hostx_allocate_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id) ;
+int
+hostx_get_resource_id_peer (int a_local_resource_id,
+ int *a_remote_resource_id) ;
+int hostx_has_dri (void) ;
+
+int hostx_has_glx (void) ;
+#endif /*XEPHYR_DRI*/
+
+#endif /*_XLIBS_STUFF_H_*/
diff --git a/xorg-server/hw/kdrive/ephyr/os.c b/xorg-server/hw/kdrive/ephyr/os.c
new file mode 100644
index 000000000..4bf6e8858
--- /dev/null
+++ b/xorg-server/hw/kdrive/ephyr/os.c
@@ -0,0 +1,51 @@
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+
+extern void processScreenArg (char *screen_size, char *parent_id) ;
+
+static int
+EphyrInit (void)
+{
+ /*
+ * make sure at least one screen
+ * has been added to the system.
+ */
+ if (!KdCardInfoLast ())
+ {
+ processScreenArg ("640x480", NULL) ;
+ }
+ return hostx_init();
+}
+
+KdOsFuncs EphyrOsFuncs = {
+ .Init = EphyrInit,
+ .pollEvents = ephyrPoll,
+};
+