summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-11-06 21:17:37 -0800
committerAnas Nashif <anas.nashif@intel.com>2012-11-06 21:17:37 -0800
commit9aa09856bf24e0a58e4b63034a80c948a1f44c53 (patch)
tree103710a7f7efc528607be5c3872bd162af08b936 /src
downloadxf86-video-vmware-9aa09856bf24e0a58e4b63034a80c948a1f44c53.tar.gz
xf86-video-vmware-9aa09856bf24e0a58e4b63034a80c948a1f44c53.tar.bz2
xf86-video-vmware-9aa09856bf24e0a58e4b63034a80c948a1f44c53.zip
Imported Upstream version 12.0.2.007bed3upstream/12.0.2.007bed3upstream/12.0.212.0.2upstream
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am63
-rw-r--r--src/Makefile.in711
-rw-r--r--src/bits2pixels.c1418
-rw-r--r--src/bits2pixels.h23
-rw-r--r--src/compat-api.h99
-rw-r--r--src/guest_os.h28
-rw-r--r--src/includeCheck.h2
-rw-r--r--src/svga_escape.h30
-rw-r--r--src/svga_limits.h55
-rw-r--r--src/svga_modes.h48
-rw-r--r--src/svga_overlay.h50
-rw-r--r--src/svga_reg.h1566
-rw-r--r--src/svga_struct.h40
-rw-r--r--src/vm_basic_types.h171
-rw-r--r--src/vm_device_version.h62
-rw-r--r--src/vmware.c1666
-rw-r--r--src/vmware.h316
-rw-r--r--src/vmware_bootstrap.c502
-rw-r--r--src/vmware_bootstrap.h71
-rw-r--r--src/vmware_common.c163
-rw-r--r--src/vmware_common.h43
-rw-r--r--src/vmwarectrl.c624
-rw-r--r--src/vmwarectrl.h48
-rw-r--r--src/vmwarectrlproto.h122
-rw-r--r--src/vmwarecurs.c487
-rw-r--r--src/vmwaremodes.c163
-rw-r--r--src/vmwarevideo.c1352
-rw-r--r--src/vmwarexinerama.c728
28 files changed, 10651 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..b0dd147
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,63 @@
+# Copyright 2005 Adam Jackson.
+#
+# 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
+# on 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
+# ADAM JACKSON 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.
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+
+vmware_drv_la_LTLIBRARIES = vmware_drv.la
+vmware_drv_la_LDFLAGS = -module -avoid-version
+vmware_drv_la_CFLAGS = $(CWARNFLAGS) @XORG_CFLAGS@
+vmware_drv_ladir = @moduledir@/drivers
+
+if BUILD_VMWGFX
+vmware_drv_la_LIBADD = $(top_builddir)/vmwgfx/libvmwgfx.la
+vmware_drv_la_DEPENDENCIES = $(top_builddir)/vmwgfx/libvmwgfx.la
+endif
+
+vmware_drv_la_SOURCES = \
+ bits2pixels.c \
+ bits2pixels.h \
+ compat-api.h \
+ guest_os.h \
+ includeCheck.h \
+ svga_escape.h \
+ svga_limits.h \
+ svga_modes.h \
+ svga_overlay.h \
+ svga_reg.h \
+ svga_struct.h \
+ vm_basic_types.h \
+ vm_device_version.h \
+ vmware.c \
+ vmwarecurs.c \
+ vmware.h \
+ vmwarectrl.c \
+ vmwarectrl.h \
+ vmwarectrlproto.h \
+ vmwarexinerama.c \
+ vmwarevideo.c \
+ vmwaremodes.c \
+ vmware_bootstrap.h \
+ vmware_bootstrap.c \
+ vmware_common.c \
+ vmware_common.h
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..1c6fb5d
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,711 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@
+
+# Copyright 2005 Adam Jackson.
+#
+# 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
+# on 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
+# ADAM JACKSON 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.
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@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@
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(vmware_drv_ladir)"
+LTLIBRARIES = $(vmware_drv_la_LTLIBRARIES)
+am_vmware_drv_la_OBJECTS = vmware_drv_la-bits2pixels.lo \
+ vmware_drv_la-vmware.lo vmware_drv_la-vmwarecurs.lo \
+ vmware_drv_la-vmwarectrl.lo vmware_drv_la-vmwarexinerama.lo \
+ vmware_drv_la-vmwarevideo.lo vmware_drv_la-vmwaremodes.lo \
+ vmware_drv_la-vmware_bootstrap.lo \
+ vmware_drv_la-vmware_common.lo
+vmware_drv_la_OBJECTS = $(am_vmware_drv_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+vmware_drv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(vmware_drv_la_CFLAGS) \
+ $(CFLAGS) $(vmware_drv_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(vmware_drv_la_SOURCES)
+DIST_SOURCES = $(vmware_drv_la_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@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASE_CFLAGS = @BASE_CFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRIVER_NAME = @DRIVER_NAME@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_CMD = @INSTALL_CMD@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+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@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN_SUBSTS = @MAN_SUBSTS@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
+PCIACCESS_LIBS = @PCIACCESS_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRICT_CFLAGS = @STRICT_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XATRACKER_CFLAGS = @XATRACKER_CFLAGS@
+XATRACKER_LIBS = @XATRACKER_LIBS@
+XORG_CFLAGS = @XORG_CFLAGS@
+XORG_LIBS = @XORG_LIBS@
+XORG_MAN_PAGE = @XORG_MAN_PAGE@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+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@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+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@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+vmware_drv_la_LTLIBRARIES = vmware_drv.la
+vmware_drv_la_LDFLAGS = -module -avoid-version
+vmware_drv_la_CFLAGS = $(CWARNFLAGS) @XORG_CFLAGS@
+vmware_drv_ladir = @moduledir@/drivers
+@BUILD_VMWGFX_TRUE@vmware_drv_la_LIBADD = $(top_builddir)/vmwgfx/libvmwgfx.la
+@BUILD_VMWGFX_TRUE@vmware_drv_la_DEPENDENCIES = $(top_builddir)/vmwgfx/libvmwgfx.la
+vmware_drv_la_SOURCES = \
+ bits2pixels.c \
+ bits2pixels.h \
+ compat-api.h \
+ guest_os.h \
+ includeCheck.h \
+ svga_escape.h \
+ svga_limits.h \
+ svga_modes.h \
+ svga_overlay.h \
+ svga_reg.h \
+ svga_struct.h \
+ vm_basic_types.h \
+ vm_device_version.h \
+ vmware.c \
+ vmwarecurs.c \
+ vmware.h \
+ vmwarectrl.c \
+ vmwarectrl.h \
+ vmwarectrlproto.h \
+ vmwarexinerama.c \
+ vmwarevideo.c \
+ vmwaremodes.c \
+ vmware_bootstrap.h \
+ vmware_bootstrap.c \
+ vmware_common.c \
+ vmware_common.h
+
+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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/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
+$(am__aclocal_m4_deps):
+install-vmware_drv_laLTLIBRARIES: $(vmware_drv_la_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(vmware_drv_ladir)" || $(MKDIR_P) "$(DESTDIR)$(vmware_drv_ladir)"
+ @list='$(vmware_drv_la_LTLIBRARIES)'; test -n "$(vmware_drv_ladir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(vmware_drv_ladir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(vmware_drv_ladir)"; \
+ }
+
+uninstall-vmware_drv_laLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(vmware_drv_la_LTLIBRARIES)'; test -n "$(vmware_drv_ladir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(vmware_drv_ladir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(vmware_drv_ladir)/$$f"; \
+ done
+
+clean-vmware_drv_laLTLIBRARIES:
+ -test -z "$(vmware_drv_la_LTLIBRARIES)" || rm -f $(vmware_drv_la_LTLIBRARIES)
+ @list='$(vmware_drv_la_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+vmware_drv.la: $(vmware_drv_la_OBJECTS) $(vmware_drv_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(vmware_drv_la_LINK) -rpath $(vmware_drv_ladir) $(vmware_drv_la_OBJECTS) $(vmware_drv_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-bits2pixels.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmware.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmware_bootstrap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmware_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmwarectrl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmwarecurs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmwaremodes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmwarevideo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmware_drv_la-vmwarexinerama.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@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@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@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@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@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 $@ $<
+
+vmware_drv_la-bits2pixels.lo: bits2pixels.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-bits2pixels.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-bits2pixels.Tpo -c -o vmware_drv_la-bits2pixels.lo `test -f 'bits2pixels.c' || echo '$(srcdir)/'`bits2pixels.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-bits2pixels.Tpo $(DEPDIR)/vmware_drv_la-bits2pixels.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bits2pixels.c' object='vmware_drv_la-bits2pixels.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-bits2pixels.lo `test -f 'bits2pixels.c' || echo '$(srcdir)/'`bits2pixels.c
+
+vmware_drv_la-vmware.lo: vmware.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmware.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmware.Tpo -c -o vmware_drv_la-vmware.lo `test -f 'vmware.c' || echo '$(srcdir)/'`vmware.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmware.Tpo $(DEPDIR)/vmware_drv_la-vmware.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmware.c' object='vmware_drv_la-vmware.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmware.lo `test -f 'vmware.c' || echo '$(srcdir)/'`vmware.c
+
+vmware_drv_la-vmwarecurs.lo: vmwarecurs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmwarecurs.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmwarecurs.Tpo -c -o vmware_drv_la-vmwarecurs.lo `test -f 'vmwarecurs.c' || echo '$(srcdir)/'`vmwarecurs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmwarecurs.Tpo $(DEPDIR)/vmware_drv_la-vmwarecurs.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmwarecurs.c' object='vmware_drv_la-vmwarecurs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmwarecurs.lo `test -f 'vmwarecurs.c' || echo '$(srcdir)/'`vmwarecurs.c
+
+vmware_drv_la-vmwarectrl.lo: vmwarectrl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmwarectrl.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmwarectrl.Tpo -c -o vmware_drv_la-vmwarectrl.lo `test -f 'vmwarectrl.c' || echo '$(srcdir)/'`vmwarectrl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmwarectrl.Tpo $(DEPDIR)/vmware_drv_la-vmwarectrl.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmwarectrl.c' object='vmware_drv_la-vmwarectrl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmwarectrl.lo `test -f 'vmwarectrl.c' || echo '$(srcdir)/'`vmwarectrl.c
+
+vmware_drv_la-vmwarexinerama.lo: vmwarexinerama.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmwarexinerama.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmwarexinerama.Tpo -c -o vmware_drv_la-vmwarexinerama.lo `test -f 'vmwarexinerama.c' || echo '$(srcdir)/'`vmwarexinerama.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmwarexinerama.Tpo $(DEPDIR)/vmware_drv_la-vmwarexinerama.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmwarexinerama.c' object='vmware_drv_la-vmwarexinerama.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmwarexinerama.lo `test -f 'vmwarexinerama.c' || echo '$(srcdir)/'`vmwarexinerama.c
+
+vmware_drv_la-vmwarevideo.lo: vmwarevideo.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmwarevideo.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmwarevideo.Tpo -c -o vmware_drv_la-vmwarevideo.lo `test -f 'vmwarevideo.c' || echo '$(srcdir)/'`vmwarevideo.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmwarevideo.Tpo $(DEPDIR)/vmware_drv_la-vmwarevideo.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmwarevideo.c' object='vmware_drv_la-vmwarevideo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmwarevideo.lo `test -f 'vmwarevideo.c' || echo '$(srcdir)/'`vmwarevideo.c
+
+vmware_drv_la-vmwaremodes.lo: vmwaremodes.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmwaremodes.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmwaremodes.Tpo -c -o vmware_drv_la-vmwaremodes.lo `test -f 'vmwaremodes.c' || echo '$(srcdir)/'`vmwaremodes.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmwaremodes.Tpo $(DEPDIR)/vmware_drv_la-vmwaremodes.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmwaremodes.c' object='vmware_drv_la-vmwaremodes.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmwaremodes.lo `test -f 'vmwaremodes.c' || echo '$(srcdir)/'`vmwaremodes.c
+
+vmware_drv_la-vmware_bootstrap.lo: vmware_bootstrap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmware_bootstrap.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmware_bootstrap.Tpo -c -o vmware_drv_la-vmware_bootstrap.lo `test -f 'vmware_bootstrap.c' || echo '$(srcdir)/'`vmware_bootstrap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmware_bootstrap.Tpo $(DEPDIR)/vmware_drv_la-vmware_bootstrap.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmware_bootstrap.c' object='vmware_drv_la-vmware_bootstrap.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmware_bootstrap.lo `test -f 'vmware_bootstrap.c' || echo '$(srcdir)/'`vmware_bootstrap.c
+
+vmware_drv_la-vmware_common.lo: vmware_common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -MT vmware_drv_la-vmware_common.lo -MD -MP -MF $(DEPDIR)/vmware_drv_la-vmware_common.Tpo -c -o vmware_drv_la-vmware_common.lo `test -f 'vmware_common.c' || echo '$(srcdir)/'`vmware_common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vmware_drv_la-vmware_common.Tpo $(DEPDIR)/vmware_drv_la-vmware_common.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmware_common.c' object='vmware_drv_la-vmware_common.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vmware_drv_la_CFLAGS) $(CFLAGS) -c -o vmware_drv_la-vmware_common.lo `test -f 'vmware_common.c' || echo '$(srcdir)/'`vmware_common.c
+
+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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ 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; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ 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)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__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 "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$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 $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(vmware_drv_ladir)"; 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)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-generic clean-libtool clean-vmware_drv_laLTLIBRARIES \
+ 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
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-vmware_drv_laLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+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-vmware_drv_laLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-vmware_drv_laLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am 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 install-vmware_drv_laLTLIBRARIES 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-vmware_drv_laLTLIBRARIES
+
+
+# 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/src/bits2pixels.c b/src/bits2pixels.c
new file mode 100644
index 0000000..e3801c5
--- /dev/null
+++ b/src/bits2pixels.c
@@ -0,0 +1,1418 @@
+/* **********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_bits2pixels[] = "Id: bits2pixels.c,v 1.6 2001/01/26 23:32:15 yoel Exp $";
+#else
+#define FILECODE "F(814)"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * bits2pixels.c --
+ *
+ * Emulation routines to convert bitmaps to pixmaps
+ */
+
+#include "vm_basic_types.h"
+#include "bits2pixels.h"
+
+
+/*
+ * Local functions
+ */
+
+static void RasterBitsToPixels8(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+static void RasterBitsToPixels16(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+static void RasterBitsToPixels24(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+static void RasterBitsToPixels32(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * vmwareRaster_BitsToPixels --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg).
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+vmwareRaster_BitsToPixels(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment, int bytes_per_pixel,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ switch (bytes_per_pixel) {
+ case 1:
+ RasterBitsToPixels8(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+
+ case 2:
+ RasterBitsToPixels16(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+
+ case 3:
+ RasterBitsToPixels24(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+
+ case 4:
+ RasterBitsToPixels32(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels8 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for an 8-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels8(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint8 *lpix, *lbits;
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ for (i=0; i<height; i++) {
+ lpix = pix;
+ lbits = bits;
+ for (j = width ; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fg : bg;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels16 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for a 16-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels16(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint16 *lpix;
+ uint8 *lbits;
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ for (i=0; i<height; i++) {
+ lpix = (uint16 *)pix;
+ lbits = bits;
+ for (j = width; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fg : bg;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels24 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for a 24-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels24(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint8 *lpix, *lbits;
+ uint32 fgColor1, fgColor2, fgColor3;
+ uint32 bgColor1, bgColor2, bgColor3;
+
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ fgColor1 = fg & 0x000000ff;
+ fgColor2 = (fg >> 8) & 0x000000ff;
+ fgColor3 = (fg >> 16) & 0x000000ff;
+
+ bgColor1 = bg & 0x000000ff;
+ bgColor2 = (bg >> 8) & 0x000000ff;
+ bgColor3 = (bg >> 16) & 0x000000ff;
+
+ for (i=0; i<height; i++) {
+ lpix = pix;
+ lbits = bits;
+ for (j = width; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 1:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 2:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 3:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 4:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 5:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 6:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 7:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 8:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 9:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 10:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 11:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 12:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 13:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 14:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 15:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 1:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 2:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 3:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 4:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 5:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 6:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 7:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 8:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 9:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 10:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 11:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 12:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 13:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 14:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 15:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fgColor1 : bgColor1;
+ *lpix++ = (expbits & 0x08) ? fgColor2 : bgColor2;
+ *lpix++ = (expbits & 0x08) ? fgColor3 : bgColor3;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fgColor1 : bgColor1;
+ *lpix++ = (expbits & 0x04) ? fgColor2 : bgColor2;
+ *lpix++ = (expbits & 0x04) ? fgColor3 : bgColor3;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fgColor1 : bgColor1;
+ *lpix++ = (expbits & 0x02) ? fgColor2 : bgColor2;
+ *lpix++ = (expbits & 0x02) ? fgColor3 : bgColor3;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels32 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for a 32-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels32(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint32 *lpix;
+ uint8 *lbits;
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ for (i=0; i<height; i++) {
+ lpix = (uint32 *)pix;
+ lbits = bits;
+ for (j = width; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fg : bg;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
diff --git a/src/bits2pixels.h b/src/bits2pixels.h
new file mode 100644
index 0000000..7eb4631
--- /dev/null
+++ b/src/bits2pixels.h
@@ -0,0 +1,23 @@
+/* **********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+/*
+ * bits2pixels.h --
+ *
+ * Drawing emulation routines
+ */
+
+#ifndef _BITS2PIXELS_H_
+#define _BITS2PIXELS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#include "includeCheck.h"
+
+void
+vmwareRaster_BitsToPixels(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment, int bytes_per_pixel,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+#endif /* _BITS4PIXELS_H_ */
diff --git a/src/compat-api.h b/src/compat-api.h
new file mode 100644
index 0000000..205ac59
--- /dev/null
+++ b/src/compat-api.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Author: Dave Airlie <airlied@redhat.com>
+ */
+
+/* this file provides API compat between server post 1.13 and pre it,
+ it should be reused inside as many drivers as possible */
+#ifndef COMPAT_API_H
+#define COMPAT_API_H
+
+#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR
+#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum]
+#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p
+#endif
+
+#ifndef XF86_HAS_SCRN_CONV
+#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum]
+#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex]
+#endif
+
+#ifndef XF86_SCRN_INTERFACE
+
+#define SCRN_ARG_TYPE int
+#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = xf86Screens[(arg1)]
+
+#define SCREEN_ARG_TYPE int
+#define SCREEN_PTR(arg1) ScreenPtr pScreen = screenInfo.screens[(arg1)]
+
+#define SCREEN_INIT_ARGS_DECL int scrnIndex, ScreenPtr pScreen, int argc, char **argv
+
+#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer pTimeout, pointer pReadmask
+#define BLOCKHANDLER_ARGS arg, blockData, pTimeout, pReadmask
+
+#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr pScreen
+#define CLOSE_SCREEN_ARGS scrnIndex, pScreen
+
+#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags
+#define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0
+
+#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags
+#define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0
+
+#define FREE_SCREEN_ARGS_DECL int arg, int flags
+
+#define VT_FUNC_ARGS_DECL int arg, int flags
+#define VT_FUNC_ARGS pScrn->scrnIndex, 0
+
+#define XF86_SCRN_ARG(x) ((x)->scrnIndex)
+#else
+#define SCRN_ARG_TYPE ScrnInfoPtr
+#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = (arg1)
+
+#define SCREEN_ARG_TYPE ScreenPtr
+#define SCREEN_PTR(arg1) ScreenPtr pScreen = (arg1)
+
+#define SCREEN_INIT_ARGS_DECL ScreenPtr pScreen, int argc, char **argv
+
+#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout, pointer pReadmask
+#define BLOCKHANDLER_ARGS arg, pTimeout, pReadmask
+
+#define CLOSE_SCREEN_ARGS_DECL ScreenPtr pScreen
+#define CLOSE_SCREEN_ARGS pScreen
+
+#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y
+#define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y
+
+#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode
+#define SWITCH_MODE_ARGS(arg, m) arg, m
+
+#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg
+
+#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg
+#define VT_FUNC_ARGS pScrn
+
+#define XF86_SCRN_ARG(x) (x)
+
+#endif
+
+#endif
diff --git a/src/guest_os.h b/src/guest_os.h
new file mode 100644
index 0000000..4beaf7c
--- /dev/null
+++ b/src/guest_os.h
@@ -0,0 +1,28 @@
+/* *********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+#ifndef _GUEST_OS_H_
+#define _GUEST_OS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#include "includeCheck.h"
+
+#define GUEST_OS_BASE 0x5000
+
+#define GUEST_OS_DOS (GUEST_OS_BASE+1)
+#define GUEST_OS_WIN31 (GUEST_OS_BASE+2)
+#define GUEST_OS_WINDOWS95 (GUEST_OS_BASE+3)
+#define GUEST_OS_WINDOWS98 (GUEST_OS_BASE+4)
+#define GUEST_OS_WINDOWSME (GUEST_OS_BASE+5)
+#define GUEST_OS_NT (GUEST_OS_BASE+6)
+#define GUEST_OS_WIN2000 (GUEST_OS_BASE+7)
+#define GUEST_OS_LINUX (GUEST_OS_BASE+8)
+#define GUEST_OS_OS2 (GUEST_OS_BASE+9)
+#define GUEST_OS_OTHER (GUEST_OS_BASE+10)
+#define GUEST_OS_FREEBSD (GUEST_OS_BASE+11)
+#define GUEST_OS_WHISTLER (GUEST_OS_BASE+12)
+
+
+#endif
diff --git a/src/includeCheck.h b/src/includeCheck.h
new file mode 100644
index 0000000..88ac8ef
--- /dev/null
+++ b/src/includeCheck.h
@@ -0,0 +1,2 @@
+/* This space intentionally left blank. */
+
diff --git a/src/svga_escape.h b/src/svga_escape.h
new file mode 100644
index 0000000..c9e7b23
--- /dev/null
+++ b/src/svga_escape.h
@@ -0,0 +1,30 @@
+/* **********************************************************
+ * Copyright 2007 VMware, Inc. All rights reserved.
+ * **********************************************************/
+
+/*
+ * svga_escape.h --
+ *
+ * Definitions for our own (vendor-specific) SVGA Escape commands.
+ */
+
+#ifndef _SVGA_ESCAPE_H_
+#define _SVGA_ESCAPE_H_
+
+/*
+ * Namespace IDs for the escape command
+ */
+
+#define SVGA_ESCAPE_NSID_VMWARE 0x00000000
+#define SVGA_ESCAPE_NSID_DEVEL 0xFFFFFFFF
+
+/*
+ * Within SVGA_ESCAPE_NSID_VMWARE, we multiplex commands according to
+ * the first DWORD of escape data (after the nsID and size). As a
+ * guideline we're using the high word and low word as a major and
+ * minor command number, respectively.
+ */
+
+#define SVGA_ESCAPE_VMWARE_MAJOR_MASK 0xFFFF0000
+
+#endif /* _SVGA_ESCAPE_H_ */
diff --git a/src/svga_limits.h b/src/svga_limits.h
new file mode 100644
index 0000000..3b35ccc
--- /dev/null
+++ b/src/svga_limits.h
@@ -0,0 +1,55 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+/*
+ * svga_limits.h --
+ *
+ * SVGA limits
+ */
+
+#ifndef _SVGA_LIMITS_H_
+#define _SVGA_LIMITS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#include "includeCheck.h"
+
+/*
+ * Location and size of SVGA frame buffer and the FIFO.
+ */
+#define SVGA_VRAM_SIZE (16*1024*1024)
+#define SVGA_MEM_SIZE (256*1024)
+
+/*
+ * SVGA_FB_START is the default starting address of the SVGA frame
+ * buffer in the guest's physical address space.
+ * SVGA_FB_START_BIGMEM is the starting address of the SVGA frame
+ * buffer for VMs that have a large amount of physical memory.
+ *
+ * The address of SVGA_FB_START is set to 2GB - (SVGA_FB_MAX_SIZE + SVGA_MEM_SIZE),
+ * thus the SVGA frame buffer sits at [SVGA_FB_START .. 2GB-1] in the
+ * physical address space. Our older SVGA drivers for NT treat the
+ * address of the frame buffer as a signed integer. For backwards
+ * compatibility, we keep the default location of the frame buffer
+ * at under 2GB in the address space. This restricts VMs to have "only"
+ * up to ~2031MB (i.e., up to SVGA_FB_START) of physical memory.
+ *
+ * For VMs that want more memory than the ~2031MB, we place the SVGA
+ * frame buffer at SVGA_FB_START_BIGMEM. This allows VMs to have up
+ * to 3584MB, at least as far as the SVGA frame buffer is concerned
+ * (note that there may be other issues that limit the VM memory
+ * size). PCI devices use high memory addresses, so we have to put
+ * SVGA_FB_START_BIGMEM low enough so that it doesn't overlap with any
+ * of these devices. Placing SVGA_FB_START_BIGMEM at 0xE0000000
+ * should leave plenty of room for the PCI devices.
+ *
+ * NOTE: All of that is only true for the 0710 chipset. As of the 0405
+ * chipset, the framebuffer start is determined solely based on the value
+ * the guest BIOS or OS programs into the PCI base address registers.
+ */
+#define SVGA_FB_LEGACY_START 0x7EFC0000
+#define SVGA_FB_LEGACY_START_BIGMEM 0xE0000000
+
+#endif
diff --git a/src/svga_modes.h b/src/svga_modes.h
new file mode 100644
index 0000000..97d869e
--- /dev/null
+++ b/src/svga_modes.h
@@ -0,0 +1,48 @@
+/* **********************************************************
+ * Copyright (C) 2007 VMware, Inc. All Rights Reserved
+ * **********************************************************/
+
+#ifndef _SVGA_MODES_H_
+#define _SVGA_MODES_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#include "includeCheck.h"
+
+#define SVGA_DEFAULT_MODES \
+ /* 4:3 modes */ \
+ SVGA_DEFAULT_MODE( 320, 240) \
+ SVGA_DEFAULT_MODE( 400, 300) \
+ SVGA_DEFAULT_MODE( 512, 384) \
+ SVGA_DEFAULT_MODE( 640, 480) \
+ SVGA_DEFAULT_MODE( 800, 600) \
+ SVGA_DEFAULT_MODE(1024, 768) \
+ SVGA_DEFAULT_MODE(1152, 864) \
+ SVGA_DEFAULT_MODE(1280, 960) \
+ SVGA_DEFAULT_MODE(1400, 1050) \
+ SVGA_DEFAULT_MODE(1600, 1200) \
+ SVGA_DEFAULT_MODE(1920, 1440) \
+ SVGA_DEFAULT_MODE(2048, 1536) \
+ SVGA_DEFAULT_MODE(2560, 1920) \
+ /* 16:9 modes */ \
+ SVGA_DEFAULT_MODE( 854, 480) \
+ SVGA_DEFAULT_MODE(1280, 720) \
+ SVGA_DEFAULT_MODE(1366, 768) \
+ SVGA_DEFAULT_MODE(1920, 1080) \
+ /* 16:10 modes */ \
+ SVGA_DEFAULT_MODE(1280, 800) \
+ SVGA_DEFAULT_MODE(1440, 900) \
+ SVGA_DEFAULT_MODE(1680, 1050) \
+ SVGA_DEFAULT_MODE(1920, 1200) \
+ SVGA_DEFAULT_MODE(2560, 1600) \
+ /* DVD modes */ \
+ SVGA_DEFAULT_MODE( 720, 480) \
+ SVGA_DEFAULT_MODE( 720, 576) \
+ /* Odd modes */ \
+ SVGA_DEFAULT_MODE( 320, 200) \
+ SVGA_DEFAULT_MODE( 640, 400) \
+ SVGA_DEFAULT_MODE( 800, 480) \
+ SVGA_DEFAULT_MODE(1280, 768) \
+ SVGA_DEFAULT_MODE(1280, 1024)
+
+
+#endif /* _SVGA_MODES_H_ */
diff --git a/src/svga_overlay.h b/src/svga_overlay.h
new file mode 100644
index 0000000..46aef9d
--- /dev/null
+++ b/src/svga_overlay.h
@@ -0,0 +1,50 @@
+/* **********************************************************
+ * Copyright 2007 VMware, Inc. All rights reserved.
+ * **********************************************************/
+
+/*
+ * svga_overlay.h --
+ *
+ * Definitions for video-overlay support.
+ */
+
+#ifndef _SVGA_OVERLAY_H_
+#define _SVGA_OVERLAY_H_
+
+/*
+ * Video formats we support
+ */
+
+#define VMWARE_FOURCC_YV12 0x32315659 /* 'Y' 'V' '1' '2' */
+#define VMWARE_FOURCC_YUY2 0x32595559 /* 'Y' 'U' 'Y' '2' */
+#define VMWARE_FOURCC_UYVY 0x59565955 /* 'U' 'Y' 'V' 'Y' */
+
+#define SVGA_ESCAPE_VMWARE_VIDEO 0x00020000
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS 0x00020001
+ /* FIFO escape layout:
+ * Type, Stream Id, (Register Id, Value) pairs */
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_FLUSH 0x00020002
+ /* FIFO escape layout:
+ * Type, Stream Id */
+
+typedef struct SVGAEscapeVideoSetRegs {
+ struct {
+ uint32 cmdType;
+ uint32 streamId;
+ } header;
+
+ /* May include zero or more items. */
+ struct {
+ uint32 registerId;
+ uint32 value;
+ } items[1];
+} SVGAEscapeVideoSetRegs;
+
+typedef struct SVGAEscapeVideoFlush {
+ uint32 cmdType;
+ uint32 streamId;
+} SVGAEscapeVideoFlush;
+
+#endif /* _SVGA_OVERLAY_H_ */
diff --git a/src/svga_reg.h b/src/svga_reg.h
new file mode 100644
index 0000000..0e1aa17
--- /dev/null
+++ b/src/svga_reg.h
@@ -0,0 +1,1566 @@
+/**********************************************************
+ * Copyright 1998-2009 VMware, 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ * Virtual hardware definitions for the VMware SVGA II device.
+ */
+
+#ifndef _SVGA_REG_H_
+#define _SVGA_REG_H_
+
+/*
+ * PCI device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE 0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
+
+/*
+ * SVGA_REG_ENABLE bit definitions.
+ */
+#define SVGA_REG_ENABLE_DISABLE 0
+#define SVGA_REG_ENABLE_ENABLE 1
+#define SVGA_REG_ENABLE_HIDE 2
+#define SVGA_REG_ENABLE_ENABLE_HIDE (SVGA_REG_ENABLE_ENABLE |\
+ SVGA_REG_ENABLE_HIDE)
+
+/*
+ * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned
+ * cursor bypass mode. This is still supported, but no new guest
+ * drivers should use it.
+ */
+#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */
+
+/*
+ * The maximum framebuffer size that can traced for e.g. guests in VESA mode.
+ * The changeMap in the monitor is proportional to this number. Therefore, we'd
+ * like to keep it as small as possible to reduce monitor overhead (using
+ * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over
+ * 4k!).
+ *
+ * NB: For compatibility reasons, this value must be greater than 0xff0000.
+ * See bug 335072.
+ */
+#define SVGA_FB_MAX_TRACEABLE_SIZE 0x1000000
+
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8
+#define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+#define SVGA_NUM_PALETTE_REGS (3 * SVGA_MAX_PSEUDOCOLORS)
+
+/* Base and Offset gets us headed the right way for PCI Base Addr Registers */
+#define SVGA_LEGACY_BASE_PORT 0x4560
+#define SVGA_NUM_PORTS 0x3
+
+#define SVGA_MAGIC 0x900000UL
+#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
+
+/* Version 2 let the address of the frame buffer be unsigned on Win32 */
+#define SVGA_VERSION_2 2
+#define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2)
+
+/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
+ PALETTE_BASE has moved */
+#define SVGA_VERSION_1 1
+#define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1)
+
+/* Version 0 is the initial version */
+#define SVGA_VERSION_0 0
+#define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0)
+
+/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */
+#define SVGA_ID_INVALID 0xFFFFFFFF
+
+/* Port offsets, relative to BAR0 */
+#define SVGA_INDEX_PORT 0x0
+#define SVGA_VALUE_PORT 0x1
+#define SVGA_BIOS_PORT 0x2
+#define SVGA_IRQSTATUS_PORT 0x8
+
+/*
+ * Interrupt source flags for IRQSTATUS_PORT and IRQMASK.
+ *
+ * Interrupts are only supported when the
+ * SVGA_CAP_IRQMASK capability is present.
+ */
+#define SVGA_IRQFLAG_ANY_FENCE 0x1 /* Any fence was passed */
+#define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */
+#define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */
+
+/*
+ * Registers
+ */
+
+enum {
+ SVGA_REG_ID = 0,
+ SVGA_REG_ENABLE = 1,
+ SVGA_REG_WIDTH = 2,
+ SVGA_REG_HEIGHT = 3,
+ SVGA_REG_MAX_WIDTH = 4,
+ SVGA_REG_MAX_HEIGHT = 5,
+ SVGA_REG_DEPTH = 6,
+ SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */
+ SVGA_REG_PSEUDOCOLOR = 8,
+ SVGA_REG_RED_MASK = 9,
+ SVGA_REG_GREEN_MASK = 10,
+ SVGA_REG_BLUE_MASK = 11,
+ SVGA_REG_BYTES_PER_LINE = 12,
+ SVGA_REG_FB_START = 13, /* (Deprecated) */
+ SVGA_REG_FB_OFFSET = 14,
+ SVGA_REG_VRAM_SIZE = 15,
+ SVGA_REG_FB_SIZE = 16,
+
+ /* ID 0 implementation only had the above registers, then the palette */
+
+ SVGA_REG_CAPABILITIES = 17,
+ SVGA_REG_MEM_START = 18, /* (Deprecated) */
+ SVGA_REG_MEM_SIZE = 19,
+ SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */
+ SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */
+ SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */
+ SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */
+ SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */
+ SVGA_REG_CURSOR_X = 25, /* (Deprecated) */
+ SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */
+ SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */
+ SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */
+ SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */
+ SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */
+ SVGA_REG_NUM_DISPLAYS = 31, /* (Deprecated) */
+ SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */
+ SVGA_REG_IRQMASK = 33, /* Interrupt mask */
+
+ /* Legacy multi-monitor support */
+ SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */
+ SVGA_REG_DISPLAY_ID = 35, /* Display ID for the following display attributes */
+ SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */
+ SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */
+ SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */
+ SVGA_REG_DISPLAY_WIDTH = 39, /* The display's width */
+ SVGA_REG_DISPLAY_HEIGHT = 40, /* The display's height */
+
+ /* See "Guest memory regions" below. */
+ SVGA_REG_GMR_ID = 41,
+ SVGA_REG_GMR_DESCRIPTOR = 42,
+ SVGA_REG_GMR_MAX_IDS = 43,
+ SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44,
+
+ SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */
+ SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */
+ SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */
+ SVGA_REG_TOP = 48, /* Must be 1 more than the last register */
+
+ SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */
+ /* Next 768 (== 256*3) registers exist for colormap */
+
+ SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS
+ /* Base of scratch registers */
+ /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage:
+ First 4 are reserved for VESA BIOS Extension; any remaining are for
+ the use of the current SVGA driver. */
+};
+
+/*
+ * Macros to compute variable length items (sizes in 32-bit words, except
+ * for SVGA_GLYPH_SCANLINE_SIZE, which is in bytes).
+ */
+#define SVGA_BITMAP_SIZE(w,h) ((((w)+31) >> 5) * (h))
+#define SVGA_PIXMAP_SIZE(w,h,bpp) ((( ((w)*(bpp))+31 ) >> 5) * (h))
+#define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32))
+#define SVGA_PIXMAP_INCREMENT(w,bpp) ((( ((w)*(bpp))+31 ) >> 5) * sizeof (uint32))
+
+/*
+ * Guest memory regions (GMRs):
+ *
+ * This is a new memory mapping feature available in SVGA devices
+ * which have the SVGA_CAP_GMR bit set. Previously, there were two
+ * fixed memory regions available with which to share data between the
+ * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs
+ * are our name for an extensible way of providing arbitrary DMA
+ * buffers for use between the driver and the SVGA device. They are a
+ * new alternative to framebuffer memory, usable for both 2D and 3D
+ * graphics operations.
+ *
+ * Since GMR mapping must be done synchronously with guest CPU
+ * execution, we use a new pair of SVGA registers:
+ *
+ * SVGA_REG_GMR_ID --
+ *
+ * Read/write.
+ * This register holds the 32-bit ID (a small positive integer)
+ * of a GMR to create, delete, or redefine. Writing this register
+ * has no side-effects.
+ *
+ * SVGA_REG_GMR_DESCRIPTOR --
+ *
+ * Write-only.
+ * Writing this register will create, delete, or redefine the GMR
+ * specified by the above ID register. If this register is zero,
+ * the GMR is deleted. Any pointers into this GMR (including those
+ * currently being processed by FIFO commands) will be
+ * synchronously invalidated.
+ *
+ * If this register is nonzero, it must be the physical page
+ * number (PPN) of a data structure which describes the physical
+ * layout of the memory region this GMR should describe. The
+ * descriptor structure will be read synchronously by the SVGA
+ * device when this register is written. The descriptor need not
+ * remain allocated for the lifetime of the GMR.
+ *
+ * The guest driver should write SVGA_REG_GMR_ID first, then
+ * SVGA_REG_GMR_DESCRIPTOR.
+ *
+ * SVGA_REG_GMR_MAX_IDS --
+ *
+ * Read-only.
+ * The SVGA device may choose to support a maximum number of
+ * user-defined GMR IDs. This register holds the number of supported
+ * IDs. (The maximum supported ID plus 1)
+ *
+ * SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH --
+ *
+ * Read-only.
+ * The SVGA device may choose to put a limit on the total number
+ * of SVGAGuestMemDescriptor structures it will read when defining
+ * a single GMR.
+ *
+ * The descriptor structure is an array of SVGAGuestMemDescriptor
+ * structures. Each structure may do one of three things:
+ *
+ * - Terminate the GMR descriptor list.
+ * (ppn==0, numPages==0)
+ *
+ * - Add a PPN or range of PPNs to the GMR's virtual address space.
+ * (ppn != 0, numPages != 0)
+ *
+ * - Provide the PPN of the next SVGAGuestMemDescriptor, in order to
+ * support multi-page GMR descriptor tables without forcing the
+ * driver to allocate physically contiguous memory.
+ * (ppn != 0, numPages == 0)
+ *
+ * Note that each physical page of SVGAGuestMemDescriptor structures
+ * can describe at least 2MB of guest memory. If the driver needs to
+ * use more than one page of descriptor structures, it must use one of
+ * its SVGAGuestMemDescriptors to point to an additional page. The
+ * device will never automatically cross a page boundary.
+ *
+ * Once the driver has described a GMR, it is immediately available
+ * for use via any FIFO command that uses an SVGAGuestPtr structure.
+ * These pointers include a GMR identifier plus an offset into that
+ * GMR.
+ *
+ * The driver must check the SVGA_CAP_GMR bit before using the GMR
+ * registers.
+ */
+
+/*
+ * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer
+ * memory as well. In the future, these IDs could even be used to
+ * allow legacy memory regions to be redefined by the guest as GMRs.
+ *
+ * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA
+ * is being phased out. Please try to use user-defined GMRs whenever
+ * possible.
+ */
+#define SVGA_GMR_NULL ((uint32) -1)
+#define SVGA_GMR_FRAMEBUFFER ((uint32) -2) /* Guest Framebuffer (GFB) */
+
+typedef
+struct SVGAGuestMemDescriptor {
+ uint32 ppn;
+ uint32 numPages;
+} SVGAGuestMemDescriptor;
+
+typedef
+struct SVGAGuestPtr {
+ uint32 gmrId;
+ uint32 offset;
+} SVGAGuestPtr;
+
+
+/*
+ * SVGAGMRImageFormat --
+ *
+ * This is a packed representation of the source 2D image format
+ * for a GMR-to-screen blit. Currently it is defined as an encoding
+ * of the screen's color depth and bits-per-pixel, however, 16 bits
+ * are reserved for future use to identify other encodings (such as
+ * RGBA or higher-precision images).
+ *
+ * Currently supported formats:
+ *
+ * bpp depth Format Name
+ * --- ----- -----------
+ * 32 24 32-bit BGRX
+ * 24 24 24-bit BGR
+ * 16 16 RGB 5-6-5
+ * 16 15 RGB 5-5-5
+ *
+ */
+
+typedef
+struct SVGAGMRImageFormat {
+ union {
+ struct {
+ uint32 bitsPerPixel : 8;
+ uint32 colorDepth : 8;
+ uint32 reserved : 16; /* Must be zero */
+ };
+
+ uint32 value;
+ };
+} SVGAGMRImageFormat;
+
+typedef
+struct SVGAGuestImage {
+ SVGAGuestPtr ptr;
+
+ /*
+ * A note on interpretation of pitch: This value of pitch is the
+ * number of bytes between vertically adjacent image
+ * blocks. Normally this is the number of bytes between the first
+ * pixel of two adjacent scanlines. With compressed textures,
+ * however, this may represent the number of bytes between
+ * compression blocks rather than between rows of pixels.
+ *
+ * XXX: Compressed textures currently must be tightly packed in guest memory.
+ *
+ * If the image is 1-dimensional, pitch is ignored.
+ *
+ * If 'pitch' is zero, the SVGA3D device calculates a pitch value
+ * assuming each row of blocks is tightly packed.
+ */
+ uint32 pitch;
+} SVGAGuestImage;
+
+/*
+ * SVGAColorBGRX --
+ *
+ * A 24-bit color format (BGRX), which does not depend on the
+ * format of the legacy guest framebuffer (GFB) or the current
+ * GMRFB state.
+ */
+
+typedef
+struct SVGAColorBGRX {
+ union {
+ struct {
+ uint32 b : 8;
+ uint32 g : 8;
+ uint32 r : 8;
+ uint32 x : 8; /* Unused */
+ };
+
+ uint32 value;
+ };
+} SVGAColorBGRX;
+
+
+/*
+ * SVGASignedRect --
+ * SVGASignedPoint --
+ *
+ * Signed rectangle and point primitives. These are used by the new
+ * 2D primitives for drawing to Screen Objects, which can occupy a
+ * signed virtual coordinate space.
+ *
+ * SVGASignedRect specifies a half-open interval: the (left, top)
+ * pixel is part of the rectangle, but the (right, bottom) pixel is
+ * not.
+ */
+
+typedef
+struct SVGASignedRect {
+ int32 left;
+ int32 top;
+ int32 right;
+ int32 bottom;
+} SVGASignedRect;
+
+typedef
+struct SVGASignedPoint {
+ int32 x;
+ int32 y;
+} SVGASignedPoint;
+
+
+/*
+ * Capabilities
+ *
+ * Note the holes in the bitfield. Missing bits have been deprecated,
+ * and must not be reused. Those capabilities will never be reported
+ * by new versions of the SVGA device.
+ *
+ * SVGA_CAP_GMR2 --
+ * Provides asynchronous commands to define and remap guest memory
+ * regions. Adds device registers SVGA_REG_GMRS_MAX_PAGES and
+ * SVGA_REG_MEMORY_SIZE.
+ *
+ * SVGA_CAP_SCREEN_OBJECT_2 --
+ * Allow screen object support, and require backing stores from the
+ * guest for each screen object.
+ */
+
+#define SVGA_CAP_NONE 0x00000000
+#define SVGA_CAP_RECT_COPY 0x00000002
+#define SVGA_CAP_CURSOR 0x00000020
+#define SVGA_CAP_CURSOR_BYPASS 0x00000040 /* Legacy (Use Cursor Bypass 3 instead) */
+#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080 /* Legacy (Use Cursor Bypass 3 instead) */
+#define SVGA_CAP_8BIT_EMULATION 0x00000100
+#define SVGA_CAP_ALPHA_CURSOR 0x00000200
+#define SVGA_CAP_3D 0x00004000
+#define SVGA_CAP_EXTENDED_FIFO 0x00008000
+#define SVGA_CAP_MULTIMON 0x00010000 /* Legacy multi-monitor support */
+#define SVGA_CAP_PITCHLOCK 0x00020000
+#define SVGA_CAP_IRQMASK 0x00040000
+#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000 /* Legacy multi-monitor support */
+#define SVGA_CAP_GMR 0x00100000
+#define SVGA_CAP_TRACES 0x00200000
+#define SVGA_CAP_GMR2 0x00400000
+#define SVGA_CAP_SCREEN_OBJECT_2 0x00800000
+
+
+/*
+ * FIFO register indices.
+ *
+ * The FIFO is a chunk of device memory mapped into guest physmem. It
+ * is always treated as 32-bit words.
+ *
+ * The guest driver gets to decide how to partition it between
+ * - FIFO registers (there are always at least 4, specifying where the
+ * following data area is and how much data it contains; there may be
+ * more registers following these, depending on the FIFO protocol
+ * version in use)
+ * - FIFO data, written by the guest and slurped out by the VMX.
+ * These indices are 32-bit word offsets into the FIFO.
+ */
+
+enum {
+ /*
+ * Block 1 (basic registers): The originally defined FIFO registers.
+ * These exist and are valid for all versions of the FIFO protocol.
+ */
+
+ SVGA_FIFO_MIN = 0,
+ SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */
+ SVGA_FIFO_NEXT_CMD,
+ SVGA_FIFO_STOP,
+
+ /*
+ * Block 2 (extended registers): Mandatory registers for the extended
+ * FIFO. These exist if the SVGA caps register includes
+ * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their
+ * associated capability bit is enabled.
+ *
+ * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied
+ * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE.
+ * This means that the guest has to test individually (in most cases
+ * using FIFO caps) for the presence of registers after this; the VMX
+ * can define "extended FIFO" to mean whatever it wants, and currently
+ * won't enable it unless there's room for that set and much more.
+ */
+
+ SVGA_FIFO_CAPABILITIES = 4,
+ SVGA_FIFO_FLAGS,
+ /* Valid with SVGA_FIFO_CAP_FENCE: */
+ SVGA_FIFO_FENCE,
+
+ /*
+ * Block 3a (optional extended registers): Additional registers for the
+ * extended FIFO, whose presence isn't actually implied by
+ * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to
+ * leave room for them.
+ *
+ * These in block 3a, the VMX currently considers mandatory for the
+ * extended FIFO.
+ */
+
+ /* Valid if exists (i.e. if extended FIFO enabled): */
+ SVGA_FIFO_3D_HWVERSION, /* See SVGA3dHardwareVersion in svga3d_reg.h */
+ /* Valid with SVGA_FIFO_CAP_PITCHLOCK: */
+ SVGA_FIFO_PITCHLOCK,
+
+ /* Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3: */
+ SVGA_FIFO_CURSOR_ON, /* Cursor bypass 3 show/hide register */
+ SVGA_FIFO_CURSOR_X, /* Cursor bypass 3 x register */
+ SVGA_FIFO_CURSOR_Y, /* Cursor bypass 3 y register */
+ SVGA_FIFO_CURSOR_COUNT, /* Incremented when any of the other 3 change */
+ SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */
+
+ /* Valid with SVGA_FIFO_CAP_RESERVE: */
+ SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */
+
+ /*
+ * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2:
+ *
+ * By default this is SVGA_ID_INVALID, to indicate that the cursor
+ * coordinates are specified relative to the virtual root. If this
+ * is set to a specific screen ID, cursor position is reinterpreted
+ * as a signed offset relative to that screen's origin.
+ */
+ SVGA_FIFO_CURSOR_SCREEN_ID,
+
+ /*
+ * Valid with SVGA_FIFO_CAP_DEAD
+ *
+ * An arbitrary value written by the host, drivers should not use it.
+ */
+ SVGA_FIFO_DEAD,
+
+ /*
+ * Valid with SVGA_FIFO_CAP_3D_HWVERSION_REVISED:
+ *
+ * Contains 3D HWVERSION (see SVGA3dHardwareVersion in svga3d_reg.h)
+ * on platforms that can enforce graphics resource limits.
+ */
+ SVGA_FIFO_3D_HWVERSION_REVISED,
+
+ /*
+ * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new
+ * registers, but this must be done carefully and with judicious use of
+ * capability bits, since comparisons based on SVGA_FIFO_MIN aren't
+ * enough to tell you whether the register exists: we've shipped drivers
+ * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of
+ * the earlier ones. The actual order of introduction was:
+ * - PITCHLOCK
+ * - 3D_CAPS
+ * - CURSOR_* (cursor bypass 3)
+ * - RESERVED
+ * So, code that wants to know whether it can use any of the
+ * aforementioned registers, or anything else added after PITCHLOCK and
+ * before 3D_CAPS, needs to reason about something other than
+ * SVGA_FIFO_MIN.
+ */
+
+ /*
+ * 3D caps block space; valid with 3D hardware version >=
+ * SVGA3D_HWVERSION_WS6_B1.
+ */
+ SVGA_FIFO_3D_CAPS = 32,
+ SVGA_FIFO_3D_CAPS_LAST = 32 + 255,
+
+ /*
+ * End of VMX's current definition of "extended-FIFO registers".
+ * Registers before here are always enabled/disabled as a block; either
+ * the extended FIFO is enabled and includes all preceding registers, or
+ * it's disabled entirely.
+ *
+ * Block 3b (truly optional extended registers): Additional registers for
+ * the extended FIFO, which the VMX already knows how to enable and
+ * disable with correct granularity.
+ *
+ * Registers after here exist if and only if the guest SVGA driver
+ * sets SVGA_FIFO_MIN high enough to leave room for them.
+ */
+
+ /* Valid if register exists: */
+ SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */
+ SVGA_FIFO_FENCE_GOAL, /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */
+ SVGA_FIFO_BUSY, /* See "FIFO Synchronization Registers" */
+
+ /*
+ * Always keep this last. This defines the maximum number of
+ * registers we know about. At power-on, this value is placed in
+ * the SVGA_REG_MEM_REGS register, and we expect the guest driver
+ * to allocate this much space in FIFO memory for registers.
+ */
+ SVGA_FIFO_NUM_REGS
+};
+
+
+/*
+ * Definition of registers included in extended FIFO support.
+ *
+ * The guest SVGA driver gets to allocate the FIFO between registers
+ * and data. It must always allocate at least 4 registers, but old
+ * drivers stopped there.
+ *
+ * The VMX will enable extended FIFO support if and only if the guest
+ * left enough room for all registers defined as part of the mandatory
+ * set for the extended FIFO.
+ *
+ * Note that the guest drivers typically allocate the FIFO only at
+ * initialization time, not at mode switches, so it's likely that the
+ * number of FIFO registers won't change without a reboot.
+ *
+ * All registers less than this value are guaranteed to be present if
+ * svgaUser->fifo.extended is set. Any later registers must be tested
+ * individually for compatibility at each use (in the VMX).
+ *
+ * This value is used only by the VMX, so it can change without
+ * affecting driver compatibility; keep it that way?
+ */
+#define SVGA_FIFO_EXTENDED_MANDATORY_REGS (SVGA_FIFO_3D_CAPS_LAST + 1)
+
+
+/*
+ * FIFO Synchronization Registers
+ *
+ * This explains the relationship between the various FIFO
+ * sync-related registers in IOSpace and in FIFO space.
+ *
+ * SVGA_REG_SYNC --
+ *
+ * The SYNC register can be used in two different ways by the guest:
+ *
+ * 1. If the guest wishes to fully sync (drain) the FIFO,
+ * it will write once to SYNC then poll on the BUSY
+ * register. The FIFO is sync'ed once BUSY is zero.
+ *
+ * 2. If the guest wants to asynchronously wake up the host,
+ * it will write once to SYNC without polling on BUSY.
+ * Ideally it will do this after some new commands have
+ * been placed in the FIFO, and after reading a zero
+ * from SVGA_FIFO_BUSY.
+ *
+ * (1) is the original behaviour that SYNC was designed to
+ * support. Originally, a write to SYNC would implicitly
+ * trigger a read from BUSY. This causes us to synchronously
+ * process the FIFO.
+ *
+ * This behaviour has since been changed so that writing SYNC
+ * will *not* implicitly cause a read from BUSY. Instead, it
+ * makes a channel call which asynchronously wakes up the MKS
+ * thread.
+ *
+ * New guests can use this new behaviour to implement (2)
+ * efficiently. This lets guests get the host's attention
+ * without waiting for the MKS to poll, which gives us much
+ * better CPU utilization on SMP hosts and on UP hosts while
+ * we're blocked on the host GPU.
+ *
+ * Old guests shouldn't notice the behaviour change. SYNC was
+ * never guaranteed to process the entire FIFO, since it was
+ * bounded to a particular number of CPU cycles. Old guests will
+ * still loop on the BUSY register until the FIFO is empty.
+ *
+ * Writing to SYNC currently has the following side-effects:
+ *
+ * - Sets SVGA_REG_BUSY to TRUE (in the monitor)
+ * - Asynchronously wakes up the MKS thread for FIFO processing
+ * - The value written to SYNC is recorded as a "reason", for
+ * stats purposes.
+ *
+ * If SVGA_FIFO_BUSY is available, drivers are advised to only
+ * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set
+ * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will
+ * eventually set SVGA_FIFO_BUSY on its own, but this approach
+ * lets the driver avoid sending multiple asynchronous wakeup
+ * messages to the MKS thread.
+ *
+ * SVGA_REG_BUSY --
+ *
+ * This register is set to TRUE when SVGA_REG_SYNC is written,
+ * and it reads as FALSE when the FIFO has been completely
+ * drained.
+ *
+ * Every read from this register causes us to synchronously
+ * process FIFO commands. There is no guarantee as to how many
+ * commands each read will process.
+ *
+ * CPU time spent processing FIFO commands will be billed to
+ * the guest.
+ *
+ * New drivers should avoid using this register unless they
+ * need to guarantee that the FIFO is completely drained. It
+ * is overkill for performing a sync-to-fence. Older drivers
+ * will use this register for any type of synchronization.
+ *
+ * SVGA_FIFO_BUSY --
+ *
+ * This register is a fast way for the guest driver to check
+ * whether the FIFO is already being processed. It reads and
+ * writes at normal RAM speeds, with no monitor intervention.
+ *
+ * If this register reads as TRUE, the host is guaranteeing that
+ * any new commands written into the FIFO will be noticed before
+ * the MKS goes back to sleep.
+ *
+ * If this register reads as FALSE, no such guarantee can be
+ * made.
+ *
+ * The guest should use this register to quickly determine
+ * whether or not it needs to wake up the host. If the guest
+ * just wrote a command or group of commands that it would like
+ * the host to begin processing, it should:
+ *
+ * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further
+ * action is necessary.
+ *
+ * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest
+ * code that we've already sent a SYNC to the host and we
+ * don't need to send a duplicate.
+ *
+ * 3. Write a reason to SVGA_REG_SYNC. This will send an
+ * asynchronous wakeup to the MKS thread.
+ */
+
+
+/*
+ * FIFO Capabilities
+ *
+ * Fence -- Fence register and command are supported
+ * Accel Front -- Front buffer only commands are supported
+ * Pitch Lock -- Pitch lock register is supported
+ * Video -- SVGA Video overlay units are supported
+ * Escape -- Escape command is supported
+ *
+ * XXX: Add longer descriptions for each capability, including a list
+ * of the new features that each capability provides.
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT --
+ *
+ * Provides dynamic multi-screen rendering, for improved Unity and
+ * multi-monitor modes. With Screen Object, the guest can
+ * dynamically create and destroy 'screens', which can represent
+ * Unity windows or virtual monitors. Screen Object also provides
+ * strong guarantees that DMA operations happen only when
+ * guest-initiated. Screen Object deprecates the BAR1 guest
+ * framebuffer (GFB) and all commands that work only with the GFB.
+ *
+ * New registers:
+ * FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID
+ *
+ * New 2D commands:
+ * DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN,
+ * BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY
+ *
+ * New 3D commands:
+ * BLIT_SURFACE_TO_SCREEN
+ *
+ * New guarantees:
+ *
+ * - The host will not read or write guest memory, including the GFB,
+ * except when explicitly initiated by a DMA command.
+ *
+ * - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK,
+ * is guaranteed to complete before any subsequent FENCEs.
+ *
+ * - All legacy commands which affect a Screen (UPDATE, PRESENT,
+ * PRESENT_READBACK) as well as new Screen blit commands will
+ * all behave consistently as blits, and memory will be read
+ * or written in FIFO order.
+ *
+ * For example, if you PRESENT from one SVGA3D surface to multiple
+ * places on the screen, the data copied will always be from the
+ * SVGA3D surface at the time the PRESENT was issued in the FIFO.
+ * This was not necessarily true on devices without Screen Object.
+ *
+ * This means that on devices that support Screen Object, the
+ * PRESENT_READBACK command should not be necessary unless you
+ * actually want to read back the results of 3D rendering into
+ * system memory. (And for that, the BLIT_SCREEN_TO_GMRFB
+ * command provides a strict superset of functionality.)
+ *
+ * - When a screen is resized, either using Screen Object commands or
+ * legacy multimon registers, its contents are preserved.
+ *
+ * SVGA_FIFO_CAP_GMR2 --
+ *
+ * Provides new commands to define and remap guest memory regions (GMR).
+ *
+ * New 2D commands:
+ * DEFINE_GMR2, REMAP_GMR2.
+ *
+ * SVGA_FIFO_CAP_3D_HWVERSION_REVISED --
+ *
+ * Indicates new register SVGA_FIFO_3D_HWVERSION_REVISED exists.
+ * This register may replace SVGA_FIFO_3D_HWVERSION on platforms
+ * that enforce graphics resource limits. This allows the platform
+ * to clear SVGA_FIFO_3D_HWVERSION and disable 3D in legacy guest
+ * drivers that do not limit their resources.
+ *
+ * Note this is an alias to SVGA_FIFO_CAP_GMR2 because these indicators
+ * are codependent (and thus we use a single capability bit).
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT_2 --
+ *
+ * Modifies the DEFINE_SCREEN command to include a guest provided
+ * backing store in GMR memory and the bytesPerLine for the backing
+ * store. This capability requires the use of a backing store when
+ * creating screen objects. However if SVGA_FIFO_CAP_SCREEN_OBJECT
+ * is present then backing stores are optional.
+ *
+ * SVGA_FIFO_CAP_DEAD --
+ *
+ * Drivers should not use this cap bit. This cap bit can not be
+ * reused since some hosts already expose it.
+ */
+
+#define SVGA_FIFO_CAP_NONE 0
+#define SVGA_FIFO_CAP_FENCE (1<<0)
+#define SVGA_FIFO_CAP_ACCELFRONT (1<<1)
+#define SVGA_FIFO_CAP_PITCHLOCK (1<<2)
+#define SVGA_FIFO_CAP_VIDEO (1<<3)
+#define SVGA_FIFO_CAP_CURSOR_BYPASS_3 (1<<4)
+#define SVGA_FIFO_CAP_ESCAPE (1<<5)
+#define SVGA_FIFO_CAP_RESERVE (1<<6)
+#define SVGA_FIFO_CAP_SCREEN_OBJECT (1<<7)
+#define SVGA_FIFO_CAP_GMR2 (1<<8)
+#define SVGA_FIFO_CAP_3D_HWVERSION_REVISED SVGA_FIFO_CAP_GMR2
+#define SVGA_FIFO_CAP_SCREEN_OBJECT_2 (1<<9)
+#define SVGA_FIFO_CAP_DEAD (1<<10)
+
+
+/*
+ * FIFO Flags
+ *
+ * Accel Front -- Driver should use front buffer only commands
+ */
+
+#define SVGA_FIFO_FLAG_NONE 0
+#define SVGA_FIFO_FLAG_ACCELFRONT (1<<0)
+#define SVGA_FIFO_FLAG_RESERVED (1<<31) /* Internal use only */
+
+/*
+ * FIFO reservation sentinel value
+ */
+
+#define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff
+
+
+/*
+ * Video overlay support
+ */
+
+#define SVGA_NUM_OVERLAY_UNITS 32
+
+
+/*
+ * Video capabilities that the guest is currently using
+ */
+
+#define SVGA_VIDEO_FLAG_COLORKEY 0x0001
+
+
+/*
+ * Offsets for the video overlay registers
+ */
+
+enum {
+ SVGA_VIDEO_ENABLED = 0,
+ SVGA_VIDEO_FLAGS,
+ SVGA_VIDEO_DATA_OFFSET,
+ SVGA_VIDEO_FORMAT,
+ SVGA_VIDEO_COLORKEY,
+ SVGA_VIDEO_SIZE, /* Deprecated */
+ SVGA_VIDEO_WIDTH,
+ SVGA_VIDEO_HEIGHT,
+ SVGA_VIDEO_SRC_X,
+ SVGA_VIDEO_SRC_Y,
+ SVGA_VIDEO_SRC_WIDTH,
+ SVGA_VIDEO_SRC_HEIGHT,
+ SVGA_VIDEO_DST_X, /* Signed int32 */
+ SVGA_VIDEO_DST_Y, /* Signed int32 */
+ SVGA_VIDEO_DST_WIDTH,
+ SVGA_VIDEO_DST_HEIGHT,
+ SVGA_VIDEO_PITCH_1,
+ SVGA_VIDEO_PITCH_2,
+ SVGA_VIDEO_PITCH_3,
+ SVGA_VIDEO_DATA_GMRID, /* Optional, defaults to SVGA_GMR_FRAMEBUFFER */
+ SVGA_VIDEO_DST_SCREEN_ID, /* Optional, defaults to virtual coords (SVGA_ID_INVALID) */
+ SVGA_VIDEO_NUM_REGS
+};
+
+
+/*
+ * SVGA Overlay Units
+ *
+ * width and height relate to the entire source video frame.
+ * srcX, srcY, srcWidth and srcHeight represent subset of the source
+ * video frame to be displayed.
+ */
+
+typedef struct SVGAOverlayUnit {
+ uint32 enabled;
+ uint32 flags;
+ uint32 dataOffset;
+ uint32 format;
+ uint32 colorKey;
+ uint32 size;
+ uint32 width;
+ uint32 height;
+ uint32 srcX;
+ uint32 srcY;
+ uint32 srcWidth;
+ uint32 srcHeight;
+ int32 dstX;
+ int32 dstY;
+ uint32 dstWidth;
+ uint32 dstHeight;
+ uint32 pitches[3];
+ uint32 dataGMRId;
+ uint32 dstScreenId;
+} SVGAOverlayUnit;
+
+
+/*
+ * SVGAScreenObject --
+ *
+ * This is a new way to represent a guest's multi-monitor screen or
+ * Unity window. Screen objects are only supported if the
+ * SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set.
+ *
+ * If Screen Objects are supported, they can be used to fully
+ * replace the functionality provided by the framebuffer registers
+ * (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY.
+ *
+ * The screen object is a struct with guaranteed binary
+ * compatibility. New flags can be added, and the struct may grow,
+ * but existing fields must retain their meaning.
+ *
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2 are required fields of
+ * a SVGAGuestPtr that is used to back the screen contents. This
+ * memory must come from the GFB. The guest is not allowed to
+ * access the memory and doing so will have undefined results. The
+ * backing store is required to be page aligned and the size is
+ * padded to the next page boundry. The number of pages is:
+ * (bytesPerLine * size.width * 4 + PAGE_SIZE - 1) / PAGE_SIZE
+ *
+ * The pitch in the backingStore is required to be at least large
+ * enough to hold a 32bbp scanline. It is recommended that the
+ * driver pad bytesPerLine for a potential performance win.
+ *
+ * The cloneCount field is treated as a hint from the guest that
+ * the user wants this display to be cloned, countCount times. A
+ * value of zero means no cloning should happen.
+ */
+
+#define SVGA_SCREEN_MUST_BE_SET (1 << 0) /* Must be set or results undefined */
+#define SVGA_SCREEN_HAS_ROOT SVGA_SCREEN_MUST_BE_SET /* Deprecated */
+#define SVGA_SCREEN_IS_PRIMARY (1 << 1) /* Guest considers this screen to be 'primary' */
+#define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2) /* Guest is running a fullscreen app here */
+
+/*
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When the screen is
+ * deactivated the base layer is defined to lose all contents and
+ * become black. When a screen is deactivated the backing store is
+ * optional. When set backingPtr and bytesPerLine will be ignored.
+ */
+#define SVGA_SCREEN_DEACTIVATE (1 << 3)
+
+/*
+ * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When this flag is set
+ * the screen contents will be outputted as all black to the user
+ * though the base layer contents is preserved. The screen base layer
+ * can still be read and written to like normal though the no visible
+ * effect will be seen by the user. When the flag is changed the
+ * screen will be blanked or redrawn to the current contents as needed
+ * without any extra commands from the driver. This flag only has an
+ * effect when the screen is not deactivated.
+ */
+#define SVGA_SCREEN_BLANKING (1 << 4)
+
+typedef
+struct SVGAScreenObject {
+ uint32 structSize; /* sizeof(SVGAScreenObject) */
+ uint32 id;
+ uint32 flags;
+ struct {
+ uint32 width;
+ uint32 height;
+ } size;
+ struct {
+ int32 x;
+ int32 y;
+ } root;
+
+ /*
+ * Added and required by SVGA_FIFO_CAP_SCREEN_OBJECT_2, optional
+ * with SVGA_FIFO_CAP_SCREEN_OBJECT.
+ */
+ SVGAGuestImage backingStore;
+ uint32 cloneCount;
+} SVGAScreenObject;
+
+
+/*
+ * Commands in the command FIFO:
+ *
+ * Command IDs defined below are used for the traditional 2D FIFO
+ * communication (not all commands are available for all versions of the
+ * SVGA FIFO protocol).
+ *
+ * Note the holes in the command ID numbers: These commands have been
+ * deprecated, and the old IDs must not be reused.
+ *
+ * Command IDs from 1000 to 1999 are reserved for use by the SVGA3D
+ * protocol.
+ *
+ * Each command's parameters are described by the comments and
+ * structs below.
+ */
+
+typedef enum {
+ SVGA_CMD_INVALID_CMD = 0,
+ SVGA_CMD_UPDATE = 1,
+ SVGA_CMD_RECT_COPY = 3,
+ SVGA_CMD_DEFINE_CURSOR = 19,
+ SVGA_CMD_DEFINE_ALPHA_CURSOR = 22,
+ SVGA_CMD_UPDATE_VERBOSE = 25,
+ SVGA_CMD_FRONT_ROP_FILL = 29,
+ SVGA_CMD_FENCE = 30,
+ SVGA_CMD_ESCAPE = 33,
+ SVGA_CMD_DEFINE_SCREEN = 34,
+ SVGA_CMD_DESTROY_SCREEN = 35,
+ SVGA_CMD_DEFINE_GMRFB = 36,
+ SVGA_CMD_BLIT_GMRFB_TO_SCREEN = 37,
+ SVGA_CMD_BLIT_SCREEN_TO_GMRFB = 38,
+ SVGA_CMD_ANNOTATION_FILL = 39,
+ SVGA_CMD_ANNOTATION_COPY = 40,
+ SVGA_CMD_DEFINE_GMR2 = 41,
+ SVGA_CMD_REMAP_GMR2 = 42,
+ SVGA_CMD_MAX
+} SVGAFifoCmdId;
+
+#define SVGA_CMD_MAX_ARGS 64
+
+
+/*
+ * SVGA_CMD_UPDATE --
+ *
+ * This is a DMA transfer which copies from the Guest Framebuffer
+ * (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which
+ * intersect with the provided virtual rectangle.
+ *
+ * This command does not support using arbitrary guest memory as a
+ * data source- it only works with the pre-defined GFB memory.
+ * This command also does not support signed virtual coordinates.
+ * If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with
+ * negative root x/y coordinates, the negative portion of those
+ * screens will not be reachable by this command.
+ *
+ * This command is not necessary when using framebuffer
+ * traces. Traces are automatically enabled if the SVGA FIFO is
+ * disabled, and you may explicitly enable/disable traces using
+ * SVGA_REG_TRACES. With traces enabled, any write to the GFB will
+ * automatically act as if a subsequent SVGA_CMD_UPDATE was issued.
+ *
+ * Traces and SVGA_CMD_UPDATE are the only supported ways to render
+ * pseudocolor screen updates. The newer Screen Object commands
+ * only support true color formats.
+ *
+ * Availability:
+ * Always available.
+ */
+
+typedef
+struct SVGAFifoCmdUpdate {
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+} SVGAFifoCmdUpdate;
+
+
+/*
+ * SVGA_CMD_RECT_COPY --
+ *
+ * Perform a rectangular DMA transfer from one area of the GFB to
+ * another, and copy the result to any screens which intersect it.
+ *
+ * Availability:
+ * SVGA_CAP_RECT_COPY
+ */
+
+typedef
+struct SVGAFifoCmdRectCopy {
+ uint32 srcX;
+ uint32 srcY;
+ uint32 destX;
+ uint32 destY;
+ uint32 width;
+ uint32 height;
+} SVGAFifoCmdRectCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_CURSOR --
+ *
+ * Provide a new cursor image, as an AND/XOR mask.
+ *
+ * The recommended way to position the cursor overlay is by using
+ * the SVGA_FIFO_CURSOR_* registers, supported by the
+ * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ * SVGA_CAP_CURSOR
+ */
+
+typedef
+struct SVGAFifoCmdDefineCursor {
+ uint32 id; /* Reserved, must be zero. */
+ uint32 hotspotX;
+ uint32 hotspotY;
+ uint32 width;
+ uint32 height;
+ uint32 andMaskDepth; /* Value must be 1 or equal to BITS_PER_PIXEL */
+ uint32 xorMaskDepth; /* Value must be 1 or equal to BITS_PER_PIXEL */
+ /*
+ * Followed by scanline data for AND mask, then XOR mask.
+ * Each scanline is padded to a 32-bit boundary.
+ */
+} SVGAFifoCmdDefineCursor;
+
+
+/*
+ * SVGA_CMD_DEFINE_ALPHA_CURSOR --
+ *
+ * Provide a new cursor image, in 32-bit BGRA format.
+ *
+ * The recommended way to position the cursor overlay is by using
+ * the SVGA_FIFO_CURSOR_* registers, supported by the
+ * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ * SVGA_CAP_ALPHA_CURSOR
+ */
+
+typedef
+struct SVGAFifoCmdDefineAlphaCursor {
+ uint32 id; /* Reserved, must be zero. */
+ uint32 hotspotX;
+ uint32 hotspotY;
+ uint32 width;
+ uint32 height;
+ /* Followed by scanline data */
+} SVGAFifoCmdDefineAlphaCursor;
+
+
+/*
+ * SVGA_CMD_UPDATE_VERBOSE --
+ *
+ * Just like SVGA_CMD_UPDATE, but also provide a per-rectangle
+ * 'reason' value, an opaque cookie which is used by internal
+ * debugging tools. Third party drivers should not use this
+ * command.
+ *
+ * Availability:
+ * SVGA_CAP_EXTENDED_FIFO
+ */
+
+typedef
+struct SVGAFifoCmdUpdateVerbose {
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 reason;
+} SVGAFifoCmdUpdateVerbose;
+
+
+/*
+ * SVGA_CMD_FRONT_ROP_FILL --
+ *
+ * This is a hint which tells the SVGA device that the driver has
+ * just filled a rectangular region of the GFB with a solid
+ * color. Instead of reading these pixels from the GFB, the device
+ * can assume that they all equal 'color'. This is primarily used
+ * for remote desktop protocols.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_ACCELFRONT
+ */
+
+#define SVGA_ROP_COPY 0x03
+
+#define SVGA_INVALID_DISPLAY_ID ((uint32)-1)
+
+typedef
+struct SVGAFifoCmdFrontRopFill {
+ uint32 color; /* In the same format as the GFB */
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 rop; /* Must be SVGA_ROP_COPY */
+} SVGAFifoCmdFrontRopFill;
+
+
+/*
+ * SVGA_CMD_FENCE --
+ *
+ * Insert a synchronization fence. When the SVGA device reaches
+ * this command, it will copy the 'fence' value into the
+ * SVGA_FIFO_FENCE register. It will also compare the fence against
+ * SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the
+ * SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will
+ * raise this interrupt.
+ *
+ * Availability:
+ * SVGA_FIFO_FENCE for this command,
+ * SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL.
+ */
+
+typedef
+struct {
+ uint32 fence;
+} SVGAFifoCmdFence;
+
+
+/*
+ * SVGA_CMD_ESCAPE --
+ *
+ * Send an extended or vendor-specific variable length command.
+ * This is used for video overlay, third party plugins, and
+ * internal debugging tools. See svga_escape.h
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_ESCAPE
+ */
+
+typedef
+struct SVGAFifoCmdEscape {
+ uint32 nsid;
+ uint32 size;
+ /* followed by 'size' bytes of data */
+} SVGAFifoCmdEscape;
+
+
+/*
+ * SVGA_CMD_DEFINE_SCREEN --
+ *
+ * Define or redefine an SVGAScreenObject. See the description of
+ * SVGAScreenObject above. The video driver is responsible for
+ * generating new screen IDs. They should be small positive
+ * integers. The virtual device will have an implementation
+ * specific upper limit on the number of screen IDs
+ * supported. Drivers are responsible for recycling IDs. The first
+ * valid ID is zero.
+ *
+ * - Interaction with other registers:
+ *
+ * For backwards compatibility, when the GFB mode registers (WIDTH,
+ * HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device
+ * deletes all screens other than screen #0, and redefines screen
+ * #0 according to the specified mode. Drivers that use
+ * SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0.
+ *
+ * If you use screen objects, do not use the legacy multi-mon
+ * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*).
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAScreenObject screen; /* Variable-length according to version */
+} SVGAFifoCmdDefineScreen;
+
+
+/*
+ * SVGA_CMD_DESTROY_SCREEN --
+ *
+ * Destroy an SVGAScreenObject. Its ID is immediately available for
+ * re-use.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ uint32 screenId;
+} SVGAFifoCmdDestroyScreen;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMRFB --
+ *
+ * This command sets a piece of SVGA device state called the
+ * Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a
+ * piece of light-weight state which identifies the location and
+ * format of an image in guest memory or in BAR1. The GMRFB has
+ * an arbitrary size, and it doesn't need to match the geometry
+ * of the GFB or any screen object.
+ *
+ * The GMRFB can be redefined as often as you like. You could
+ * always use the same GMRFB, you could redefine it before
+ * rendering from a different guest screen, or you could even
+ * redefine it before every blit.
+ *
+ * There are multiple ways to use this command. The simplest way is
+ * to use it to move the framebuffer either to elsewhere in the GFB
+ * (BAR1) memory region, or to a user-defined GMR. This lets a
+ * driver use a framebuffer allocated entirely out of normal system
+ * memory, which we encourage.
+ *
+ * Another way to use this command is to set up a ring buffer of
+ * updates in GFB memory. If a driver wants to ensure that no
+ * frames are skipped by the SVGA device, it is important that the
+ * driver not modify the source data for a blit until the device is
+ * done processing the command. One efficient way to accomplish
+ * this is to use a ring of small DMA buffers. Each buffer is used
+ * for one blit, then we move on to the next buffer in the
+ * ring. The FENCE mechanism is used to protect each buffer from
+ * re-use until the device is finished with that buffer's
+ * corresponding blit.
+ *
+ * This command does not affect the meaning of SVGA_CMD_UPDATE.
+ * UPDATEs always occur from the legacy GFB memory area. This
+ * command has no support for pseudocolor GMRFBs. Currently only
+ * true-color 15, 16, and 24-bit depths are supported. Future
+ * devices may expose capabilities for additional framebuffer
+ * formats.
+ *
+ * The default GMRFB value is undefined. Drivers must always send
+ * this command at least once before performing any blit from the
+ * GMRFB.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAGuestPtr ptr;
+ uint32 bytesPerLine;
+ SVGAGMRImageFormat format;
+} SVGAFifoCmdDefineGMRFB;
+
+
+/*
+ * SVGA_CMD_BLIT_GMRFB_TO_SCREEN --
+ *
+ * This is a guest-to-host blit. It performs a DMA operation to
+ * copy a rectangular region of pixels from the current GMRFB to
+ * one or more Screen Objects.
+ *
+ * The destination coordinate may be specified relative to a
+ * screen's origin (if a screen ID is specified) or relative to the
+ * virtual coordinate system's origin (if the screen ID is
+ * SVGA_ID_INVALID). The actual destination may span zero or more
+ * screens, in the case of a virtual destination rect or a rect
+ * which extends off the edge of the specified screen.
+ *
+ * This command writes to the screen's "base layer": the underlying
+ * framebuffer which exists below any cursor or video overlays. No
+ * action is necessary to explicitly hide or update any overlays
+ * which exist on top of the updated region.
+ *
+ * The SVGA device is guaranteed to finish reading from the GMRFB
+ * by the time any subsequent FENCE commands are reached.
+ *
+ * This command consumes an annotation. See the
+ * SVGA_CMD_ANNOTATION_* commands for details.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint srcOrigin;
+ SVGASignedRect destRect;
+ uint32 destScreenId;
+} SVGAFifoCmdBlitGMRFBToScreen;
+
+
+/*
+ * SVGA_CMD_BLIT_SCREEN_TO_GMRFB --
+ *
+ * This is a host-to-guest blit. It performs a DMA operation to
+ * copy a rectangular region of pixels from a single Screen Object
+ * back to the current GMRFB.
+ *
+ * Usage note: This command should be used rarely. It will
+ * typically be inefficient, but it is necessary for some types of
+ * synchronization between 3D (GPU) and 2D (CPU) rendering into
+ * overlapping areas of a screen.
+ *
+ * The source coordinate is specified relative to a screen's
+ * origin. The provided screen ID must be valid. If any parameters
+ * are invalid, the resulting pixel values are undefined.
+ *
+ * This command reads the screen's "base layer". Overlays like
+ * video and cursor are not included, but any data which was sent
+ * using a blit-to-screen primitive will be available, no matter
+ * whether the data's original source was the GMRFB or the 3D
+ * acceleration hardware.
+ *
+ * Note that our guest-to-host blits and host-to-guest blits aren't
+ * symmetric in their current implementation. While the parameters
+ * are identical, host-to-guest blits are a lot less featureful.
+ * They do not support clipping: If the source parameters don't
+ * fully fit within a screen, the blit fails. They must originate
+ * from exactly one screen. Virtual coordinates are not directly
+ * supported.
+ *
+ * Host-to-guest blits do support the same set of GMRFB formats
+ * offered by guest-to-host blits.
+ *
+ * The SVGA device is guaranteed to finish writing to the GMRFB by
+ * the time any subsequent FENCE commands are reached.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint destOrigin;
+ SVGASignedRect srcRect;
+ uint32 srcScreenId;
+} SVGAFifoCmdBlitScreenToGMRFB;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_FILL --
+ *
+ * This is a blit annotation. This command stores a small piece of
+ * device state which is consumed by the next blit-to-screen
+ * command. The state is only cleared by commands which are
+ * specifically documented as consuming an annotation. Other
+ * commands (such as ESCAPEs for debugging) may intervene between
+ * the annotation and its associated blit.
+ *
+ * This annotation is a promise about the contents of the next
+ * blit: The video driver is guaranteeing that all pixels in that
+ * blit will have the same value, specified here as a color in
+ * SVGAColorBGRX format.
+ *
+ * The SVGA device can still render the blit correctly even if it
+ * ignores this annotation, but the annotation may allow it to
+ * perform the blit more efficiently, for example by ignoring the
+ * source data and performing a fill in hardware.
+ *
+ * This annotation is most important for performance when the
+ * user's display is being remoted over a network connection.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGAColorBGRX color;
+} SVGAFifoCmdAnnotationFill;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_COPY --
+ *
+ * This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more
+ * information about annotations.
+ *
+ * This annotation is a promise about the contents of the next
+ * blit: The video driver is guaranteeing that all pixels in that
+ * blit will have the same value as those which already exist at an
+ * identically-sized region on the same or a different screen.
+ *
+ * Note that the source pixels for the COPY in this annotation are
+ * sampled before applying the anqnotation's associated blit. They
+ * are allowed to overlap with the blit's destination pixels.
+ *
+ * The copy source rectangle is specified the same way as the blit
+ * destination: it can be a rectangle which spans zero or more
+ * screens, specified relative to either a screen or to the virtual
+ * coordinate system's origin. If the source rectangle includes
+ * pixels which are not from exactly one screen, the results are
+ * undefined.
+ *
+ * Availability:
+ * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2
+ */
+
+typedef
+struct {
+ SVGASignedPoint srcOrigin;
+ uint32 srcScreenId;
+} SVGAFifoCmdAnnotationCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMR2 --
+ *
+ * Define guest memory region v2. See the description of GMRs above.
+ *
+ * Availability:
+ * SVGA_CAP_GMR2
+ */
+
+typedef
+struct {
+ uint32 gmrId;
+ uint32 numPages;
+} SVGAFifoCmdDefineGMR2;
+
+
+/*
+ * SVGA_CMD_REMAP_GMR2 --
+ *
+ * Remap guest memory region v2. See the description of GMRs above.
+ *
+ * This command allows guest to modify a portion of an existing GMR by
+ * invalidating it or reassigning it to different guest physical pages.
+ * The pages are identified by physical page number (PPN). The pages
+ * are assumed to be pinned and valid for DMA operations.
+ *
+ * Description of command flags:
+ *
+ * SVGA_REMAP_GMR2_VIA_GMR: If enabled, references a PPN list in a GMR.
+ * The PPN list must not overlap with the remap region (this can be
+ * handled trivially by referencing a separate GMR). If flag is
+ * disabled, PPN list is appended to SVGARemapGMR command.
+ *
+ * SVGA_REMAP_GMR2_PPN64: If set, PPN list is in PPN64 format, otherwise
+ * it is in PPN32 format.
+ *
+ * SVGA_REMAP_GMR2_SINGLE_PPN: If set, PPN list contains a single entry.
+ * A single PPN can be used to invalidate a portion of a GMR or
+ * map it to to a single guest scratch page.
+ *
+ * Availability:
+ * SVGA_CAP_GMR2
+ */
+
+typedef enum {
+ SVGA_REMAP_GMR2_PPN32 = 0,
+ SVGA_REMAP_GMR2_VIA_GMR = (1 << 0),
+ SVGA_REMAP_GMR2_PPN64 = (1 << 1),
+ SVGA_REMAP_GMR2_SINGLE_PPN = (1 << 2),
+} SVGARemapGMR2Flags;
+
+typedef
+struct {
+ uint32 gmrId;
+ SVGARemapGMR2Flags flags;
+ uint32 offsetPages; /* offset in pages to begin remap */
+ uint32 numPages; /* number of pages to remap */
+ /*
+ * Followed by additional data depending on SVGARemapGMR2Flags.
+ *
+ * If flag SVGA_REMAP_GMR2_VIA_GMR is set, single SVGAGuestPtr follows.
+ * Otherwise an array of page descriptors in PPN32 or PPN64 format
+ * (according to flag SVGA_REMAP_GMR2_PPN64) follows. If flag
+ * SVGA_REMAP_GMR2_SINGLE_PPN is set, array contains a single entry.
+ */
+} SVGAFifoCmdRemapGMR2;
+
+#endif
diff --git a/src/svga_struct.h b/src/svga_struct.h
new file mode 100644
index 0000000..fe4f0bf
--- /dev/null
+++ b/src/svga_struct.h
@@ -0,0 +1,40 @@
+/* **********************************************************
+ * Copyright (C) 1998-2000 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+#ifndef _SVGA_STRUCT_H_
+#define _SVGA_STRUCT_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#include "includeCheck.h"
+
+ /*
+ * Offscreen memory surface structure
+ *
+ */
+
+enum SVGASurfaceVersion {
+ SVGA_SURFACE_VERSION_1 = 1 /* Initial version... */
+};
+
+typedef struct _SVGASurface {
+ uint32 size; /* Size of the structure */
+ uint32 version; /* Version of this surface structure. */
+ uint32 bpp; /* Format of the surface */
+ uint32 width; /* Width of the surface */
+ uint32 height; /* Height of the surface */
+ uint32 pitch; /* Pitch of the surface */
+ volatile uint32 numQueued; /* Number of times this bitmap has been queued */
+ volatile uint32 numDequeued; /* Number of times this bitmap has been dequeued */
+ uint32 userData; /* Driver defined data */
+ uint32 dataOffset; /* Offset to the data */
+} SVGASurface;
+
+typedef struct SVGAPoint {
+ int16 x;
+ int16 y;
+} SVGAPoint;
+
+#endif
diff --git a/src/vm_basic_types.h b/src/vm_basic_types.h
new file mode 100644
index 0000000..37272ee
--- /dev/null
+++ b/src/vm_basic_types.h
@@ -0,0 +1,171 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+/*
+ *
+ * vm_basic_types.h --
+ *
+ * basic data types.
+ */
+
+
+#ifndef _VM_BASIC_TYPES_H_
+#define _VM_BASIC_TYPES_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+/* STRICT ANSI means the Xserver build and X defines Bool differently. */
+#if 0
+typedef char Bool;
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifdef _MSC_VER
+typedef unsigned __int64 uint64;
+typedef signed __int64 int64;
+
+#pragma warning (disable :4018) // signed/unsigned mismatch
+#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
+#pragma warning (disable :4305) // truncation from 'const int' to 'short'
+#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
+//#pragma warning (disable :4101) // unreferenced local variable
+#pragma warning (disable :4133) // incompatible types - from 'struct VM *' to 'int *'
+#pragma warning (disable :4047) // differs in levels of indirection
+#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
+#pragma warning (disable :4142) // benign redefinition of type
+
+#elif defined(__GNUC__)
+/* The Xserver source compiles with -ansi -pendantic */
+#ifndef __STRICT_ANSI__
+typedef unsigned long long uint64;
+typedef long long int64;
+#endif
+#else
+/* int64/uint64 aren't actually used in the vmware driver. */
+#if 0
+#error - Need compiler define for int64/uint64
+#endif
+#endif
+
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+
+typedef int int32;
+typedef short int16;
+typedef char int8;
+
+
+/*
+ * Printf format for 64-bit number. Use it like this:
+ * printf("%"FMT64"d\n", big);
+ */
+
+#ifdef _MSC_VER
+#define FMT64 "I64"
+#elif defined(__GNUC__)
+#define FMT64 "L"
+#else
+/* FMT64 isn't actually used in the vmware driver. */
+#if 0
+#error - Need compiler define for FMT64
+#endif
+#endif
+
+typedef uint32 VA;
+typedef uint32 VPN;
+
+typedef uint32 PA;
+typedef uint32 PPN;
+
+typedef uint32 MA;
+typedef uint32 MPN;
+
+#define INVALID_MPN ((MPN)-1)
+
+#define EXTERN extern
+/*
+ * Right now our use of CONST is broken enough that it only works
+ * with GCC. XXX Need to fix this.
+ */
+#ifdef __GNUC__
+#define CONST const
+#else
+#ifndef CONST
+#define CONST
+#endif
+#endif
+
+#ifdef _MSC_VER
+#ifndef INLINE
+#define INLINE __inline
+#endif
+#else
+#ifndef INLINE
+#define INLINE inline
+#endif
+#endif
+
+
+#if defined(WIN32) && !defined(VMX86_NO_THREADS)
+#define THREADSPECIFIC _declspec(thread)
+#else
+#define THREADSPECIFIC
+#endif
+
+/*
+ * Like "INLINE" but use this token to mark functions that are inline
+ * because they have only a single call site. In other words, if a second
+ * call site is introduced, the "INLINE_SINGLE_CALLER" token should be
+ * removed.
+ */
+#define INLINE_SINGLE_CALLER INLINE
+
+/*
+ * Attributes placed on function declarations to tell the compiler
+ * that the function never returns.
+ */
+#ifdef _MSC_VER
+#define NORETURN_DECL(_fndecl) __declspec(noreturn) _fndecl
+#elif defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 5
+#define NORETURN_DECL(_fndecl) _fndecl __attribute__((__noreturn__))
+#else
+#define NORETURN_DECL(_fndecl) _fndecl
+#endif
+
+
+/*
+ * GCC's argument checking for printf-like functions
+ * This is conditional until we have replaced all `"%x", void *'
+ * with `"0x%08x", (uint32) void *'. Note that %p prints different things
+ * on different platforms.
+ *
+ * fmtPos is the position of the format string argument, beginning at 1
+ * varPos is the position of the variable argument, beginning at 1
+ */
+#if defined(__GNUC__) && defined(notdef)
+# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
+#else
+# define PRINTF_DECL(fmtPos, varPos)
+#endif
+
+/*
+ * Used to silence compiler warnings that get generated when the
+ * compiler thinks that a function returns when it is marked noreturn.
+ */
+#define INFINITE_LOOP() do { } while (1)
+
+#endif
diff --git a/src/vm_device_version.h b/src/vm_device_version.h
new file mode 100644
index 0000000..92a5cac
--- /dev/null
+++ b/src/vm_device_version.h
@@ -0,0 +1,62 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+
+#ifndef VM_DEVICE_VERSION_H
+#define VM_DEVICE_VERSION_H
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+#define PCI_VENDOR_ID_VMWARE 0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
+#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
+#define PCI_DEVICE_ID_VMWARE_NET 0x0720
+#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
+#define PCI_DEVICE_ID_VMWARE_IDE 0x1729
+
+/* From linux/pci.h. We emulate an AMD ethernet controller */
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_VLANCE 0x2000
+#define PCI_VENDOR_ID_BUSLOGIC 0x104B
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
+
+/* Intel Values for the chipset */
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
+#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
+#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
+#define PCI_DEVICE_ID_INTEL_82443BX 0x7192
+
+
+/************* Strings for IDE Identity Fields **************************/
+#define VIDE_ID_SERIAL_STR "00000000000000000001" /* Must be 20 Bytes */
+#define VIDE_ID_FIRMWARE_STR "00000001" /* Must be 8 Bytes */
+
+/* No longer than 40 Bytes and must be an even length. */
+#define VIDE_ATA_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE Hard Drive "
+#define VIDE_ATAPI_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE CDROM Drive "
+
+#define ATAPI_VENDOR_ID "NECVMWar" /* Must be 8 Bytes */
+#define ATAPI_PRODUCT_ID PRODUCT_GENERIC_NAME " IDE CDROM" /* Must be 16 Bytes */
+#define ATAPI_REV_LEVEL "1.00" /* Must be 4 Bytes */
+
+
+/************* Strings for SCSI Identity Fields **************************/
+#define SCSI_DISK_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI Hard Drive"
+#define SCSI_CDROM_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI CDROM Drive"
+
+/************* Strings for the VESA BIOS Identity Fields *****************/
+#define VBE_OEM_STRING COMPANY_NAME " SVGA"
+#define VBE_VENDOR_NAME COMPANY_NAME
+#define VBE_PRODUCT_NAME PRODUCT_GENERIC_NAME
+
+
+#endif /* VM_DEVICE_VERSION_H */
diff --git a/src/vmware.c b/src/vmware.c
new file mode 100644
index 0000000..41201f1
--- /dev/null
+++ b/src/vmware.c
@@ -0,0 +1,1666 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_vmware[] =
+ "Id: vmware.c,v 1.11 2001/02/23 02:10:39 yoel Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * TODO: support the vmware linux kernel fb driver (Option "UseFBDev").
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "compiler.h" /* inb/outb */
+
+#include "xf86Pci.h" /* pci */
+
+#include "mipointer.h" /* sw cursor */
+#include "mibstore.h" /* backing store */
+#include "micmap.h" /* mi color map */
+#include "vgaHW.h" /* VGA hardware */
+#include "fb.h"
+#include "shadowfb.h" /* ShadowFB wrappers */
+
+#include "xf86cmap.h" /* xf86HandleColormaps */
+
+#include "vmware.h"
+#include "guest_os.h"
+#include "vm_device_version.h"
+#include "svga_modes.h"
+#include "vmware_bootstrap.h"
+#include "vmware_common.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5)
+
+#define xf86LoaderReqSymLists(...) do {} while (0)
+#define LoaderRefSymLists(...) do {} while (0)
+
+#else
+
+const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbCreateDefColormap",
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *shadowfbSymbols[] = {
+ "ShadowFBInit2",
+ NULL
+};
+#endif
+
+/* Table of default modes to always add to the mode list. */
+
+typedef struct {
+ int width;
+ int height;
+} VMWAREDefaultMode;
+
+#define VMW_MIN_INITIAL_WIDTH 800
+#define VMW_MIN_INITIAL_HEIGHT 600
+
+#define SVGA_DEFAULT_MODE(width, height) { width, height, },
+
+static const VMWAREDefaultMode VMWAREDefaultModes[] = {
+ SVGA_DEFAULT_MODES
+};
+
+#undef SVGA_DEFAULT_MODE
+
+static void VMWAREStopFIFO(ScrnInfoPtr pScrn);
+static void VMWARESave(ScrnInfoPtr pScrn);
+
+static Bool
+VMWAREGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL) {
+ return TRUE;
+ }
+ pScrn->driverPrivate = xnfcalloc(sizeof(VMWARERec), 1);
+ /* FIXME: Initialize driverPrivate... */
+ return TRUE;
+}
+
+static void
+VMWAREFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate) {
+ free(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+ }
+}
+
+CARD32
+vmwareReadReg(VMWAREPtr pVMWARE, int index)
+{
+ /*
+ * Block SIGIO for the duration, so we don't get interrupted after the
+ * outl but before the inl by a mouse move (which write to our registers).
+ */
+ int oldsigio, ret;
+ oldsigio = xf86BlockSIGIO();
+ outl(pVMWARE->indexReg, index);
+ ret = inl(pVMWARE->valueReg);
+ xf86UnblockSIGIO(oldsigio);
+ return ret;
+}
+
+void
+vmwareWriteReg(VMWAREPtr pVMWARE, int index, CARD32 value)
+{
+ /*
+ * Block SIGIO for the duration, so we don't get interrupted in between
+ * the outls by a mouse move (which write to our registers).
+ */
+ int oldsigio;
+ oldsigio = xf86BlockSIGIO();
+ outl(pVMWARE->indexReg, index);
+ outl(pVMWARE->valueReg, value);
+ xf86UnblockSIGIO(oldsigio);
+}
+
+void
+vmwareWriteWordToFIFO(VMWAREPtr pVMWARE, CARD32 value)
+{
+ volatile CARD32* vmwareFIFO = pVMWARE->vmwareFIFO;
+
+ /* Need to sync? */
+ if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(CARD32) == vmwareFIFO[SVGA_FIFO_STOP])
+ || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(CARD32) &&
+ vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) {
+ VmwareLog(("Syncing because of full fifo\n"));
+ vmwareWaitForFB(pVMWARE);
+ }
+
+ vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(CARD32)] = value;
+
+ write_mem_barrier();
+
+ if(vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] -
+ sizeof(CARD32)) {
+ vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN];
+ } else {
+ vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(CARD32);
+ }
+}
+
+void
+vmwareWaitForFB(VMWAREPtr pVMWARE)
+{
+ vmwareWriteReg(pVMWARE, SVGA_REG_SYNC, 1);
+ while (vmwareReadReg(pVMWARE, SVGA_REG_BUSY));
+}
+
+void
+vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE, BoxPtr pBB)
+{
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_UPDATE);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->x1);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->y1);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->x2 - pBB->x1);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->y2 - pBB->y1);
+}
+
+void
+vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE)
+{
+ BoxRec BB;
+
+ BB.x1 = 0;
+ BB.y1 = 0;
+ BB.x2 = pVMWARE->ModeReg.svga_reg_width;
+ BB.y2 = pVMWARE->ModeReg.svga_reg_height;
+ vmwareSendSVGACmdUpdate(pVMWARE, &BB);
+}
+
+static CARD32
+vmwareCalculateWeight(CARD32 mask)
+{
+ CARD32 weight;
+
+ for (weight = 0; mask; mask >>= 1) {
+ if (mask & 1) {
+ weight++;
+ }
+ }
+ return weight;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMXGetVMwareSvgaId --
+ *
+ * Retrieve the SVGA_ID of the VMware SVGA adapter.
+ * This function should hide any backward compatibility mess.
+ *
+ * Results:
+ * The SVGA_ID_* of the present VMware adapter.
+ *
+ * Side effects:
+ * ins/outs
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static uint32
+VMXGetVMwareSvgaId(VMWAREPtr pVMWARE)
+{
+ uint32 vmware_svga_id;
+
+ /* Any version with any SVGA_ID_* support will initialize SVGA_REG_ID
+ * to SVGA_ID_0 to support versions of this driver with SVGA_ID_0.
+ *
+ * Versions of SVGA_ID_0 ignore writes to the SVGA_REG_ID register.
+ *
+ * Versions of SVGA_ID_1 will allow us to overwrite the content
+ * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1.
+ *
+ * Versions of SVGA_ID_2 will allow us to overwrite the content
+ * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1
+ * or SVGA_ID_2.
+ */
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_2);
+ vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+ if (vmware_svga_id == SVGA_ID_2) {
+ return SVGA_ID_2;
+ }
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_1);
+ vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+ if (vmware_svga_id == SVGA_ID_1) {
+ return SVGA_ID_1;
+ }
+
+ if (vmware_svga_id == SVGA_ID_0) {
+ return SVGA_ID_0;
+ }
+
+ /* No supported VMware SVGA devices found */
+ return SVGA_ID_INVALID;
+}
+
+static Bool
+VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ MessageType from;
+ VMWAREPtr pVMWARE;
+ OptionInfoPtr options;
+ int bpp24flags;
+ uint32 id;
+ int i;
+ ClockRange* clockRanges;
+ unsigned long domainIOBase = 0;
+ uint32 width = 0, height = 0;
+ Bool defaultMode;
+
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
+#ifndef BUILD_FOR_420
+ domainIOBase = pScrn->domainIOBase;
+#endif
+#endif
+
+ if (flags & PROBE_DETECT) {
+ return FALSE;
+ }
+
+ if (pScrn->numEntities != 1) {
+ return FALSE;
+ }
+
+ if (!VMWAREGetRec(pScrn)) {
+ return FALSE;
+ }
+ pVMWARE = VMWAREPTR(pScrn);
+
+ pVMWARE->pvtSema = &pScrn->vtSema;
+
+ pVMWARE->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pVMWARE->pEnt->location.type != BUS_PCI) {
+ return FALSE;
+ }
+ pVMWARE->PciInfo = xf86GetPciInfoForEntity(pVMWARE->pEnt->index);
+ if (pVMWARE->PciInfo == NULL) {
+ return FALSE;
+ }
+
+ if (DEVICE_ID(pVMWARE->PciInfo) == PCI_DEVICE_ID_VMWARE_SVGA) {
+ pVMWARE->indexReg = domainIOBase +
+ SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT*sizeof(uint32);
+ pVMWARE->valueReg = domainIOBase +
+ SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT*sizeof(uint32);
+ } else {
+ /* Note: This setting of valueReg causes unaligned I/O */
+#if XSERVER_LIBPCIACCESS
+ pVMWARE->portIOBase = pVMWARE->PciInfo->regions[0].base_addr;
+#else
+ pVMWARE->portIOBase = pVMWARE->PciInfo->ioBase[0];
+#endif
+ pVMWARE->indexReg = domainIOBase +
+ pVMWARE->portIOBase + SVGA_INDEX_PORT;
+ pVMWARE->valueReg = domainIOBase +
+ pVMWARE->portIOBase + SVGA_VALUE_PORT;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "VMware SVGA regs at (0x%04lx, 0x%04lx)\n",
+ pVMWARE->indexReg, pVMWARE->valueReg);
+
+ if (!xf86LoadSubModule(pScrn, "vgahw")) {
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ if (!vgaHWGetHWRec(pScrn)) {
+ return FALSE;
+ }
+
+#ifdef HAVE_XORG_SERVER_1_12_0
+ vgaHWSetStdFuncs(VGAHWPTR(pScrn));
+#endif
+
+ /*
+ * Save the current video state. Do it here before VMXGetVMwareSvgaId
+ * writes to any registers.
+ */
+ VMWARESave(pScrn);
+
+ id = VMXGetVMwareSvgaId(pVMWARE);
+ if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No supported VMware SVGA found (read ID 0x%08x).\n", id);
+ return FALSE;
+ }
+ pVMWARE->suspensionSavedRegId = id;
+
+#if !XSERVER_LIBPCIACCESS
+ pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device,
+ pVMWARE->PciInfo->func);
+#endif
+ pVMWARE->Primary = xf86IsPrimaryPci(pVMWARE->PciInfo);
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+#ifdef ACCELERATE_OPS
+ pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES);
+#else
+ pVMWARE->vmwareCapability = 0;
+#endif
+
+ pVMWARE->bitsPerPixel = vmwareReadReg(pVMWARE,
+ SVGA_REG_HOST_BITS_PER_PIXEL);
+ if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, pVMWARE->bitsPerPixel);
+ }
+
+ pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
+ pVMWARE->videoRam = vmwareReadReg(pVMWARE, SVGA_REG_VRAM_SIZE);
+ pVMWARE->memPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_FB_START);
+ pVMWARE->maxWidth = vmwareReadReg(pVMWARE, SVGA_REG_MAX_WIDTH);
+ pVMWARE->maxHeight = vmwareReadReg(pVMWARE, SVGA_REG_MAX_HEIGHT);
+ pVMWARE->cursorDefined = FALSE;
+ pVMWARE->cursorShouldBeHidden = FALSE;
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS_2) {
+ pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_REMOVE_FROM_FB;
+ pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_RESTORE_TO_FB;
+ } else {
+ pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_HIDE;
+ pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_SHOW;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "caps: 0x%08X\n", pVMWARE->vmwareCapability);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "depth: %d\n", pVMWARE->depth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "bpp: %d\n", pVMWARE->bitsPerPixel);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "vram: %d\n", pVMWARE->videoRam);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "pbase: 0x%08lx\n", pVMWARE->memPhysBase);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mwidt: %d\n", pVMWARE->maxWidth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mheig: %d\n", pVMWARE->maxHeight);
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+ bpp24flags = Support24bppFb | Support32bppFb;
+ } else {
+ switch (pVMWARE->depth) {
+ case 16:
+ /*
+ * In certain cases, the Windows host appears to
+ * report 16 bpp and 16 depth but 555 weight. Just
+ * silently convert it to depth of 15.
+ */
+ if (pVMWARE->bitsPerPixel == 16 &&
+ pVMWARE->weight.green == 5)
+ pVMWARE->depth = 15;
+ case 8:
+ case 15:
+ bpp24flags = NoDepth24Support;
+ break;
+ case 32:
+ /*
+ * There is no 32 bit depth, apparently it can get
+ * reported this way sometimes on the Windows host.
+ */
+ if (pVMWARE->bitsPerPixel == 32)
+ pVMWARE->depth = 24;
+ case 24:
+ if (pVMWARE->bitsPerPixel == 24)
+ bpp24flags = Support24bppFb;
+ else
+ bpp24flags = Support32bppFb;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Adapter is using an unsupported depth (%d).\n",
+ pVMWARE->depth);
+ return FALSE;
+ }
+ }
+
+ if (!xf86SetDepthBpp(pScrn, pVMWARE->depth, pVMWARE->bitsPerPixel,
+ pVMWARE->bitsPerPixel, bpp24flags)) {
+ return FALSE;
+ }
+
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+
+ if (pScrn->bitsPerPixel != pVMWARE->bitsPerPixel) {
+ if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+ pScrn->bitsPerPixel);
+ pVMWARE->bitsPerPixel =
+ vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+ pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Currently unavailable depth/bpp of %d/%d requested.\n"
+ "\tThe guest X server must run at the same depth and bpp as the host\n"
+ "\t(which are currently %d/%d). This is automatically detected. Please\n"
+ "\tdo not specify a depth on the command line or via the config file.\n",
+ pScrn->depth, pScrn->bitsPerPixel,
+ pVMWARE->depth, pVMWARE->bitsPerPixel);
+ return FALSE;
+ }
+ }
+
+ /*
+ * Defer reading the colour registers until here in case we changed
+ * bpp above.
+ */
+
+ pVMWARE->weight.red =
+ vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_RED_MASK));
+ pVMWARE->weight.green =
+ vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_GREEN_MASK));
+ pVMWARE->weight.blue =
+ vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_BLUE_MASK));
+ pVMWARE->offset.blue = 0;
+ pVMWARE->offset.green = pVMWARE->weight.blue;
+ pVMWARE->offset.red = pVMWARE->weight.green + pVMWARE->offset.green;
+ pVMWARE->defaultVisual = vmwareReadReg(pVMWARE, SVGA_REG_PSEUDOCOLOR) ?
+ PseudoColor : TrueColor;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "depth: %d\n", pVMWARE->depth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "bpp: %d\n", pVMWARE->bitsPerPixel);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "w.red: %d\n", (int)pVMWARE->weight.red);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "w.grn: %d\n", (int)pVMWARE->weight.green);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "w.blu: %d\n", (int)pVMWARE->weight.blue);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "vis: %d\n", pVMWARE->defaultVisual);
+
+ if (pScrn->depth != pVMWARE->depth) {
+ if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Currently unavailable depth of %d requested.\n"
+ "\tIf the guest X server's BPP matches the host's "
+ "BPP, then\n\tthe guest X server's depth must also "
+ "match the\n\thost's depth (currently %d).\n",
+ pScrn->depth, pVMWARE->depth);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Currently unavailable depth of %d requested.\n"
+ "\tThe guest X server must run at the same depth as "
+ "the host (which\n\tis currently %d). This is "
+ "automatically detected. Please do not\n\tspecify "
+ "a depth on the command line or via the config file.\n",
+ pScrn->depth, pVMWARE->depth);
+ }
+ return FALSE;
+ }
+ xf86PrintDepthBpp(pScrn);
+
+#if 0
+ if (pScrn->depth == 24 && pix24bpp == 0) {
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ }
+#endif
+
+ if (pScrn->depth > 8) {
+ rgb zeros = { 0, 0, 0 };
+
+ if (!xf86SetWeight(pScrn, pVMWARE->weight, zeros)) {
+ return FALSE;
+ }
+ /* FIXME check returned weight */
+ }
+ if (!xf86SetDefaultVisual(pScrn, pVMWARE->defaultVisual)) {
+ return FALSE;
+ }
+ if (pScrn->defaultVisual != pVMWARE->defaultVisual) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given visual (%d) is not supported by this driver (%d is required)\n",
+ pScrn->defaultVisual, pVMWARE->defaultVisual);
+ return FALSE;
+ }
+#if 0
+ bytesPerPixel = pScrn->bitsPerPixel / 8;
+#endif
+ pScrn->progClock = TRUE;
+
+#if 0 /* MGA does not do this */
+ if (pScrn->visual != 0) { /* FIXME */
+ /* print error message */
+ return FALSE;
+ }
+#endif
+
+ xf86CollectOptions(pScrn, NULL);
+ if (!(options = VMWARECopyOptions()))
+ return FALSE;
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ if (pScrn->depth <= 8) {
+ pScrn->rgbBits = 8;
+ }
+
+ if (!pScrn->chipset) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04x is not recognised\n", DEVICE_ID(pVMWARE->PciInfo));
+ return FALSE;
+ }
+
+ from = X_DEFAULT;
+ pVMWARE->hwCursor = TRUE;
+ if (xf86GetOptValBool(options, OPTION_HW_CURSOR, &pVMWARE->hwCursor)) {
+ from = X_CONFIG;
+ }
+ if (pVMWARE->hwCursor && !(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW cursor is not supported in this configuration\n");
+ from = X_PROBED;
+ pVMWARE->hwCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pVMWARE->hwCursor ? "HW" : "SW");
+ pScrn->videoRam = pVMWARE->videoRam / 1024;
+ pScrn->memPhysBase = pVMWARE->memPhysBase;
+
+ from = X_DEFAULT;
+ defaultMode = TRUE;
+ if (xf86GetOptValBool(options, OPTION_DEFAULT_MODE, &defaultMode)) {
+ from = X_CONFIG;
+ }
+
+ width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
+ height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
+ width = MAX(width, VMW_MIN_INITIAL_WIDTH);
+ height = MAX(height, VMW_MIN_INITIAL_HEIGHT);
+
+ if (width > pVMWARE->maxWidth || height > pVMWARE->maxHeight) {
+ /*
+ * This is an error condition and shouldn't happen.
+ * revert to MIN_INITIAL_ values
+ */
+ width = VMW_MIN_INITIAL_WIDTH;
+ height = VMW_MIN_INITIAL_HEIGHT;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will %sset up a driver mode with dimensions %dx%d.\n",
+ defaultMode ? "" : "not ", width, height);
+
+ free(options);
+
+ {
+ Gamma zeros = { 0.0, 0.0, 0.0 };
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+#if 0
+ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) {
+ /* print error message */
+ VMWAREFreeRec(pScrn);
+ if (i > 0) {
+ free(pciList);
+ }
+ return FALSE;
+ }
+#endif
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = 1;
+ clockRanges->maxClock = 400000000;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ clockRanges->ClockMulFactor = 1;
+ clockRanges->ClockDivFactor = 1;
+
+ if (defaultMode) {
+ vmwareAddDefaultMode(pScrn, width, height);
+ }
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
+ clockRanges, NULL, 256, pVMWARE->maxWidth,
+ pVMWARE->bitsPerPixel * 1,
+ 128, pVMWARE->maxHeight,
+ pScrn->display->virtualX, pScrn->display->virtualY,
+ pVMWARE->videoRam,
+ LOOKUP_BEST_REFRESH | LOOKUP_OPTIONAL_TOLERANCES);
+
+ if (i == -1) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86PruneDriverModes(pScrn);
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pScrn->currentMode = pScrn->modes;
+ pScrn->virtualX = pScrn->modes->HDisplay;
+ pScrn->virtualY = pScrn->modes->VDisplay;
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ xf86PrintModes(pScrn);
+ xf86SetDpi(pScrn, 0, 0);
+ if (!xf86LoadSubModule(pScrn, "fb") ||
+ !xf86LoadSubModule(pScrn, "shadowfb")) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(fbSymbols, shadowfbSymbols, NULL);
+
+ /* Need ramdac for hwcursor */
+ if (pVMWARE->hwCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ return TRUE;
+}
+
+static Bool
+VMWAREMapMem(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#if XSERVER_LIBPCIACCESS
+ int err;
+ struct pci_device *const device = pVMWARE->PciInfo;
+ void *fbBase;
+#endif
+
+#if XSERVER_LIBPCIACCESS
+ err = pci_device_map_range(device,
+ pVMWARE->memPhysBase,
+ pVMWARE->videoRam,
+ PCI_DEV_MAP_FLAG_WRITABLE,
+ &fbBase);
+ if (err) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to map frame buffer BAR. %s (%d)\n",
+ strerror (err), err);
+ return FALSE;
+ }
+ pVMWARE->FbBase = fbBase;
+#else
+ pVMWARE->FbBase = xf86MapPciMem(pScrn->scrnIndex, 0,
+ pVMWARE->PciTag,
+ pVMWARE->memPhysBase,
+ pVMWARE->videoRam);
+#endif
+ if (!pVMWARE->FbBase)
+ return FALSE;
+
+ VmwareLog(("FB Mapped: %p/%u -> %p/%u\n",
+ pVMWARE->memPhysBase, pVMWARE->videoRam,
+ pVMWARE->FbBase, pVMWARE->videoRam));
+ return TRUE;
+}
+
+static Bool
+VMWAREUnmapMem(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE;
+
+ pVMWARE = VMWAREPTR(pScrn);
+
+ VmwareLog(("Unmapped: %p/%u\n", pVMWARE->FbBase, pVMWARE->videoRam));
+
+#if XSERVER_LIBPCIACCESS
+ pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->FbBase, pVMWARE->videoRam);
+#else
+ xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->FbBase, pVMWARE->videoRam);
+#endif
+ pVMWARE->FbBase = NULL;
+ return TRUE;
+}
+
+static void
+VMWARESave(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+ vmwareReg->svga_reg_enable = vmwareReadReg(pVMWARE, SVGA_REG_ENABLE);
+ vmwareReg->svga_reg_width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
+ vmwareReg->svga_reg_height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
+ vmwareReg->svga_reg_bits_per_pixel =
+ vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+ vmwareReg->svga_reg_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+
+ /* XXX this should be based on the cap bit, not hwCursor... */
+ if (pVMWARE->hwCursor) {
+ vmwareReg->svga_reg_cursor_on =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ON);
+ vmwareReg->svga_reg_cursor_x =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_X);
+ vmwareReg->svga_reg_cursor_y =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_Y);
+ vmwareReg->svga_reg_cursor_id =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ID);
+ }
+
+ vmwareReg->svga_fifo_enabled = vmwareReadReg(pVMWARE, SVGA_REG_CONFIG_DONE);
+}
+
+static void
+VMWARERestoreRegs(ScrnInfoPtr pScrn, VMWARERegPtr vmwareReg)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VmwareLog(("VMWARERestoreRegs: W: %d, H: %d, BPP: %d, Enable: %d\n",
+ vmwareReg->svga_reg_width, vmwareReg->svga_reg_height,
+ vmwareReg->svga_reg_bits_per_pixel, vmwareReg->svga_reg_enable));
+ if (vmwareReg->svga_reg_enable) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
+ vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+ vmwareReg->svga_reg_bits_per_pixel);
+ vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+ vmwareWriteReg(pVMWARE, SVGA_REG_GUEST_ID, GUEST_OS_LINUX);
+ if (pVMWARE->hwCursor) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID,
+ vmwareReg->svga_reg_cursor_id);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X,
+ vmwareReg->svga_reg_cursor_x);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y,
+ vmwareReg->svga_reg_cursor_y);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON,
+ vmwareReg->svga_reg_cursor_on);
+ }
+ } else {
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
+ vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+ vmwareReg->svga_reg_bits_per_pixel);
+ vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+ }
+}
+
+static void
+VMWARERestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
+
+ vmwareWaitForFB(pVMWARE);
+ if (!vmwareReg->svga_fifo_enabled) {
+ VMWAREStopFIFO(pScrn);
+ }
+
+ vgaHWProtect(pScrn, TRUE);
+ VMWARERestoreRegs(pScrn, vmwareReg);
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+static Bool
+VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->ModeReg;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
+
+ vgaHWUnlock(hwp);
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ vmwareReg->svga_reg_enable = 1;
+ vmwareReg->svga_reg_width = max(mode->HDisplay, pScrn->virtualX);
+ vmwareReg->svga_reg_height = max(mode->VDisplay, pScrn->virtualY);
+ vmwareReg->svga_reg_bits_per_pixel = pVMWARE->bitsPerPixel;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ VMWARERestoreRegs(pScrn, vmwareReg);
+
+ if (pVMWARE->hwCursor) {
+ vmwareCursorModeInit(pScrn, mode);
+ }
+
+ VmwareLog(("Required mode: %ux%u\n", mode->HDisplay, mode->VDisplay));
+ VmwareLog(("Virtual: %ux%u\n", pScrn->virtualX, pScrn->virtualY));
+ VmwareLog(("dispWidth: %u\n", pScrn->displayWidth));
+ pVMWARE->fbOffset = vmwareReadReg(pVMWARE, SVGA_REG_FB_OFFSET);
+ pVMWARE->fbPitch = vmwareReadReg(pVMWARE, SVGA_REG_BYTES_PER_LINE);
+ pVMWARE->FbSize = vmwareReadReg(pVMWARE, SVGA_REG_FB_SIZE);
+
+ pScrn->displayWidth = (pVMWARE->fbPitch * 8) / ((pScrn->bitsPerPixel + 7) & ~7);
+ VmwareLog(("fbOffset: %u\n", pVMWARE->fbOffset));
+ VmwareLog(("fbPitch: %u\n", pVMWARE->fbPitch));
+ VmwareLog(("fbSize: %u\n", pVMWARE->FbSize));
+ VmwareLog(("New dispWidth: %u\n", pScrn->displayWidth));
+
+ vmwareCheckVideoSanity(pScrn);
+
+ if (rebuildPixmap) {
+ pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen),
+ pScrn->pScreen->width,
+ pScrn->pScreen->height,
+ pScrn->pScreen->rootDepth,
+ pScrn->bitsPerPixel,
+ PixmapBytePad(pScrn->displayWidth,
+ pScrn->pScreen->rootDepth),
+ (pointer)(pVMWARE->FbBase + pScrn->fbOffset));
+
+ (*pScrn->EnableDisableFBAccess)(XF86_SCRN_ARG(pScrn), FALSE);
+ (*pScrn->EnableDisableFBAccess)(XF86_SCRN_ARG(pScrn), TRUE);
+ }
+
+ vgaHWProtect(pScrn, FALSE);
+
+ /*
+ * Push the new Xinerama state to X clients and the hardware,
+ * synchronously with the mode change. Note that this must happen
+ * AFTER we write the new width and height to the hardware
+ * registers, since updating the WIDTH and HEIGHT registers will
+ * reset the device's multimon topology.
+ */
+ vmwareNextXineramaState(pVMWARE);
+
+ return TRUE;
+}
+
+void
+vmwareNextXineramaState(VMWAREPtr pVMWARE)
+{
+ VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
+
+ /*
+ * Switch to the next Xinerama state (from pVMWARE->xineramaNextState).
+ *
+ * This new state will be available to X clients via the Xinerama
+ * extension, and we push the new state to the virtual hardware,
+ * in order to configure a number of virtual monitors within the
+ * device's framebuffer.
+ *
+ * This function can be called at any time, but it should usually be
+ * called just after a mode switch. This is for two reasons:
+ *
+ * 1) We don't want X clients to see a Xinerama topology and a video
+ * mode that are inconsistent with each other, so we'd like to switch
+ * both at the same time.
+ *
+ * 2) We must set the host's display topology registers after setting
+ * the new video mode, since writes to WIDTH/HEIGHT will reset the
+ * hardware display topology.
+ */
+
+ /*
+ * Update Xinerama info appropriately.
+ */
+ if (pVMWARE->xinerama && !pVMWARE->xineramaStatic) {
+ if (pVMWARE->xineramaNextState) {
+ free(pVMWARE->xineramaState);
+ pVMWARE->xineramaState = pVMWARE->xineramaNextState;
+ pVMWARE->xineramaNumOutputs = pVMWARE->xineramaNextNumOutputs;
+
+ pVMWARE->xineramaNextState = NULL;
+ pVMWARE->xineramaNextNumOutputs = 0;
+
+ } else {
+ /*
+ * There is no next state pending. Switch back to
+ * single-monitor mode. This is necessary for resetting the
+ * Xinerama state if we get a mode change which doesn't
+ * follow a VMwareCtrlDoSetTopology call.
+ */
+ VMWAREXineramaPtr basicState =
+ (VMWAREXineramaPtr)calloc(1, sizeof (VMWAREXineramaRec));
+ if (basicState) {
+ basicState->x_org = 0;
+ basicState->y_org = 0;
+ basicState->width = vmwareReg->svga_reg_width;
+ basicState->height = vmwareReg->svga_reg_height;
+
+ free(pVMWARE->xineramaState);
+ pVMWARE->xineramaState = basicState;
+ pVMWARE->xineramaNumOutputs = 1;
+ }
+ }
+ }
+
+ /*
+ * Update host's view of guest topology. This tells the device
+ * how we're carving up its framebuffer into virtual screens.
+ */
+ if (pVMWARE->vmwareCapability & SVGA_CAP_DISPLAY_TOPOLOGY) {
+ if (pVMWARE->xinerama) {
+ int i = 0;
+ VMWAREXineramaPtr xineramaState = pVMWARE->xineramaState;
+ vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS,
+ pVMWARE->xineramaNumOutputs);
+
+ for (i = 0; i < pVMWARE->xineramaNumOutputs; i++) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, i);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, i == 0);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X,
+ xineramaState[i].x_org);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y,
+ xineramaState[i].y_org);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH,
+ xineramaState[i].width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT,
+ xineramaState[i].height);
+ }
+ } else {
+ vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, 0);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, TRUE);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X, 0);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y, 0);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, vmwareReg->svga_reg_width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, vmwareReg->svga_reg_height);
+ }
+
+ /* Done. */
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, SVGA_INVALID_DISPLAY_ID);
+ }
+}
+
+static void
+VMWAREAdjustFrame(ADJUST_FRAME_ARGS_DECL)
+{
+ /* FIXME */
+}
+
+static void
+VMWAREInitFIFO(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *const device = pVMWARE->PciInfo;
+ int err;
+ void *mmioVirtBase;
+#endif
+ volatile CARD32* vmwareFIFO;
+ Bool extendedFifo;
+ int min;
+
+ TRACEPOINT
+
+ pVMWARE->mmioPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_MEM_START);
+ pVMWARE->mmioSize = vmwareReadReg(pVMWARE, SVGA_REG_MEM_SIZE) & ~3;
+#if XSERVER_LIBPCIACCESS
+ err = pci_device_map_range(device, pVMWARE->mmioPhysBase,
+ pVMWARE->mmioSize,
+ PCI_DEV_MAP_FLAG_WRITABLE,
+ &mmioVirtBase);
+ if (err) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to map mmio BAR. %s (%d)\n",
+ strerror (err), err);
+ return;
+ }
+ pVMWARE->mmioVirtBase = mmioVirtBase;
+#else
+ pVMWARE->mmioVirtBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pVMWARE->PciTag,
+ pVMWARE->mmioPhysBase,
+ pVMWARE->mmioSize);
+#endif
+ vmwareFIFO = pVMWARE->vmwareFIFO = (CARD32*)pVMWARE->mmioVirtBase;
+
+ extendedFifo = pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO;
+ min = extendedFifo ? vmwareReadReg(pVMWARE, SVGA_REG_MEM_REGS) : 4;
+
+ vmwareWaitForFB(pVMWARE);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
+
+ vmwareFIFO[SVGA_FIFO_MIN] = min * sizeof(CARD32);
+ vmwareFIFO[SVGA_FIFO_MAX] = pVMWARE->mmioSize;
+ vmwareFIFO[SVGA_FIFO_NEXT_CMD] = min * sizeof(CARD32);
+ vmwareFIFO[SVGA_FIFO_STOP] = min * sizeof(CARD32);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 1);
+}
+
+static void
+VMWAREStopFIFO(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ TRACEPOINT
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
+#if XSERVER_LIBPCIACCESS
+ pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
+#else
+ xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
+#endif
+}
+
+static Bool
+VMWARECloseScreen(CLOSE_SCREEN_ARGS_DECL)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ ScreenPtr save = &pVMWARE->ScrnFuncs;
+
+ VmwareLog(("cursorSema: %d\n", pVMWARE->cursorSema));
+
+ if (*pVMWARE->pvtSema) {
+ if (pVMWARE->videoStreams) {
+ vmwareVideoEnd(pScreen);
+ }
+
+ if (pVMWARE->CursorInfoRec) {
+ vmwareCursorCloseScreen(pScreen);
+ }
+
+ VMWARERestore(pScrn);
+ VMWAREUnmapMem(pScrn);
+
+ pScrn->vtSema = FALSE;
+ }
+
+ pScreen->CloseScreen = save->CloseScreen;
+ pScreen->SaveScreen = save->SaveScreen;
+
+#if VMWARE_DRIVER_FUNC
+ pScrn->DriverFunc = NULL;
+#endif
+
+ return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
+}
+
+static Bool
+VMWARESaveScreen(ScreenPtr pScreen, int mode)
+{
+ VmwareLog(("VMWareSaveScreen() mode = %d\n", mode));
+
+ /*
+ * This thoroughly fails to do anything useful to svga mode. I doubt
+ * we care; who wants to idle-blank their VM's screen anyway?
+ */
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/*#define DEBUG_LOG_UPDATES*/
+
+static void
+VMWAREPreDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+#ifdef DEBUG_LOG_UPDATES
+ {
+ int i;
+ for (i = 0; i < nboxes; i++) {
+ VmwareLog(("PreUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes - i,
+ boxPtr[i].x1, boxPtr[i].y1,
+ boxPtr[i].x2 - boxPtr[i].x1,
+ boxPtr[i].y2 - boxPtr[i].y1));
+ }
+ }
+#endif
+
+ /*
+ * We only register this callback if we have a HW cursor.
+ */
+ while (nboxes--) {
+ if (BOX_INTERSECT(*boxPtr, pVMWARE->hwcur.box)) {
+ if (!pVMWARE->cursorExcludedForUpdate) {
+ PRE_OP_HIDE_CURSOR();
+ pVMWARE->cursorExcludedForUpdate = TRUE;
+ }
+ break;
+ }
+ boxPtr++;
+ }
+}
+
+static void
+VMWAREPostDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ while (nboxes--) {
+#ifdef DEBUG_LOG_UPDATES
+ VmwareLog(("PostUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes,
+ boxPtr->x1, boxPtr->y1,
+ boxPtr->x2 - boxPtr->x1, boxPtr->y2 - boxPtr->y1));
+#endif
+
+ /* Clip off (y only) for offscreen memory */
+ if (boxPtr->y2 >= pVMWARE->ModeReg.svga_reg_height)
+ boxPtr->y2 = pVMWARE->ModeReg.svga_reg_height;
+ if (boxPtr->y1 >= pVMWARE->ModeReg.svga_reg_height)
+ boxPtr->y1 = pVMWARE->ModeReg.svga_reg_height;
+ if (boxPtr->y1 == boxPtr->y2) {
+ boxPtr++;
+ continue;
+ }
+
+ vmwareSendSVGACmdUpdate(pVMWARE, boxPtr++);
+ }
+
+ if (pVMWARE->hwCursor && pVMWARE->cursorExcludedForUpdate) {
+ POST_OP_SHOW_CURSOR();
+ pVMWARE->cursorExcludedForUpdate = FALSE;
+ }
+}
+
+static void
+VMWARELoadPalette(ScrnInfoPtr pScrn, int numColors, int* indices,
+ LOCO* colors, VisualPtr pVisual)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ int i;
+
+ for (i = 0; i < numColors; i++) {
+ vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 0, colors[*indices].red);
+ vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 1, colors[*indices].green);
+ vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 2, colors[*indices].blue);
+ indices++;
+ }
+ VmwareLog(("Palette loading done\n"));
+}
+
+
+DisplayModeRec *
+VMWAREAddDisplayMode(ScrnInfoPtr pScrn,
+ const char *name,
+ int width,
+ int height)
+{
+ DisplayModeRec *mode;
+
+ mode = malloc(sizeof(DisplayModeRec));
+ memset(mode, 0, sizeof *mode);
+
+ mode->name = malloc(strlen(name) + 1);
+ strcpy(mode->name, name);
+ mode->status = MODE_OK;
+ mode->type = M_T_DEFAULT;
+ mode->HDisplay = width;
+ mode->VDisplay = height;
+
+ mode->next = pScrn->modes;
+ mode->prev = pScrn->modes->prev;
+ pScrn->modes->prev->next = mode;
+ pScrn->modes->prev = mode;
+
+ return mode;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareIsRegionEqual --
+ *
+ * This function implements REGION_EQUAL because older versions of
+ * regionstr.h don't define it.
+ * It is a slightly modified version of miRegionEqual from $Xorg: miregion.c
+ *
+ * Results:
+ * TRUE if regions are equal; FALSE otherwise
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+vmwareIsRegionEqual(const RegionPtr reg1,
+ const RegionPtr reg2)
+{
+ int i, num;
+ BoxPtr rects1, rects2;
+
+ if ((reg1->extents.x1 != reg2->extents.x1) ||
+ (reg1->extents.x2 != reg2->extents.x2) ||
+ (reg1->extents.y1 != reg2->extents.y1) ||
+ (reg1->extents.y2 != reg2->extents.y2)) {
+ return FALSE;
+ }
+
+ num = REGION_NUM_RECTS(reg1);
+ if (num != REGION_NUM_RECTS(reg2)) {
+ return FALSE;
+ }
+
+ rects1 = REGION_RECTS(reg1);
+ rects2 = REGION_RECTS(reg2);
+
+ for (i = 0; i < num; i++) {
+ if ((rects1[i].x1 != rects2[i].x1) ||
+ (rects1[i].x2 != rects2[i].x2) ||
+ (rects1[i].y1 != rects2[i].y1) ||
+ (rects1[i].y2 != rects2[i].y2)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+VMWAREScreenInit(SCREEN_INIT_ARGS_DECL)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ vgaHWPtr hwp;
+ VMWAREPtr pVMWARE;
+ OptionInfoPtr options;
+ Bool useXinerama = TRUE;
+
+ pVMWARE = VMWAREPTR(pScrn);
+
+
+ xf86CollectOptions(pScrn, NULL);
+ if (!(options = VMWARECopyOptions()))
+ return FALSE;
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /*
+ * Init xinerama preferences.
+ */
+ useXinerama = xf86ReturnOptValBool(options, OPTION_XINERAMA,
+ pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON);
+ if (useXinerama && !(pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Xinerama is not safely supported by the current virtual hardware. "
+ "Do not request resolutions that require > 16MB of framebuffer.\n");
+ }
+
+
+ if (useXinerama && xf86IsOptionSet(options, OPTION_GUI_LAYOUT)) {
+ char *topology = xf86GetOptValString(options, OPTION_GUI_LAYOUT);
+ if (topology) {
+ pVMWARE->xineramaState =
+ VMWAREParseTopologyString(pScrn, topology,
+ &pVMWARE->xineramaNumOutputs, "gui");
+
+ pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
+
+ free(topology);
+ }
+ } else if (useXinerama &&
+ xf86IsOptionSet(options, OPTION_STATIC_XINERAMA)) {
+ char *topology = xf86GetOptValString(options, OPTION_STATIC_XINERAMA);
+ if (topology) {
+ pVMWARE->xineramaState =
+ VMWAREParseTopologyString(pScrn, topology,
+ &pVMWARE->xineramaNumOutputs,
+ "static Xinerama");
+
+ pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
+
+ free(topology);
+ }
+ }
+
+ free(options);
+
+ /* Initialise VMWARE_CTRL extension. */
+ VMwareCtrl_ExtInit(pScrn);
+
+ /* Initialise Xinerama extension. */
+ if (useXinerama) {
+ VMwareXinerama_ExtInit(pScrn);
+ }
+
+ if (pVMWARE->xinerama && pVMWARE->xineramaStatic) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, pVMWARE->xineramaState ?
+ "Using static Xinerama.\n" :
+ "Failed to configure static Xinerama.\n");
+ }
+
+ /*
+ * If using the vgahw module, its data structures and related
+ * things are typically initialised/mapped here.
+ */
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ VMWAREInitFIFO(pScrn);
+
+ /* Initialise the first mode */
+ VMWAREModeInit(pScrn, pScrn->currentMode, FALSE);
+
+ /* Set the viewport if supported */
+ VMWAREAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
+
+ /*
+ * Setup the screen's visuals, and initialise the framebuffer
+ * code.
+ */
+ VMWAREMapMem(pScrn);
+
+ /*
+ * Clear the framebuffer (and any black-border mode areas).
+ */
+ memset(pVMWARE->FbBase, 0, pVMWARE->FbSize);
+ vmwareSendSVGACmdUpdateFullScreen(pVMWARE);
+
+ /* Reset the visual list */
+ miClearVisualTypes();
+
+ /*
+ * Setup the visuals supported. This driver only supports
+ * TrueColor for bpp > 8, so the default set of visuals isn't
+ * acceptable. To deal with this, call miSetVisualTypes with
+ * the appropriate visual mask.
+ */
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ return FALSE;
+ }
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ return FALSE;
+ }
+ }
+
+ miSetPixmapDepths();
+
+ /*
+ * Initialise the framebuffer.
+ */
+ if (!fbScreenInit(pScreen, pVMWARE->FbBase + pVMWARE->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth,
+ pScrn->bitsPerPixel)) {
+ return FALSE;
+ }
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ int i;
+ VisualPtr visual;
+
+ for (i = 0, visual = pScreen->visuals;
+ i < pScreen->numVisuals; i++, visual++) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+ fbPictureInit (pScreen, 0, 0);
+
+ /*
+ * Save the old screen vector.
+ */
+ pVMWARE->ScrnFuncs = *pScreen;
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ /*
+ * Initialize shadowfb to notify us of dirty rectangles. We only
+ * need preFB access callbacks if we're using the hw cursor.
+ */
+ if (!ShadowFBInit2(pScreen,
+ pVMWARE->hwCursor ? VMWAREPreDirtyBBUpdate : NULL,
+ VMWAREPostDirtyBBUpdate)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ShadowFB initialization failed\n");
+ return FALSE;
+ }
+
+ /*
+ * If we have a hw cursor, we need to hook functions that might
+ * read from the framebuffer.
+ */
+ if (pVMWARE->hwCursor) {
+ vmwareCursorHookWrappers(pScreen);
+ }
+
+ /*
+ * If backing store is to be supported (as is usually the case),
+ * initialise it.
+ */
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ /*
+ * Initialize software cursor.
+ */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /*
+ * Initialize hardware cursor.
+ */
+ if (pVMWARE->hwCursor) {
+ if (!vmwareCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ pVMWARE->hwCursor = FALSE;
+ }
+ }
+
+ /*
+ * Install colourmap functions. If using the vgahw module,
+ * vgaHandleColormaps would usually be called here.
+ */
+ if (!fbCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!xf86HandleColormaps(pScreen, 256, 8,
+ VMWARELoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR |
+ CMAP_RELOAD_ON_MODE_SWITCH)) {
+ return FALSE;
+ }
+
+ /*
+ * We explictly add a set of default modes because the X server will
+ * not include modes larger than the initial one.
+ */
+ {
+ unsigned int i;
+ unsigned int numModes = sizeof (VMWAREDefaultModes) / sizeof *(VMWAREDefaultModes);
+ char name[10];
+ for (i = 0; i < numModes; i++) {
+ const VMWAREDefaultMode *mode = &VMWAREDefaultModes[i];
+
+ /* Only modes that fit the hardware maximums should be added. */
+ if (mode->width <= pVMWARE->maxWidth && mode->height <= pVMWARE->maxHeight) {
+ snprintf(name, 10, "%dx%d", mode->width, mode->height);
+ VMWAREAddDisplayMode(pScrn, name, mode->width, mode->height);
+ }
+ }
+
+ /* Add the hardware maximums as a mode. */
+ snprintf(name, 10, "%dx%d", pVMWARE->maxWidth, pVMWARE->maxHeight);
+ VMWAREAddDisplayMode(pScrn, name, pVMWARE->maxWidth, pVMWARE->maxHeight);
+ }
+
+ /*
+ * We will lazily add the dynamic modes as the are needed when new
+ * modes are requested through the control extension.
+ */
+ memset(&pVMWARE->dynModes, 0, sizeof pVMWARE->dynModes);
+
+#if VMWARE_DRIVER_FUNC
+ pScrn->DriverFunc = VMWareDriverFunc;
+#endif
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Initialize Xv extension */
+ pVMWARE->videoStreams = NULL;
+ if (vmwareVideoEnabled(pVMWARE)) {
+ if (!vmwareVideoInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n");
+ }
+ }
+
+ /**
+ * Wrap CloseScreen and SaveScreen. Do this late since we
+ * want to be first in the callchain, to avoid using resources
+ * already taken down in CloseScreen.
+ */
+
+ pVMWARE->ScrnFuncs.CloseScreen = pScreen->CloseScreen;
+ pVMWARE->ScrnFuncs.SaveScreen = pScreen->SaveScreen;
+
+ pScreen->CloseScreen = VMWARECloseScreen;
+ pScreen->SaveScreen = VMWARESaveScreen;
+
+ /* Done */
+ return TRUE;
+}
+
+static Bool
+VMWARESwitchMode(SWITCH_MODE_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ ScreenPtr pScreen = pScrn->pScreen;
+
+ pScreen->mmWidth = (pScreen->width * VMWARE_INCHTOMM +
+ pScrn->xDpi / 2) / pScrn->xDpi;
+ pScreen->mmHeight = (pScreen->height * VMWARE_INCHTOMM +
+ pScrn->yDpi / 2) / pScrn->yDpi;
+
+ return VMWAREModeInit(pScrn, mode, TRUE);
+}
+
+static Bool
+VMWAREEnterVT(VT_FUNC_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ /*
+ * After system resumes from hiberation, EnterVT will be called and this
+ * is a good place to restore the SVGA ID register.
+ */
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, pVMWARE->suspensionSavedRegId);
+
+ if (!pVMWARE->SavedReg.svga_fifo_enabled) {
+ VMWAREInitFIFO(pScrn);
+ }
+
+ return VMWAREModeInit(pScrn, pScrn->currentMode, TRUE);
+}
+
+static void
+VMWARELeaveVT(VT_FUNC_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ /*
+ * Before shutting down system for hibneration, LeaveVT will be called,
+ * we save the ID register value here and later restore it in EnterVT.
+ */
+ pVMWARE->suspensionSavedRegId = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+
+ VMWARERestore(pScrn);
+}
+
+static void
+VMWAREFreeScreen(FREE_SCREEN_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ /*
+ * If the vgahw module is used vgaHWFreeHWRec() would be called
+ * here.
+ */
+ VMWAREFreeRec(pScrn);
+}
+
+static ModeStatus
+VMWAREValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return MODE_OK;
+}
+
+void
+vmwlegacy_hookup(ScrnInfoPtr pScrn)
+{
+ pScrn->PreInit = VMWAREPreInit;
+ pScrn->ScreenInit = VMWAREScreenInit;
+ pScrn->SwitchMode = VMWARESwitchMode;
+ pScrn->EnterVT = VMWAREEnterVT;
+ pScrn->LeaveVT = VMWARELeaveVT;
+ pScrn->FreeScreen = VMWAREFreeScreen;
+ pScrn->ValidMode = VMWAREValidMode;
+}
+
+#ifdef XFree86LOADER
+void
+VMWARERefSymLists(void)
+{
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols,
+ shadowfbSymbols, NULL);
+}
+#endif /* XFree86LOADER */
diff --git a/src/vmware.h b/src/vmware.h
new file mode 100644
index 0000000..028dff3
--- /dev/null
+++ b/src/vmware.h
@@ -0,0 +1,316 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+#ifndef VMWARE_H
+#define VMWARE_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_XORG_SERVER_1_1_0
+#include <string.h>
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/extensions/panoramiXproto.h>
+
+#ifdef XSERVER_LIBPCIACCESS
+#include <pciaccess.h>
+#else
+#include "xf86Resources.h"
+#endif
+
+#include "compiler.h" /* inb/outb */
+
+#include "xf86Pci.h" /* pci */
+#include "xf86Cursor.h" /* hw cursor */
+#include "cursorstr.h" /* xhot/yhot */
+
+#include "vgaHW.h" /* VGA hardware */
+#include "fb.h"
+
+#include "xf86cmap.h" /* xf86HandleColormaps */
+
+#include "vm_basic_types.h"
+#include "svga_reg.h"
+#include "svga_struct.h"
+#include "vmware_bootstrap.h"
+#include <xf86Module.h>
+
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
+#define _swapl(x, n) swapl(x,n)
+#define _swaps(x, n) swaps(x,n)
+#else
+#define _swapl(x, n) (void) n; swapl(x)
+#define _swaps(x, n) (void) n; swaps(x)
+#endif
+
+/*
+ * The virtual hardware's cursor limits are pretty big. Some VMware
+ * product versions limit to 1024x1024 pixels, others limit to 128
+ * kilobytes of cursor data. We just choose an arbitrary maximum
+ * cursor size. 64x64 is a common value for real hardware, so we'll go
+ * with that.
+ */
+#define MAX_CURS 64
+
+#define NUM_DYN_MODES 2
+
+
+typedef struct {
+ CARD32 svga_reg_enable;
+ CARD32 svga_reg_width;
+ CARD32 svga_reg_height;
+ CARD32 svga_reg_bits_per_pixel;
+
+ CARD32 svga_reg_cursor_on;
+ CARD32 svga_reg_cursor_x;
+ CARD32 svga_reg_cursor_y;
+ CARD32 svga_reg_cursor_id;
+
+ Bool svga_fifo_enabled;
+
+ CARD32 svga_reg_id;
+} VMWARERegRec, *VMWARERegPtr;
+
+typedef xXineramaScreenInfo VMWAREXineramaRec, *VMWAREXineramaPtr;
+
+typedef struct {
+ EntityInfoPtr pEnt;
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *PciInfo;
+#else
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+#endif
+ Bool Primary;
+ int depth;
+ int bitsPerPixel;
+ rgb weight;
+ rgb offset;
+ int defaultVisual;
+ int videoRam;
+ unsigned long memPhysBase;
+ unsigned long fbOffset;
+ unsigned long fbPitch;
+ unsigned long ioBase;
+ unsigned long portIOBase;
+ int maxWidth;
+ int maxHeight;
+ unsigned int vmwareCapability;
+
+ unsigned char* FbBase;
+ unsigned long FbSize;
+
+ VMWARERegRec SavedReg;
+ VMWARERegRec ModeReg;
+ CARD32 suspensionSavedRegId;
+
+ DisplayModePtr dynModes[NUM_DYN_MODES];
+
+ Bool* pvtSema;
+
+ Bool noAccel;
+ Bool hwCursor;
+ Bool cursorDefined;
+ int cursorSema;
+ Bool cursorExcludedForUpdate;
+ Bool cursorShouldBeHidden;
+
+ unsigned int cursorRemoveFromFB;
+ unsigned int cursorRestoreToFB;
+
+#ifdef RENDER
+ CompositeProcPtr Composite;
+ void (*EnableDisableFBAccess)(int, Bool);
+#endif /* RENDER */
+
+ unsigned long mmioPhysBase;
+ unsigned long mmioSize;
+
+ unsigned char* mmioVirtBase;
+ CARD32* vmwareFIFO;
+
+ xf86CursorInfoPtr CursorInfoRec;
+ CursorPtr oldCurs;
+ struct {
+ int bg, fg, x, y;
+ int hotX, hotY;
+ BoxRec box;
+
+ uint32 mask[SVGA_BITMAP_SIZE(MAX_CURS, MAX_CURS)];
+ uint32 maskPixmap[SVGA_PIXMAP_SIZE(MAX_CURS, MAX_CURS, 32)];
+ uint32 source[SVGA_BITMAP_SIZE(MAX_CURS, MAX_CURS)];
+ uint32 sourcePixmap[SVGA_PIXMAP_SIZE(MAX_CURS, MAX_CURS, 32)];
+ } hwcur;
+
+ unsigned long indexReg, valueReg;
+
+ ScreenRec ScrnFuncs;
+
+ /*
+ * Xinerama state
+ */
+ Bool xinerama;
+ Bool xineramaStatic;
+
+ VMWAREXineramaPtr xineramaState;
+ unsigned int xineramaNumOutputs;
+
+ VMWAREXineramaPtr xineramaNextState;
+ unsigned int xineramaNextNumOutputs;
+
+ /*
+ * Xv
+ */
+ DevUnion *videoStreams;
+
+} VMWARERec, *VMWAREPtr;
+
+#define VMWAREPTR(p) ((VMWAREPtr)((p)->driverPrivate))
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define ABS(x) (((x) >= 0) ? (x) : -(x))
+
+#define BOX_INTERSECT(a, b) \
+ (ABS(((a).x1 + (a).x2) - ((b).x1 + (b).x2)) <= \
+ ((a).x2 - (a).x1) + ((b).x2 - (b).x1) && \
+ ABS(((a).y1 + (a).y2) - ((b).y1 + (b).y2)) <= \
+ ((a).y2 - (a).y1) + ((b).y2 - (b).y1))
+
+#define SVGA_GLYPH_SCANLINE_SIZE_DWORDS(w) (((w) + 31) >> 5)
+
+#define PRE_OP_HIDE_CURSOR() \
+ if (pVMWARE->cursorDefined && *pVMWARE->pvtSema) { \
+ pVMWARE->cursorSema++; \
+ if (pVMWARE->cursorSema == 1) { \
+ vmwareWriteCursorRegs(pVMWARE, FALSE, FALSE); \
+ } \
+ }
+#define POST_OP_SHOW_CURSOR() \
+ if (pVMWARE->cursorDefined && *pVMWARE->pvtSema) { \
+ pVMWARE->cursorSema--; \
+ if (!pVMWARE->cursorSema && !pVMWARE->cursorShouldBeHidden) { \
+ vmwareWriteCursorRegs(pVMWARE, TRUE, FALSE); \
+ } \
+ }
+
+#define MOUSE_ID 1
+
+/* Undefine this to kill all acceleration */
+#define ACCELERATE_OPS
+
+#if XSERVER_LIBPCIACCESS
+#define VENDOR_ID(p) (p)->vendor_id
+#define DEVICE_ID(p) (p)->device_id
+#define SUBVENDOR_ID(p) (p)->subvendor_id
+#define SUBSYS_ID(p) (p)->subdevice_id
+#define CHIP_REVISION(p) (p)->revision
+#else
+#define VENDOR_ID(p) (p)->vendor
+#define DEVICE_ID(p) (p)->chipType
+#define SUBVENDOR_ID(p) (p)->subsysVendor
+#define SUBSYS_ID(p) (p)->subsysCard
+#define CHIP_REVISION(p) (p)->chipRev
+#endif
+
+void vmwareWriteReg(
+ VMWAREPtr pVMWARE, int index, CARD32 value
+ );
+
+CARD32 vmwareReadReg(
+ VMWAREPtr pVMWARE, int index
+ );
+
+void vmwareWriteWordToFIFO(
+ VMWAREPtr pVMWARE, CARD32 value
+ );
+
+void vmwareWaitForFB(
+ VMWAREPtr pVMWARE
+ );
+
+void vmwareSendSVGACmdUpdate(
+ VMWAREPtr pVMWARE, BoxPtr pBB
+ );
+
+void vmwareSendSVGACmdUpdateFullScreen(
+ VMWAREPtr pVMWARE
+ );
+
+DisplayModeRec *VMWAREAddDisplayMode(
+ ScrnInfoPtr pScrn,
+ const char *name,
+ int width,
+ int height
+ );
+
+Bool vmwareIsRegionEqual(
+ const RegionPtr reg1,
+ const RegionPtr reg2
+ );
+
+void vmwareNextXineramaState(
+ VMWAREPtr pVMWARE
+ );
+
+/* vmwarecurs.c */
+Bool vmwareCursorInit(
+ ScreenPtr pScr
+ );
+
+void vmwareCursorModeInit(
+ ScrnInfoPtr pScrn,
+ DisplayModePtr mode
+ );
+
+void vmwareCursorCloseScreen(
+ ScreenPtr pScr
+ );
+
+void vmwareWriteCursorRegs(
+ VMWAREPtr pVMWARE,
+ Bool visible,
+ Bool force
+ );
+
+void vmwareCursorHookWrappers(
+ ScreenPtr pScreen
+ );
+
+
+/* vmwarectrl.c */
+void VMwareCtrl_ExtInit(ScrnInfoPtr pScrn);
+
+/* vmwarexinerama.c */
+void VMwareXinerama_ExtInit(ScrnInfoPtr pScrn);
+
+/* vmwarevideo.c */
+Bool vmwareVideoInit(
+ ScreenPtr pScreen
+ );
+void vmwareVideoEnd(
+ ScreenPtr pScreen
+ );
+Bool vmwareVideoEnabled(
+ VMWAREPtr pVMWARE
+ );
+
+void vmwareCheckVideoSanity(
+ ScrnInfoPtr pScrn
+ );
+
+/* vmwaremode.c */
+void vmwareAddDefaultMode(
+ ScrnInfoPtr pScrn,
+ uint32 dwidth,
+ uint32 dheight
+ );
+#endif
diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c
new file mode 100644
index 0000000..ea5be19
--- /dev/null
+++ b/src/vmware_bootstrap.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2011 VMWare, 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 TUNGSTEN GRAPHICS 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.
+ *
+ * Author: Unknown at vmware
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "compiler.h"
+#include "xf86Pci.h" /* pci */
+#include "vm_device_version.h"
+#include "vmware_bootstrap.h"
+
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
+#include "xf86Resources.h"
+#endif
+
+#ifndef XSERVER_LIBPCIACCESS
+#include "vm_basic_types.h"
+#include "svga_reg.h"
+#endif
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+#ifdef HaveDriverFuncs
+#define VMWARE_DRIVER_FUNC HaveDriverFuncs
+#else
+#define VMWARE_DRIVER_FUNC 0
+#endif
+
+/*
+ * So that the file compiles unmodified when dropped in to a < 6.9 source tree.
+ */
+#ifndef _X_EXPORT
+#define _X_EXPORT
+#endif
+/*
+ * So that the file compiles unmodified when dropped into an xfree source tree.
+ */
+#ifndef XORG_VERSION_CURRENT
+#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
+#endif
+
+/*
+ * This is the only way I know to turn a #define of an integer constant into
+ * a constant string.
+ */
+#define VMW_INNERSTRINGIFY(s) #s
+#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
+
+#define VMWARE_NAME "vmware"
+#define VMWARE_DRIVER_NAME "vmware"
+#define VMWARE_DRIVER_VERSION \
+ (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
+#define VMWARE_DRIVER_VERSION_STRING \
+ VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
+ "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
+
+static const char VMWAREBuildStr[] = "VMware Guest X Server "
+ VMWARE_DRIVER_VERSION_STRING " - build=$Name$\n";
+
+/*
+ * Standard four digit version string expected by VMware Tools installer.
+ * As the driver's version is only {major, minor, patchlevel},
+ * The fourth digit may describe the commit number relative to the
+ * last version tag as output from `git describe`
+ */
+
+#ifdef __GNUC__
+#ifdef VMW_SUBPATCH
+const char vmware_drv_modinfo[]
+__attribute__((section(".modinfo"),unused)) =
+ "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
+#else
+const char vmware_drv_modinfo[]
+__attribute__((section(".modinfo"),unused)) =
+ "version=" VMWARE_DRIVER_VERSION_STRING ".0";
+#endif /*VMW_SUBPATCH*/
+#endif
+
+#ifndef XSERVER_LIBPCIACCESS
+static resRange vmwareLegacyRes[] = {
+ { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
+ SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
+ _VGA_EXCLUSIVE, _END
+};
+#else
+#define vmwareLegacyRes NULL
+#endif
+
+#if XSERVER_LIBPCIACCESS
+#define VENDOR_ID(p) (p)->vendor_id
+#define DEVICE_ID(p) (p)->device_id
+#define SUBVENDOR_ID(p) (p)->subvendor_id
+#define SUBSYS_ID(p) (p)->subdevice_id
+#define CHIP_REVISION(p) (p)->revision
+#else
+#define VENDOR_ID(p) (p)->vendor
+#define DEVICE_ID(p) (p)->chipType
+#define SUBVENDOR_ID(p) (p)->subsysVendor
+#define SUBSYS_ID(p) (p)->subsysCard
+#define CHIP_REVISION(p) (p)->chipRev
+#endif
+
+#if XSERVER_LIBPCIACCESS
+
+#define VMWARE_DEVICE_MATCH(d, i) \
+ {PCI_VENDOR_ID_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+
+static const struct pci_id_match VMwareDeviceMatch[] = {
+ VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA2, 0 ),
+ VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA, 0 ),
+ { 0, 0, 0 },
+};
+#endif
+
+/*
+ * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
+ * MEMSE for the SVGA resources. Thus, RES_EXCLUSIVE_VGA is required.
+ *
+ * The 0710 chip also uses hardcoded IO ports that aren't disablable.
+ */
+
+static PciChipsets VMWAREPciChipsets[] = {
+ { PCI_DEVICE_ID_VMWARE_SVGA2, PCI_DEVICE_ID_VMWARE_SVGA2, RES_EXCLUSIVE_VGA },
+ { PCI_DEVICE_ID_VMWARE_SVGA, PCI_DEVICE_ID_VMWARE_SVGA, vmwareLegacyRes },
+ { -1, -1, RES_UNDEFINED }
+};
+
+static SymTabRec VMWAREChipsets[] = {
+ { PCI_DEVICE_ID_VMWARE_SVGA2, "vmware0405" },
+ { PCI_DEVICE_ID_VMWARE_SVGA, "vmware0710" },
+ { -1, NULL }
+};
+
+#ifdef XFree86LOADER
+static XF86ModuleVersionInfo vmwareVersRec = {
+ VMWARE_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ { 0, 0, 0, 0}
+};
+#endif /* XFree86LOADER */
+
+static const OptionInfoRec VMWAREOptions[] = {
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XINERAMA, "Xinerama", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
+ { OPTION_GUI_LAYOUT, "GuiLayout", OPTV_STRING, {0}, FALSE },
+ { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_DIRECT_PRESENTS, "DirectPresents", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_HW_PRESENTS, "HWPresents", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_RENDERCHECK, "RenderCheck", OPTV_BOOLEAN, {0}, FALSE},
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+OptionInfoPtr VMWARECopyOptions(void)
+{
+ OptionInfoPtr options;
+ if (!(options = malloc(sizeof(VMWAREOptions))))
+ return NULL;
+
+ memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
+ return options;
+}
+
+static Bool
+VMwarePreinitStub(ScrnInfoPtr pScrn, int flags)
+{
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *pciInfo;
+#else
+ pciVideoPtr pciInfo;
+#endif /* XSERVER_LIBPCIACCESS */
+ EntityInfoPtr pEnt;
+
+ pScrn->PreInit = pScrn->driverPrivate;
+
+#ifdef BUILD_VMWGFX
+ pScrn->driverPrivate = NULL;
+
+ /*
+ * Try vmwgfx path.
+ */
+ if ((*pScrn->PreInit)(pScrn, flags))
+ return TRUE;
+
+#else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Driver was compiled without KMS- and 3D support.\n");
+#endif /* defined(BUILD_VMWGFX) */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling 3D support.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling Render Acceleration.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling RandR12+ support.\n");
+
+ pScrn->driverPrivate = NULL;
+ vmwlegacy_hookup(pScrn);
+
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ pciInfo = xf86GetPciInfoForEntity(pEnt->index);
+ if (pciInfo == NULL)
+ return FALSE;
+
+ pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets,
+ DEVICE_ID(pciInfo));
+
+ return (*pScrn->PreInit)(pScrn, flags);
+};
+
+#if XSERVER_LIBPCIACCESS
+static Bool
+VMwarePciProbe (DriverPtr drv,
+ int entity_num,
+ struct pci_device *device,
+ intptr_t match_data)
+{
+ ScrnInfoPtr scrn = NULL;
+ EntityInfoPtr entity;
+
+ scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ if (scrn != NULL) {
+ scrn->driverVersion = VMWARE_DRIVER_VERSION;
+ scrn->driverName = VMWARE_DRIVER_NAME;
+ scrn->name = VMWARE_NAME;
+ scrn->Probe = NULL;
+ }
+
+ entity = xf86GetEntityInfo(entity_num);
+ switch (DEVICE_ID(device)) {
+ case PCI_DEVICE_ID_VMWARE_SVGA2:
+ case PCI_DEVICE_ID_VMWARE_SVGA:
+ xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n");
+
+#ifdef BUILD_VMWGFX
+ vmwgfx_hookup(scrn);
+#else
+ vmwlegacy_hookup(scrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+ scrn->driverPrivate = scrn->PreInit;
+ scrn->PreInit = VMwarePreinitStub;
+ break;
+ default:
+ xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n");
+ }
+ return scrn != NULL;
+}
+#else
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RewriteTagString --
+ *
+ * Rewrites the given string, removing the $Name$, and
+ * replacing it with the contents. The output string must
+ * have enough room, or else.
+ *
+ * Results:
+ *
+ * Output string updated.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RewriteTagString(const char *istr, char *ostr, int osize)
+{
+ int chr;
+ Bool inTag = FALSE;
+ char *op = ostr;
+
+ do {
+ chr = *istr++;
+ if (chr == '$') {
+ if (inTag) {
+ inTag = FALSE;
+ for (; op > ostr && op[-1] == ' '; op--) {
+ }
+ continue;
+ }
+ if (strncmp(istr, "Name:", 5) == 0) {
+ istr += 5;
+ istr += strspn(istr, " ");
+ inTag = TRUE;
+ continue;
+ }
+ }
+ *op++ = chr;
+ } while (chr);
+}
+
+static Bool
+VMWAREProbe(DriverPtr drv, int flags)
+{
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+ Bool foundScreen = FALSE;
+ char buildString[sizeof(VMWAREBuildStr)];
+
+ RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
+ xf86MsgVerb(X_PROBED, 4, "%s", buildString);
+
+ numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
+ if (numDevSections <= 0) {
+#ifdef DEBUG
+ xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
+#endif
+ return FALSE;
+ }
+ if (xf86GetPciVideoInfo()) {
+ VmwareLog(("Some PCI Video Info Exists\n"));
+ numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_ID_VMWARE,
+ VMWAREChipsets, VMWAREPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ free(devSections);
+ if (numUsed <= 0)
+ return FALSE;
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+
+ VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
+ pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+ VMWAREPciChipsets, NULL, NULL, NULL,
+ NULL, NULL);
+ if (pScrn) {
+ VmwareLog(("And even configuration suceeded\n"));
+ pScrn->driverVersion = VMWARE_DRIVER_VERSION;
+ pScrn->driverName = VMWARE_DRIVER_NAME;
+ pScrn->name = VMWARE_NAME;
+ pScrn->Probe = VMWAREProbe;
+
+#ifdef BUILD_VMWGFX
+ vmwgfx_hookup(pScrn);
+#else
+ vmwlegacy_hookup(pScrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+ pScrn->driverPrivate = pScrn->PreInit;
+ pScrn->PreInit = VMwarePreinitStub;
+ foundScreen = TRUE;
+ }
+ }
+ free(usedChips);
+ }
+ return foundScreen;
+}
+#endif
+
+static void
+VMWAREIdentify(int flags)
+{
+ xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
+}
+
+static const OptionInfoRec *
+VMWAREAvailableOptions(int chipid, int busid)
+{
+ return VMWAREOptions;
+}
+
+#if VMWARE_DRIVER_FUNC
+static Bool
+VMWareDriverFunc(ScrnInfoPtr pScrn,
+ xorgDriverFuncOp op,
+ pointer data)
+{
+ CARD32 *flag;
+ xorgRRModeMM *modemm;
+
+ switch (op) {
+ case GET_REQUIRED_HW_INTERFACES:
+ flag = (CARD32 *)data;
+
+ if (flag) {
+ *flag = HW_IO | HW_MMIO;
+ }
+ return TRUE;
+ case RR_GET_MODE_MM:
+ modemm = (xorgRRModeMM *)data;
+
+ /*
+ * Because changing the resolution of the guest is usually changing the size
+ * of a window on the host desktop, the real physical DPI will not change. To
+ * keep the guest in sync, we scale the 'physical' screen dimensions to
+ * keep the DPI constant.
+ */
+ if (modemm && modemm->mode) {
+ modemm->mmWidth = (modemm->mode->HDisplay * VMWARE_INCHTOMM +
+ pScrn->xDpi / 2) / pScrn->xDpi;
+ modemm->mmHeight = (modemm->mode->VDisplay * VMWARE_INCHTOMM +
+ pScrn->yDpi / 2) / pScrn->yDpi;
+ }
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+#endif
+
+
+_X_EXPORT DriverRec vmware = {
+ VMWARE_DRIVER_VERSION,
+ VMWARE_DRIVER_NAME,
+ VMWAREIdentify,
+#if XSERVER_LIBPCIACCESS
+ NULL,
+#else
+ VMWAREProbe,
+#endif
+ VMWAREAvailableOptions,
+ NULL,
+ 0,
+#if VMWARE_DRIVER_FUNC
+ VMWareDriverFunc,
+#endif
+#if XSERVER_LIBPCIACCESS
+ VMwareDeviceMatch,
+ VMwarePciProbe,
+#endif
+};
+
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(vmwareSetup);
+
+_X_EXPORT XF86ModuleData vmwareModuleData = {
+ &vmwareVersRec,
+ vmwareSetup,
+ NULL
+};
+
+static pointer
+vmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+
+ xf86AddDriver(&vmware, module, VMWARE_DRIVER_FUNC);
+
+ VMWARERefSymLists();
+
+ return (pointer)1;
+ }
+ if (errmaj) {
+ *errmaj = LDR_ONCEONLY;
+ }
+ return NULL;
+}
+#endif /* XFree86LOADER */
diff --git a/src/vmware_bootstrap.h b/src/vmware_bootstrap.h
new file mode 100644
index 0000000..f72d298
--- /dev/null
+++ b/src/vmware_bootstrap.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 VMWare, 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 TUNGSTEN GRAPHICS 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.
+ *
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+#ifndef _VMWARE_BOOTSTRAP_H_
+#define _VMWARE_BOOTSTRAP_H_
+
+#include <xf86.h>
+
+#define VMWARE_INCHTOMM 25.4
+
+typedef enum {
+ OPTION_HW_CURSOR,
+ OPTION_XINERAMA,
+ OPTION_STATIC_XINERAMA,
+ OPTION_GUI_LAYOUT,
+ OPTION_DEFAULT_MODE,
+ OPTION_RENDER_ACCEL,
+ OPTION_DRI,
+ OPTION_DIRECT_PRESENTS,
+ OPTION_HW_PRESENTS,
+ OPTION_RENDERCHECK
+} VMWAREOpts;
+
+OptionInfoPtr VMWARECopyOptions(void);
+
+void
+vmwlegacy_hookup(ScrnInfoPtr pScrn);
+
+#ifdef BUILD_VMWGFX
+void
+vmwgfx_hookup(ScrnInfoPtr pScrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+#ifdef XFree86LOADER
+void
+VMWARERefSymLists(void);
+#endif /* XFree86LOADER */
+
+/*#define DEBUG_LOGGING*/
+#ifdef DEBUG_LOGGING
+# define VmwareLog(args) ErrorF args
+# define TRACEPOINT VmwareLog(("%s : %s\n", __FUNCTION__, __FILE__));
+#else
+# define VmwareLog(args)
+# define TRACEPOINT
+#endif
+
+#endif
diff --git a/src/vmware_common.c b/src/vmware_common.c
new file mode 100644
index 0000000..6ef7ca6
--- /dev/null
+++ b/src/vmware_common.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2011 VMWare, 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 TUNGSTEN GRAPHICS 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.
+ *
+ * Author: Unknown at vmware
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86.h>
+#include "vmware_common.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+static int
+VMWAREParseTopologyElement(ScrnInfoPtr pScrn,
+ unsigned int output,
+ const char *elementName,
+ const char *element,
+ const char *expectedTerminators,
+ Bool needTerminator,
+ unsigned int *outValue)
+{
+ char buf[10] = {0, };
+ size_t i = 0;
+ int retVal = -1;
+ const char *str = element;
+
+ for (i = 0; str[i] >= '0' && str[i] <= '9'; i++);
+ if (i == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unable to parse %s.\n",
+ output, elementName);
+ goto exit;
+ }
+
+ strncpy(buf, str, i);
+ *outValue = atoi(buf);
+
+ if (*outValue > (unsigned short)-1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %s must be less than %hu.\n",
+ output, elementName, (unsigned short)-1);
+ goto exit;
+ }
+
+ str += i;
+
+ if (needTerminator || str[0] != '\0') {
+ Bool unexpected = TRUE;
+
+ for (i = 0; i < strlen(expectedTerminators); i++) {
+ if (str[0] == expectedTerminators[i]) {
+ unexpected = FALSE;
+ }
+ }
+
+ if (unexpected) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Output %u: unexpected character '%c' after %s.\n",
+ output, str[0], elementName);
+ goto exit;
+ } else {
+ str++;
+ }
+ }
+
+ retVal = str - element;
+
+ exit:
+ return retVal;
+}
+
+xXineramaScreenInfo *
+VMWAREParseTopologyString(ScrnInfoPtr pScrn,
+ const char *topology,
+ unsigned int *retNumOutputs,
+ const char info[])
+{
+ xXineramaScreenInfo *extents = NULL;
+ unsigned int numOutputs = 0;
+ const char *str = topology;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Starting...\n",
+ info);
+
+ do {
+ unsigned int x, y, width, height;
+ int i;
+
+ i = VMWAREParseTopologyElement(pScrn, numOutputs, "width", str, "xX", TRUE, &width);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ i = VMWAREParseTopologyElement(pScrn, numOutputs, "height", str, "+", TRUE, &height);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ i= VMWAREParseTopologyElement(pScrn, numOutputs, "X offset", str, "+", TRUE, &x);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ i = VMWAREParseTopologyElement(pScrn, numOutputs, "Y offset", str, ";", FALSE, &y);
+ if (i == -1) {
+ goto error;
+ }
+ str += i;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %ux%u+%u+%u\n",
+ numOutputs, width, height, x, y);
+
+ numOutputs++;
+ extents = realloc(extents, numOutputs * sizeof (xXineramaScreenInfo));
+ extents[numOutputs - 1].x_org = x;
+ extents[numOutputs - 1].y_org = y;
+ extents[numOutputs - 1].width = width;
+ extents[numOutputs - 1].height = height;
+ } while (*str != 0);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Succeeded.\n",
+ info);
+ goto exit;
+
+ error:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Failed.\n",
+ info);
+
+ free(extents);
+ extents = NULL;
+ numOutputs = 0;
+
+ exit:
+ *retNumOutputs = numOutputs;
+ return extents;
+}
diff --git a/src/vmware_common.h b/src/vmware_common.h
new file mode 100644
index 0000000..5629c10
--- /dev/null
+++ b/src/vmware_common.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 VMWare, 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 TUNGSTEN GRAPHICS 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.
+ *
+ * Author: Unknown at vmware
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+
+#ifndef _VMWARE_COMMON_H_
+#define _VMWARE_COMMON_H_
+
+#include <X11/extensions/panoramiXproto.h>
+#include <xf86.h>
+
+#include "compat-api.h"
+
+xXineramaScreenInfo *
+VMWAREParseTopologyString(ScrnInfoPtr pScrn,
+ const char *topology,
+ unsigned int *retNumOutputs,
+ const char info[]);
+
+#endif
diff --git a/src/vmwarectrl.c b/src/vmwarectrl.c
new file mode 100644
index 0000000..d31bef6
--- /dev/null
+++ b/src/vmwarectrl.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright 2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwarectrl.c --
+ *
+ * The implementation of the VMWARE_CTRL protocol extension that
+ * allows X clients to communicate with the driver.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "randrstr.h"
+#include <X11/X.h>
+#include <X11/extensions/panoramiXproto.h>
+
+#include "vmware.h"
+#include "vmwarectrlproto.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlQueryVersion --
+ *
+ * Implementation of QueryVersion command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareCtrlQueryVersion(ClientPtr client)
+{
+ xVMwareCtrlQueryVersionReply rep = { 0, };
+ register int n;
+
+ REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = VMWARE_CTRL_MAJOR_VERSION;
+ rep.minorVersion = VMWARE_CTRL_MINOR_VERSION;
+ if (client->swapped) {
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.majorVersion, n);
+ _swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xVMwareCtrlQueryVersionReply), (char *)&rep);
+
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlDoSetRes --
+ *
+ * Set the custom resolution into the mode list.
+ *
+ * This is done by alternately updating one of two dynamic modes. It is
+ * done this way because the server gets upset if you try to switch
+ * to a new resolution that has the same index as the current one.
+ *
+ * Results:
+ * TRUE on success, FALSE otherwise.
+ *
+ * Side effects:
+ * One dynamic mode will be updated if successful.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+VMwareCtrlDoSetRes(ScrnInfoPtr pScrn,
+ CARD32 x,
+ CARD32 y,
+ Bool resetXinerama)
+{
+ int modeIndex;
+ DisplayModePtr mode;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ if (pScrn && pScrn->modes) {
+ VmwareLog(("DoSetRes: %d %d\n", x, y));
+
+ if (resetXinerama) {
+ free(pVMWARE->xineramaNextState);
+ pVMWARE->xineramaNextState = NULL;
+ pVMWARE->xineramaNextNumOutputs = 0;
+ }
+
+ /*
+ * Don't resize larger than possible but don't
+ * return an X Error either.
+ */
+ if (x > pVMWARE->maxWidth ||
+ y > pVMWARE->maxHeight) {
+ return TRUE;
+ }
+
+ /*
+ * Find an dynamic mode which isn't current, and replace it with
+ * the requested mode. Normally this will cause us to alternate
+ * between two dynamic mode slots, but there are some important
+ * corner cases to consider. For example, adding the same mode
+ * multiple times, adding a mode that we never switch to, or
+ * adding a mode which is a duplicate of a built-in mode. The
+ * best way to handle all of these cases is to directly test the
+ * dynamic mode against the current mode pointer for this
+ * screen.
+ */
+
+ for (modeIndex = 0; modeIndex < NUM_DYN_MODES; modeIndex++) {
+ /*
+ * Initialise the dynamic mode if it hasn't been used before.
+ */
+ if (!pVMWARE->dynModes[modeIndex]) {
+ pVMWARE->dynModes[modeIndex] = VMWAREAddDisplayMode(pScrn, "DynMode", 1, 1);
+ }
+
+ mode = pVMWARE->dynModes[modeIndex];
+ if (mode != pScrn->currentMode) {
+ break;
+ }
+ }
+
+ mode->HDisplay = x;
+ mode->VDisplay = y;
+
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlSetRes --
+ *
+ * Implementation of SetRes command handler. Initialises and sends a
+ * reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareCtrlSetRes(ClientPtr client)
+{
+ REQUEST(xVMwareCtrlSetResReq);
+ xVMwareCtrlSetResReply rep = { 0, };
+ ScrnInfoPtr pScrn;
+ ExtensionEntry *ext;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq);
+
+ if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+
+ pScrn = ext->extPrivate;
+ if (pScrn->scrnIndex != stuff->screen) {
+ return BadMatch;
+ }
+
+ if (!VMwareCtrlDoSetRes(pScrn, stuff->x, stuff->y, TRUE)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = (sizeof(xVMwareCtrlSetResReply) - sizeof(xGenericReply)) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.screen = stuff->screen;
+ rep.x = stuff->x;
+ rep.y = stuff->y;
+ if (client->swapped) {
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.screen, n);
+ _swapl(&rep.x, n);
+ _swapl(&rep.y, n);
+ }
+ WriteToClient(client, sizeof(xVMwareCtrlSetResReply), (char *)&rep);
+
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlDoSetTopology --
+ *
+ * Set the custom topology and set a dynamic mode to the bounding box
+ * of the passed topology. If a topology is already pending, then do
+ * nothing but do not return failure.
+ *
+ * Results:
+ * TRUE on success, FALSE otherwise.
+ *
+ * Side effects:
+ * One dynamic mode and the pending xinerama state will be updated if
+ * successful.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static Bool
+VMwareCtrlDoSetTopology(ScrnInfoPtr pScrn,
+ xXineramaScreenInfo *extents,
+ unsigned long number)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ if (pVMWARE && pVMWARE->xinerama) {
+ VMWAREXineramaPtr xineramaState;
+ short maxX = 0;
+ short maxY = 0;
+ size_t i;
+
+ if (pVMWARE->xineramaNextState) {
+ VmwareLog(("DoSetTopology: Aborting due to existing pending state\n"));
+ return TRUE;
+ }
+
+ for (i = 0; i < number; i++) {
+ maxX = MAX(maxX, extents[i].x_org + extents[i].width);
+ maxY = MAX(maxY, extents[i].y_org + extents[i].height);
+ }
+
+ VmwareLog(("DoSetTopology: %d %d\n", maxX, maxY));
+
+ xineramaState = (VMWAREXineramaPtr)calloc(number, sizeof(VMWAREXineramaRec));
+ if (xineramaState) {
+ memcpy(xineramaState, extents, number * sizeof (VMWAREXineramaRec));
+
+ /*
+ * Make this the new pending Xinerama state. Normally we'll
+ * wait until the next mode switch in order to synchronously
+ * push this state out to X clients and the virtual hardware.
+ *
+ * However, if we're already in the right video mode, there
+ * will be no mode change. In this case, push it out
+ * immediately.
+ */
+ free(pVMWARE->xineramaNextState);
+ pVMWARE->xineramaNextState = xineramaState;
+ pVMWARE->xineramaNextNumOutputs = number;
+
+ if (maxX == pVMWARE->ModeReg.svga_reg_width &&
+ maxY == pVMWARE->ModeReg.svga_reg_height) {
+
+ /*
+ * The annoyance here is that when we reprogram the
+ * SVGA device's monitor topology registers, it may
+ * rearrange those monitors on the host's screen, but they
+ * will still have the old contents. This might be
+ * correct, but it isn't guaranteed to match what's on X's
+ * framebuffer at the moment. So we'll send a
+ * full-framebuffer update rect afterwards.
+ */
+
+ vmwareNextXineramaState(pVMWARE);
+#ifdef HAVE_XORG_SERVER_1_2_0
+ RRSendConfigNotify(pScrn->pScreen);
+#endif
+ vmwareSendSVGACmdUpdateFullScreen(pVMWARE);
+
+ return TRUE;
+ } else {
+ return VMwareCtrlDoSetRes(pScrn, maxX, maxY, FALSE);
+ }
+
+ } else {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlSetTopology --
+ *
+ * Implementation of SetTopology command handler. Initialises and sends a
+ * reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareCtrlSetTopology(ClientPtr client)
+{
+ REQUEST(xVMwareCtrlSetTopologyReq);
+ xVMwareCtrlSetTopologyReply rep = { 0, };
+ ScrnInfoPtr pScrn;
+ ExtensionEntry *ext;
+ register int n;
+ xXineramaScreenInfo *extents;
+
+ REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq);
+
+ if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+
+ pScrn = ext->extPrivate;
+ if (pScrn->scrnIndex != stuff->screen) {
+ return BadMatch;
+ }
+
+ extents = (xXineramaScreenInfo *)(stuff + 1);
+ if (!VMwareCtrlDoSetTopology(pScrn, extents, stuff->number)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = (sizeof(xVMwareCtrlSetTopologyReply) - sizeof(xGenericReply)) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.screen = stuff->screen;
+ if (client->swapped) {
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.screen, n);
+ }
+ WriteToClient(client, sizeof(xVMwareCtrlSetTopologyReply), (char *)&rep);
+
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlDispatch --
+ *
+ * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for
+ * each command type.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of individual command handlers.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareCtrlDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch(stuff->data) {
+ case X_VMwareCtrlQueryVersion:
+ return VMwareCtrlQueryVersion(client);
+ case X_VMwareCtrlSetRes:
+ return VMwareCtrlSetRes(client);
+ case X_VMwareCtrlSetTopology:
+ return VMwareCtrlSetTopology(client);
+ }
+ return BadRequest;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareCtrlQueryVersion --
+ *
+ * Wrapper for QueryVersion handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareCtrlQueryVersion(ClientPtr client)
+{
+ register int n;
+
+ REQUEST(xVMwareCtrlQueryVersionReq);
+ REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq);
+
+ _swaps(&stuff->length, n);
+
+ return VMwareCtrlQueryVersion(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareCtrlSetRes --
+ *
+ * Wrapper for SetRes handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareCtrlSetRes(ClientPtr client)
+{
+ register int n;
+
+ REQUEST(xVMwareCtrlSetResReq);
+ REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq);
+
+ _swaps(&stuff->length, n);
+ _swapl(&stuff->screen, n);
+ _swapl(&stuff->x, n);
+ _swapl(&stuff->y, n);
+
+ return VMwareCtrlSetRes(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareCtrlSetTopology --
+ *
+ * Wrapper for SetTopology handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareCtrlSetTopology(ClientPtr client)
+{
+ register int n;
+
+ REQUEST(xVMwareCtrlSetTopologyReq);
+ REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq);
+
+ _swaps(&stuff->length, n);
+ _swapl(&stuff->screen, n);
+ _swapl(&stuff->number, n);
+ /* Each extent is a struct of shorts. */
+ SwapRestS(stuff);
+
+ return VMwareCtrlSetTopology(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareCtrlDispatch --
+ *
+ * Wrapper for dispatcher that handles input from other-endian clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of individual command handlers.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareCtrlDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch(stuff->data) {
+ case X_VMwareCtrlQueryVersion:
+ return SVMwareCtrlQueryVersion(client);
+ case X_VMwareCtrlSetRes:
+ return SVMwareCtrlSetRes(client);
+ case X_VMwareCtrlSetTopology:
+ return SVMwareCtrlSetTopology(client);
+ }
+ return BadRequest;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrlResetProc --
+ *
+ * Cleanup handler called when the extension is removed.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+VMwareCtrlResetProc(ExtensionEntry* extEntry)
+{
+ /* Currently, no cleanup is necessary. */
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrl_ExitInit --
+ *
+ * Initialiser for the VMWARE_CTRL protocol extension.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Protocol extension will be registered if successful.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+VMwareCtrl_ExtInit(ScrnInfoPtr pScrn)
+{
+ ExtensionEntry *myext;
+
+ if (!(myext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
+ if (!(myext = AddExtension(VMWARE_CTRL_PROTOCOL_NAME, 0, 0,
+ VMwareCtrlDispatch,
+ SVMwareCtrlDispatch,
+ VMwareCtrlResetProc,
+ StandardMinorOpcode))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to add VMWARE_CTRL extension\n");
+ return;
+ }
+
+ /*
+ * For now, only support one screen as that's all the virtual
+ * hardware supports.
+ */
+ myext->extPrivate = pScrn;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initialized VMWARE_CTRL extension version %d.%d\n",
+ VMWARE_CTRL_MAJOR_VERSION, VMWARE_CTRL_MINOR_VERSION);
+ }
+}
diff --git a/src/vmwarectrl.h b/src/vmwarectrl.h
new file mode 100644
index 0000000..a671ae1
--- /dev/null
+++ b/src/vmwarectrl.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwarectrl.h --
+ *
+ * The definitions used by the VMWARE_CTRL protocol extension that
+ * allows X clients to communicate with the driver.
+ */
+
+
+#ifndef _VMWARE_CTRL_H_
+#define _VMWARE_CTRL_H_
+
+#define VMWARE_CTRL_PROTOCOL_NAME "VMWARE_CTRL"
+
+#define VMWARE_CTRL_MAJOR_VERSION 0
+#define VMWARE_CTRL_MINOR_VERSION 2
+
+#define X_VMwareCtrlQueryVersion 0
+#define X_VMwareCtrlSetRes 1
+#define X_VMwareCtrlSetTopology 2
+
+#endif /* _VMWARE_CTRL_H_ */
diff --git a/src/vmwarectrlproto.h b/src/vmwarectrlproto.h
new file mode 100644
index 0000000..76f157f
--- /dev/null
+++ b/src/vmwarectrlproto.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwarectrlproto.h --
+ *
+ * The description of the VMWARE_CTRL protocol extension that
+ * allows X clients to communicate with the driver.
+ */
+
+#ifndef _VMWARE_CTRL_PROTO_H_
+#define _VMWARE_CTRL_PROTO_H_
+
+
+#include <X11/X.h>
+#include "vmwarectrl.h"
+
+
+/*
+ * Requests and Replies
+ */
+
+/* Version 0.1 definitions. */
+
+typedef struct {
+ CARD8 reqType; /* always X_VMwareCtrlReqCode */
+ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlQueryVersion */
+ CARD16 length B16;
+ CARD32 majorVersion B32;
+ CARD32 minorVersion B32;
+} xVMwareCtrlQueryVersionReq;
+#define sz_xVMwareCtrlQueryVersionReq 12
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 majorVersion B32;
+ CARD32 minorVersion B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xVMwareCtrlQueryVersionReply;
+#define sz_xVMwareCtrlQueryVersionReply 32
+
+typedef struct {
+ CARD8 reqType; /* always X_VMwareCtrlReqCode */
+ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlSetRes */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 x B32;
+ CARD32 y B32;
+} xVMwareCtrlSetResReq;
+#define sz_xVMwareCtrlSetResReq 16
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 screen B32;
+ CARD32 x B32;
+ CARD32 y B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+} xVMwareCtrlSetResReply;
+#define sz_xVMwareCtrlSetResReply 32
+
+/* Version 0.2 definitions. */
+
+typedef struct {
+ CARD8 reqType; /* always X_VMwareCtrlReqCode */
+ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlSetTopology */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 number B32;
+ CARD32 pad1 B32;
+} xVMwareCtrlSetTopologyReq;
+#define sz_xVMwareCtrlSetTopologyReq 16
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 screen B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xVMwareCtrlSetTopologyReply;
+#define sz_xVMwareCtrlSetTopologyReply 32
+
+#endif /* _VMWARE_CTRL_PROTO_H_ */
diff --git a/src/vmwarecurs.c b/src/vmwarecurs.c
new file mode 100644
index 0000000..93dacc0
--- /dev/null
+++ b/src/vmwarecurs.c
@@ -0,0 +1,487 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_vmwarecurs[] =
+ "Id: vmwarecurs.c,v 1.5 2001/01/30 23:33:02 bennett Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmware.h"
+#include "vmware_common.h"
+#include "bits2pixels.h"
+
+static void VMWAREGetImage(DrawablePtr src, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask,
+ char *pBinImage);
+static void VMWARECopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+#ifdef RENDER
+static void VMWAREComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, INT16 xSrc, INT16 ySrc,
+ INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst,
+ CARD16 width, CARD16 height);
+#endif /* RENDER */
+
+static void
+RedefineCursor(VMWAREPtr pVMWARE)
+{
+ int i;
+
+ VmwareLog(("RedefineCursor\n"));
+
+ pVMWARE->cursorDefined = FALSE;
+
+ /* Define cursor */
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_DEFINE_CURSOR);
+ vmwareWriteWordToFIFO(pVMWARE, MOUSE_ID);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->hwcur.hotX);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->hwcur.hotY);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->CursorInfoRec->MaxWidth);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->CursorInfoRec->MaxHeight);
+ vmwareWriteWordToFIFO(pVMWARE, 1);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->bitsPerPixel);
+
+ /*
+ * Since we have AND and XOR masks rather than 'source' and 'mask',
+ * color expand 'mask' with all zero as its foreground and all one as
+ * its background. This makes 'image & 0 ^ 'source' = source. We
+ * arange for 'image' & 1 ^ 'source' = 'image' below when we clip
+ * 'source' below.
+ */
+ vmwareRaster_BitsToPixels((uint8 *) pVMWARE->hwcur.mask,
+ SVGA_BITMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth),
+ (uint8 *) pVMWARE->hwcur.maskPixmap,
+ SVGA_PIXMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->bitsPerPixel),
+ pVMWARE->bitsPerPixel / 8,
+ pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight, 0, ~0);
+ for (i = 0; i < SVGA_BITMAP_SIZE(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight); i++) {
+ vmwareWriteWordToFIFO(pVMWARE, ~pVMWARE->hwcur.mask[i]);
+ }
+
+ vmwareRaster_BitsToPixels((uint8 *) pVMWARE->hwcur.source,
+ SVGA_BITMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth),
+ (uint8 *) pVMWARE->hwcur.sourcePixmap,
+ SVGA_PIXMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->bitsPerPixel),
+ pVMWARE->bitsPerPixel / 8,
+ pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight,
+ pVMWARE->hwcur.fg, pVMWARE->hwcur.bg);
+ /*
+ * As pointed out above, we need to clip the expanded 'source' against
+ * the expanded 'mask' since we actually have AND and XOR masks in the
+ * virtual hardware. Effectively, 'source' becomes a three color fg/bg/0
+ * pixmap that XORs appropriately.
+ */
+ for (i = 0; i < SVGA_PIXMAP_SIZE(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight,
+ pVMWARE->bitsPerPixel); i++) {
+ pVMWARE->hwcur.sourcePixmap[i] &= ~pVMWARE->hwcur.maskPixmap[i];
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->hwcur.sourcePixmap[i]);
+ }
+
+ /* Sync the FIFO, so that the definition preceeds any use of the cursor */
+ vmwareWaitForFB(pVMWARE);
+ pVMWARE->cursorDefined = TRUE;
+}
+
+static void
+vmwareSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ TRACEPOINT
+
+ if (pVMWARE->hwcur.fg != fg || pVMWARE->hwcur.bg != bg) {
+ VmwareLog(("SetCursorColors(0x%08x, 0x%08x)\n", bg, fg));
+ pVMWARE->hwcur.fg = fg;
+ pVMWARE->hwcur.bg = bg;
+ RedefineCursor(pVMWARE);
+ }
+}
+
+static Bool
+vmwareUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VmwareLog(("UseHWCursor new cursor %p refcnt %i old cursor %p refcnt %i\n",
+ pCurs, pCurs->refcnt, pVMWARE->oldCurs, pVMWARE->oldCurs ? pVMWARE->oldCurs->refcnt : 0));
+ pCurs->refcnt++;
+ if (pVMWARE->oldCurs)
+ FreeCursor(pVMWARE->oldCurs, None);
+ pVMWARE->oldCurs = pCurs;
+
+ pVMWARE->hwcur.hotX = pCurs->bits->xhot;
+ pVMWARE->hwcur.hotY = pCurs->bits->yhot;
+
+ return pScrn->bitsPerPixel > 8;
+}
+
+static void
+vmwareLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src )
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ const int imageSize = SVGA_BITMAP_SIZE(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight);
+ TRACEPOINT
+
+ memcpy(pVMWARE->hwcur.source, src, imageSize * sizeof(uint32));
+ memcpy(pVMWARE->hwcur.mask,
+ src + imageSize * sizeof(uint32), imageSize * sizeof(uint32));
+ RedefineCursor(pVMWARE);
+}
+
+#ifdef ARGB_CURSOR
+#include "cursorstr.h"
+
+static Bool
+vmwareUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VmwareLog(("UseHWCursorARGB new cursor %p refcnt %i old cursor %p refcnt %i\n",
+ pCurs, pCurs->refcnt, pVMWARE->oldCurs, pVMWARE->oldCurs ? pVMWARE->oldCurs->refcnt : 0));
+ pCurs->refcnt++;
+ if (pVMWARE->oldCurs)
+ FreeCursor(pVMWARE->oldCurs, None);
+ pVMWARE->oldCurs = pCurs;
+
+ return pCurs->bits->height <= MAX_CURS &&
+ pCurs->bits->width <= MAX_CURS &&
+ pScrn->bitsPerPixel > 8;
+}
+
+static void
+vmwareLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ CARD32 width = pCurs->bits->width;
+ CARD32 height = pCurs->bits->height;
+ CARD32* image = pCurs->bits->argb;
+ CARD32* imageEnd = image + (width * height);
+
+ pVMWARE->cursorDefined = FALSE;
+
+ pVMWARE->hwcur.hotX = pCurs->bits->xhot;
+ pVMWARE->hwcur.hotY = pCurs->bits->yhot;
+
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_DEFINE_ALPHA_CURSOR);
+ vmwareWriteWordToFIFO(pVMWARE, MOUSE_ID);
+ vmwareWriteWordToFIFO(pVMWARE, pCurs->bits->xhot);
+ vmwareWriteWordToFIFO(pVMWARE, pCurs->bits->yhot);
+ vmwareWriteWordToFIFO(pVMWARE, width);
+ vmwareWriteWordToFIFO(pVMWARE, height);
+
+ while (image != imageEnd) {
+ vmwareWriteWordToFIFO(pVMWARE, *image++);
+ }
+
+ vmwareWaitForFB(pVMWARE);
+ pVMWARE->cursorDefined = TRUE;
+}
+#endif
+
+void
+vmwareWriteCursorRegs(VMWAREPtr pVMWARE, Bool visible, Bool force)
+{
+ int enableVal;
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID, MOUSE_ID);
+ if (visible) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X,
+ pVMWARE->hwcur.x + pVMWARE->hwcur.hotX);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y,
+ pVMWARE->hwcur.y + pVMWARE->hwcur.hotY);
+ }
+
+ if (force) {
+ enableVal = visible ? SVGA_CURSOR_ON_SHOW : SVGA_CURSOR_ON_HIDE;
+ } else {
+ enableVal = visible ? pVMWARE->cursorRestoreToFB :
+ pVMWARE->cursorRemoveFromFB;
+ }
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON, enableVal);
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/* #define DEBUG_LOG_MOUSE_HIDE_SHOW */
+
+static void
+vmwareShowCursor(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef DEBUG_LOG_MOUSE_HIDE_SHOW
+ VmwareLog(("Show: %d %d %d\n", pVMWARE->cursorSema, pVMWARE->cursorDefined,
+ pVMWARE->cursorShouldBeHidden));
+#endif
+ pVMWARE->cursorShouldBeHidden = FALSE;
+ if (pVMWARE->cursorSema == 0 && pVMWARE->cursorDefined) {
+ vmwareWriteCursorRegs(pVMWARE, TRUE, TRUE);
+ }
+}
+
+static void
+vmwareHideCursor(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef DEBUG_LOG_MOUSE_HIDE_SHOW
+ VmwareLog(("Hide: %d %d %d\n", pVMWARE->cursorSema, pVMWARE->cursorDefined,
+ pVMWARE->cursorShouldBeHidden));
+#endif
+ if (pVMWARE->cursorDefined) {
+ vmwareWriteCursorRegs(pVMWARE, FALSE, TRUE);
+ }
+ pVMWARE->cursorShouldBeHidden = TRUE;
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/* #define DEBUG_LOG_MOUSE_MOVE */
+
+static void
+vmwareSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef DEBUG_LOG_MOUSE_MOVE
+ VmwareLog(("Move: %d %d %d\n", pVMWARE->cursorSema, pVMWARE->cursorDefined,
+ pVMWARE->cursorShouldBeHidden));
+#endif
+ /*
+ * We're bad people. We have no concept of a frame (VMWAREAdjustFrame()
+ * is a NOP). The hwcursor code expects us to be frame aware though, so
+ * we have to do this. I'm open to suggestions. I tried not even
+ * hooking AdjustFrame and it didn't help.
+ */
+ pVMWARE->hwcur.x = x + pScrn->frameX0;
+ pVMWARE->hwcur.y = y + pScrn->frameY0;
+ pVMWARE->hwcur.box.x1 = pVMWARE->hwcur.x;
+ pVMWARE->hwcur.box.x2 = pVMWARE->hwcur.x + pVMWARE->CursorInfoRec->MaxWidth;
+ pVMWARE->hwcur.box.y1 = pVMWARE->hwcur.y;
+ pVMWARE->hwcur.box.y2 = pVMWARE->hwcur.y + pVMWARE->CursorInfoRec->MaxHeight;
+
+ vmwareShowCursor(pScrn);
+}
+
+void
+vmwareCursorModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ if (pVMWARE->cursorDefined) {
+ vmwareWriteCursorRegs(pVMWARE, !pVMWARE->cursorShouldBeHidden, TRUE);
+ }
+}
+
+Bool
+vmwareCursorInit(ScreenPtr pScreen)
+{
+ xf86CursorInfoPtr infoPtr;
+ VMWAREPtr pVMWARE = VMWAREPTR(xf86ScreenToScrn(pScreen));
+ Bool ret;
+
+ TRACEPOINT
+
+ /* Require cursor bypass for hwcursor. Ignore deprecated FIFO hwcursor */
+ if (!(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS)) {
+ return FALSE;
+ }
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ pVMWARE->CursorInfoRec = infoPtr;
+ pVMWARE->oldCurs = NULL;
+
+ infoPtr->MaxWidth = MAX_CURS;
+ infoPtr->MaxHeight = MAX_CURS;
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_UPDATE_UNHIDDEN |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ infoPtr->SetCursorColors = vmwareSetCursorColors;
+ infoPtr->SetCursorPosition = vmwareSetCursorPosition;
+ infoPtr->LoadCursorImage = vmwareLoadCursorImage;
+ infoPtr->HideCursor = vmwareHideCursor;
+ infoPtr->ShowCursor = vmwareShowCursor;
+ infoPtr->UseHWCursor = vmwareUseHWCursor;
+
+#ifdef ARGB_CURSOR
+ if (pVMWARE->vmwareCapability & SVGA_CAP_ALPHA_CURSOR) {
+ infoPtr->UseHWCursorARGB = vmwareUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = vmwareLoadCursorARGB;
+ }
+#endif
+
+ ret = xf86InitCursor(pScreen, infoPtr);
+ if (!ret) {
+ xf86DestroyCursorInfoRec(infoPtr);
+ pVMWARE->CursorInfoRec = NULL;
+ }
+ return ret;
+}
+
+void
+vmwareCursorCloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ pScreen->GetImage = pVMWARE->ScrnFuncs.GetImage;
+ pScreen->CopyWindow = pVMWARE->ScrnFuncs.CopyWindow;
+#ifdef RENDER
+ if (ps) {
+ ps->Composite = pVMWARE->Composite;
+ }
+#endif /* RENDER */
+
+ vmwareHideCursor(pScrn);
+ if (pVMWARE->oldCurs)
+ FreeCursor(pVMWARE->oldCurs, None);
+ pVMWARE->oldCurs = NULL;
+ xf86DestroyCursorInfoRec(pVMWARE->CursorInfoRec);
+}
+
+/*** Wrap functions that read from the framebuffer ***/
+
+void
+vmwareCursorHookWrappers(ScreenPtr pScreen)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(xf86ScreenToScrn(pScreen));
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ TRACEPOINT
+
+ pVMWARE->ScrnFuncs.GetImage = pScreen->GetImage;
+ pVMWARE->ScrnFuncs.CopyWindow = pScreen->CopyWindow;
+ pScreen->GetImage = VMWAREGetImage;
+ pScreen->CopyWindow = VMWARECopyWindow;
+
+#ifdef RENDER
+ if (ps) {
+ pVMWARE->Composite = ps->Composite;
+ ps->Composite = VMWAREComposite;
+ }
+#endif /* RENDER */
+
+}
+
+static void
+VMWAREGetImage(DrawablePtr src, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *pBinImage)
+{
+ ScreenPtr pScreen = src->pScreen;
+ VMWAREPtr pVMWARE = VMWAREPTR(xf86ScreenToScrn(src->pScreen));
+ BoxRec box;
+ Bool hidden = FALSE;
+
+ VmwareLog(("VMWAREGetImage(%p, %d, %d, %d, %d, %d, %d, %p)\n",
+ src, x, y, w, h, format, planeMask, pBinImage));
+
+ box.x1 = src->x + x;
+ box.y1 = src->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+
+ if (BOX_INTERSECT(box, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ hidden = TRUE;
+ }
+
+ pScreen->GetImage = pVMWARE->ScrnFuncs.GetImage;
+ (*pScreen->GetImage)(src, x, y, w, h, format, planeMask, pBinImage);
+ pScreen->GetImage = VMWAREGetImage;
+
+ if (hidden) {
+ POST_OP_SHOW_CURSOR();
+ }
+}
+
+static void
+VMWARECopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VMWAREPtr pVMWARE = VMWAREPTR(xf86ScreenToScrn(pWin->drawable.pScreen));
+ BoxPtr pBB;
+ Bool hidden = FALSE;
+
+ /*
+ * We only worry about the source region here, since shadowfb will
+ * take care of the destination region.
+ */
+ pBB = REGION_EXTENTS(pWin->drawable.pScreen, prgnSrc);
+
+ VmwareLog(("VMWARECopyWindow(%p, (%d, %d), (%d, %d - %d, %d)\n",
+ pWin, ptOldOrg.x, ptOldOrg.y,
+ pBB->x1, pBB->y1, pBB->x2, pBB->y2));
+
+ if (BOX_INTERSECT(*pBB, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ hidden = TRUE;
+ }
+
+ pScreen->CopyWindow = pVMWARE->ScrnFuncs.CopyWindow;
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+ pScreen->CopyWindow = VMWARECopyWindow;
+
+ if (hidden) {
+ POST_OP_SHOW_CURSOR();
+ }
+}
+
+#ifdef RENDER
+static void
+VMWAREComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, INT16 xSrc, INT16 ySrc,
+ INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst,
+ CARD16 width, CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ VMWAREPtr pVMWARE = VMWAREPTR(xf86ScreenToScrn(pScreen));
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec box;
+ Bool hidden = FALSE;
+
+ if (pSrc->pDrawable) {
+ VmwareLog(("VMWAREComposite op = %d, pSrc = %p, pMask = %p, pDst = %p,"
+ " src = (%d, %d), mask = (%d, %d), dst = (%d, %d), w = %d,"
+ " h = %d\n", op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height));
+
+ /*
+ * We only worry about the source region here, since shadowfb or XAA
+ * will take care of the destination region.
+ */
+ box.x1 = pSrc->pDrawable->x + xSrc;
+ box.y1 = pSrc->pDrawable->y + ySrc;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ if (BOX_INTERSECT(box, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ hidden = TRUE;
+ }
+ }
+
+ ps->Composite = pVMWARE->Composite;
+ (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ ps->Composite = VMWAREComposite;
+
+ if (hidden) {
+ POST_OP_SHOW_CURSOR();
+ }
+}
+#endif /* RENDER */
diff --git a/src/vmwaremodes.c b/src/vmwaremodes.c
new file mode 100644
index 0000000..2965dca
--- /dev/null
+++ b/src/vmwaremodes.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2007 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwaremodes.c --
+ *
+ * Provide additional modes for the driver.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "xf86.h"
+#ifdef HAVE_XORG_SERVER_1_2_0
+#include <xf86Modes.h>
+#endif
+#include "vm_basic_types.h"
+#include "vmware.h"
+
+#ifndef M_T_DRIVER
+# define M_T_DRIVER 0x40 /* Supplied by the driver (EDID, etc) */
+#endif
+
+#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER
+#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
+
+#define VMW_DEFLT_MODE_NAME "vmwlegacy-default-%dx%d"
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareAddDefaultMode --
+ *
+ * Add a default mode with the current screen dimensions.
+ *
+ * Results:
+ * The default mode.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+vmwareAddDefaultMode(ScrnInfoPtr pScrn, uint32 dwidth, uint32 dheight)
+{
+ DisplayModePtr *monitorModes = &pScrn->monitor->Modes;
+ DisplayModePtr modes = NULL;
+
+ if (monitorModes == NULL || *monitorModes == NULL) {
+ goto out_err;
+ }
+
+#ifdef HAVE_XORG_SERVER_1_2_0
+ if (dwidth && dheight) {
+ MonPtr monitor = pScrn->monitor;
+ DisplayModePtr mode = NULL;
+ DisplayModeRec dynamic =
+ { MODEPREFIX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX };
+ unsigned dispModeCount = 0;
+ char **dispModeList;
+ char *dynModeName;
+ char name[80];
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ /* First, add the default mode name to the display mode
+ * requests.
+ */
+
+ snprintf(name, sizeof(name), VMW_DEFLT_MODE_NAME, dwidth, dheight);
+
+ dynModeName = xnfstrdup(name);
+ if (!dynModeName || !pScrn->display)
+ goto out_err;
+
+ if (pScrn->display->modes) {
+ dispModeList = pScrn->display->modes;
+ while(*dispModeList)
+ dispModeList++;
+ dispModeCount = dispModeList - pScrn->display->modes;
+ }
+
+ dispModeList = xnfcalloc(dispModeCount + 2, sizeof(*dispModeList));
+ if (!dispModeList)
+ goto out_err;
+
+ memcpy(dispModeList, pScrn->display->modes,
+ dispModeCount * sizeof(*dispModeList));
+ dispModeList[dispModeCount] = dynModeName;
+ pScrn->display->modes = dispModeList;
+
+ /* Then, add the default mode itself.
+ */
+
+ dynamic.name = name;
+ dynamic.HDisplay = dwidth;
+ dynamic.HSyncStart = dynamic.HDisplay + 1;
+ dynamic.HSyncEnd = dynamic.HSyncStart + 1;
+ dynamic.HTotal = dynamic.HSyncEnd * 5 / 4;
+ dynamic.VDisplay = dheight;
+ dynamic.VSyncStart = dynamic.VDisplay + 1;
+ dynamic.VSyncEnd = dynamic.VSyncStart + 1;
+ dynamic.VTotal = dynamic.VSyncEnd + 1;
+ if (monitor->nVrefresh > 0)
+ dynamic.VRefresh = monitor->vrefresh[0].lo;
+ else
+ dynamic.VRefresh = 60;
+ dynamic.Clock = dynamic.VRefresh * dynamic.VTotal *
+ dynamic.HTotal / 1000;
+ mode = xf86DuplicateMode(&dynamic);
+ modes = xf86ModesAdd(modes, mode);
+
+ if (dispModeCount == 0) {
+
+ /*
+ * Set up a large virtual size, so that we allow also
+ * setting modes larger than the initial mode.
+ *
+ * We might also want to consider the case where
+ * dispModeCount != 0, but the requested display modes
+ * are not available. This is sufficient for now.
+ */
+
+ if (pScrn->display->virtualX == 0)
+ pScrn->display->virtualX = pVMWARE->maxWidth;
+ if (pScrn->display->virtualY == 0)
+ pScrn->display->virtualY = pVMWARE->maxHeight;
+ }
+ }
+
+ *monitorModes = xf86ModesAdd(*monitorModes, modes);
+#else
+ (void) modes;
+#endif
+ return;
+ out_err:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to add default mode.");
+}
diff --git a/src/vmwarevideo.c b/src/vmwarevideo.c
new file mode 100644
index 0000000..745c71f
--- /dev/null
+++ b/src/vmwarevideo.c
@@ -0,0 +1,1352 @@
+/*
+ * Copyright 2007 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwarevideo.c --
+ *
+ * Xv extension support.
+ * See http://www.xfree86.org/current/DESIGN16.html
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmware.h"
+#include "vmware_common.h"
+#include "xf86xv.h"
+#include "fourcc.h"
+#include "svga_escape.h"
+#include "svga_overlay.h"
+
+#include <X11/extensions/Xv.h>
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+
+#define HAVE_FILLKEYHELPERDRAWABLE \
+ ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 2) || \
+ ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) == 1) && \
+ (GET_ABI_MINOR(ABI_VIDEODRV_VERSION) >= 2)))
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+/*
+ * Used to pack structs
+ */
+#define PACKED __attribute__((__packed__))
+
+/*
+ * Number of videos that can be played simultaneously
+ */
+#define VMWARE_VID_NUM_PORTS 1
+
+/*
+ * Using a dark shade as the default colorKey
+ */
+#define VMWARE_VIDEO_COLORKEY 0x100701
+
+/*
+ * Maximum dimensions
+ */
+#define VMWARE_VID_MAX_WIDTH 2048
+#define VMWARE_VID_MAX_HEIGHT 2048
+
+#define VMWARE_VID_NUM_ENCODINGS 1
+static XF86VideoEncodingRec vmwareVideoEncodings[] =
+{
+ {
+ 0,
+ "XV_IMAGE",
+ VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+#define VMWARE_VID_NUM_FORMATS 2
+static XF86VideoFormatRec vmwareVideoFormats[] =
+{
+ { 16, TrueColor},
+ { 24, TrueColor}
+};
+
+#define VMWARE_VID_NUM_IMAGES 3
+static XF86ImageRec vmwareVideoImages[] =
+{
+ XVIMAGE_YV12,
+ XVIMAGE_YUY2,
+ XVIMAGE_UYVY
+};
+
+#define VMWARE_VID_NUM_ATTRIBUTES 2
+static XF86AttributeRec vmwareVideoAttributes[] =
+{
+ {
+ XvGettable | XvSettable,
+ 0x000000,
+ 0xffffff,
+ "XV_COLORKEY"
+ },
+ {
+ XvGettable | XvSettable,
+ 0,
+ 1,
+ "XV_AUTOPAINT_COLORKEY"
+ }
+};
+
+/*
+ * Video frames are stored in a circular list of buffers.
+ */
+#define VMWARE_VID_NUM_BUFFERS 1
+/*
+ * Defines the structure used to hold and pass video data to the host
+ */
+typedef struct {
+ uint32 dataOffset;
+ pointer data;
+} VMWAREVideoBuffer;
+
+typedef struct {
+ uint32 size;
+ uint32 offset;
+} VMWAREOffscreenRec, *VMWAREOffscreenPtr;
+
+/*
+ * Trivial offscreen manager that allocates memory from the
+ * bottom of the VRAM.
+ */
+static VMWAREOffscreenRec offscreenMgr;
+
+/*
+ * structs that reside in fmt_priv.
+ */
+typedef struct {
+ int pitches[3];
+ int offsets[3];
+} VMWAREVideoFmtData;
+
+/*
+ * Structure representing a specific video stream.
+ */
+struct VMWAREVideoRec {
+ uint32 streamId;
+ /*
+ * Function prototype same as XvPutImage.
+ */
+ int (*play)(ScrnInfoPtr, struct VMWAREVideoRec *,
+ short, short, short, short, short,
+ short, short, short, int, unsigned char*,
+ short, short, RegionPtr, DrawablePtr);
+ /*
+ * Offscreen memory region used to pass video data to the host.
+ */
+ VMWAREOffscreenPtr fbarea;
+ VMWAREVideoBuffer bufs[VMWARE_VID_NUM_BUFFERS];
+ uint8 currBuf;
+ uint32 size;
+ uint32 colorKey;
+ Bool isAutoPaintColorkey;
+ uint32 flags;
+ RegionRec clipBoxes;
+ VMWAREVideoFmtData *fmt_priv;
+};
+
+typedef struct VMWAREVideoRec VMWAREVideoRec;
+typedef VMWAREVideoRec *VMWAREVideoPtr;
+
+/*
+ * Callback functions
+ */
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
+static int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int image,
+ unsigned char *buf, short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data,
+ DrawablePtr dst);
+#else
+static int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int image,
+ unsigned char *buf, short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data);
+#endif
+static void vmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup);
+static int vmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
+ unsigned short *width,
+ unsigned short *height, int *pitches,
+ int *offsets);
+static int vmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, pointer data);
+static int vmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 *value, pointer data);
+static void vmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
+ short vid_w, short vid_h, short drw_w,
+ short drw_h, unsigned int *p_w,
+ unsigned int *p_h, pointer data);
+
+/*
+ * Local functions for video streams
+ */
+static XF86VideoAdaptorPtr vmwareVideoSetup(ScrnInfoPtr pScrn);
+static int vmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
+ short src_x, short src_y, short drw_x,
+ short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int format,
+ unsigned char *buf, short width,
+ short height, RegionPtr clipBoxes,
+ DrawablePtr draw);
+static int vmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
+ int format, unsigned short width,
+ unsigned short height);
+static int vmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
+ short src_x, short src_y, short drw_x,
+ short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int format,
+ unsigned char *buf, short width,
+ short height, RegionPtr clipBoxes,
+ DrawablePtr draw);
+static void vmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId);
+static void vmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
+ uint32 regId, uint32 value);
+static void vmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid);
+
+/*
+ * Offscreen memory manager functions
+ */
+static void vmwareOffscreenInit(void);
+static VMWAREOffscreenPtr vmwareOffscreenAllocate(VMWAREPtr pVMWARE,
+ uint32 size);
+static void vmwareOffscreenFree(VMWAREOffscreenPtr memptr);
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareCheckVideoSanity --
+ *
+ * Ensures that on ModeSwitch the offscreen memory used
+ * by the Xv streams doesn't become part of the guest framebuffer.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * If it is found that the offscreen used by video streams lies
+ * within the range of the framebuffer(after ModeSwitch) then the video
+ * streams will be stopped.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+vmwareCheckVideoSanity(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWAREVideoPtr pVid;
+
+ if (offscreenMgr.size == 0 ||
+ offscreenMgr.offset > pVMWARE->FbSize) {
+ return ;
+ }
+
+ pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
+ vmwareStopVideo(pScrn, pVid, TRUE);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareOffscreenInit --
+ *
+ * Initializes the trivial Offscreen memory manager.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Initializes the Offscreen manager meta-data structure.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareOffscreenInit(void)
+{
+ offscreenMgr.size = 0;
+ offscreenMgr.offset = 0;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareOffscreenAllocate --
+ *
+ * Allocates offscreen memory.
+ * Memory is allocated from the bottom part of the VRAM.
+ * The memory manager is trivial iand can handle only 1 video-stream.
+ * ----------
+ * | |
+ * | FB |
+ * | |
+ * |---------
+ * | |
+ * | |
+ * |--------|
+ * | Offscr |
+ * |--------|
+ *
+ * VRAM
+ *
+ * Results:
+ * Pointer to the allocated Offscreen memory.
+ *
+ * Side effects:
+ * Updates the Offscreen memory manager meta-data structure.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static VMWAREOffscreenPtr
+vmwareOffscreenAllocate(VMWAREPtr pVMWARE, uint32 size)
+{
+ VMWAREOffscreenPtr memptr;
+
+ if ((pVMWARE->videoRam - pVMWARE->FbSize - pVMWARE->fbPitch - 7) < size) {
+ return NULL;
+ }
+
+ memptr = malloc(sizeof(VMWAREOffscreenRec));
+ if (!memptr) {
+ return NULL;
+ }
+ memptr->size = size;
+ memptr->offset = (pVMWARE->videoRam - size) & ~7;
+
+ VmwareLog(("vmwareOffscreenAllocate: Offset:%x", memptr->offset));
+
+ offscreenMgr.size = memptr->size;
+ offscreenMgr.offset = memptr->offset;
+ return memptr;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareOffscreenFree --
+ *
+ * Frees the allocated offscreen memory.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Updates the Offscreen memory manager meta-data structure.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareOffscreenFree(VMWAREOffscreenPtr memptr)
+{
+ if (memptr) {
+ free(memptr);
+ }
+
+ offscreenMgr.size = 0;
+ offscreenMgr.offset = 0;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoEnabled --
+ *
+ * Checks if Video FIFO and Escape FIFO cap are enabled.
+ *
+ * Results:
+ * TRUE if required caps are enabled, FALSE otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+vmwareVideoEnabled(VMWAREPtr pVMWARE)
+{
+ return ((pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO) &&
+ (pVMWARE->vmwareFIFO[SVGA_FIFO_CAPABILITIES] &
+ (SVGA_FIFO_CAP_VIDEO | SVGA_FIFO_CAP_ESCAPE)));
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoInit --
+ *
+ * Initializes Xv support.
+ *
+ * Results:
+ * TRUE on success, FALSE on error.
+ *
+ * Side effects:
+ * Xv support is initialized. Memory is allocated for all supported
+ * video streams.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+vmwareVideoInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ int numAdaptors;
+
+ TRACEPOINT
+
+ vmwareOffscreenInit();
+
+ numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors);
+
+ newAdaptor = vmwareVideoSetup(pScrn);
+ if (!newAdaptor) {
+ VmwareLog(("Failed to initialize Xv extension \n"));
+ return FALSE;
+ }
+
+ if (!numAdaptors) {
+ numAdaptors = 1;
+ overlayAdaptors = &newAdaptor;
+ } else {
+ newAdaptors = malloc((numAdaptors + 1) *
+ sizeof(XF86VideoAdaptorPtr*));
+ if (!newAdaptors) {
+ xf86XVFreeVideoAdaptorRec(newAdaptor);
+ return FALSE;
+ }
+
+ memcpy(newAdaptors, overlayAdaptors,
+ numAdaptors * sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[numAdaptors++] = newAdaptor;
+ overlayAdaptors = newAdaptors;
+ }
+
+ if (!xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors)) {
+ VmwareLog(("Failed to initialize Xv extension\n"));
+ xf86XVFreeVideoAdaptorRec(newAdaptor);
+ return FALSE;
+ }
+
+ if (newAdaptors) {
+ free(newAdaptors);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initialized VMware Xv extension successfully.\n");
+ return TRUE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoEnd --
+ *
+ * Unitializes video.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * pVMWARE->videoStreams = NULL
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+vmwareVideoEnd(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWAREVideoPtr pVid;
+ int i;
+
+ TRACEPOINT
+
+ /*
+ * Video streams are allocated after the DevUnion array
+ * (see VideoSetup)
+ */
+ pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
+ for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
+ vmwareVideoEndStream(pScrn, &pVid[i]);
+ REGION_UNINIT(pScreen, &pVid[i].clipBoxes);
+ }
+
+ free(pVMWARE->videoStreams);
+ pVMWARE->videoStreams = NULL;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoSetup --
+ *
+ * Initializes a XF86VideoAdaptor structure with the capabilities and
+ * functions supported by this video driver.
+ *
+ * Results:
+ * On success initialized XF86VideoAdaptor struct or NULL on error
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static XF86VideoAdaptorPtr
+vmwareVideoSetup(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ XF86VideoAdaptorPtr adaptor;
+ VMWAREVideoPtr pPriv;
+ DevUnion *du;
+ int i;
+
+ TRACEPOINT
+
+ adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
+ if (!adaptor) {
+ VmwareLog(("Not enough memory\n"));
+ return NULL;
+ }
+ du = calloc(1, VMWARE_VID_NUM_PORTS *
+ (sizeof(DevUnion) + sizeof(VMWAREVideoRec)));
+
+ if (!du) {
+ VmwareLog(("Not enough memory.\n"));
+ xf86XVFreeVideoAdaptorRec(adaptor);
+ return NULL;
+ }
+
+ adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
+ adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adaptor->name = "VMware Video Engine";
+ adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
+ adaptor->pEncodings = vmwareVideoEncodings;
+ adaptor->nFormats = VMWARE_VID_NUM_FORMATS;
+ adaptor->pFormats = vmwareVideoFormats;
+ adaptor->nPorts = VMWARE_VID_NUM_PORTS;
+
+ pPriv = (VMWAREVideoPtr) &du[VMWARE_VID_NUM_PORTS];
+ adaptor->pPortPrivates = du;
+
+ for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
+ pPriv[i].streamId = i;
+ pPriv[i].play = vmwareVideoInitStream;
+ pPriv[i].flags = SVGA_VIDEO_FLAG_COLORKEY;
+ pPriv[i].colorKey = VMWARE_VIDEO_COLORKEY;
+ pPriv[i].isAutoPaintColorkey = TRUE;
+ REGION_NULL(pScreen, &pPriv[i].clipBoxes);
+ adaptor->pPortPrivates[i].ptr = &pPriv[i];
+ }
+ pVMWARE->videoStreams = du;
+
+ adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES;
+ adaptor->pAttributes = vmwareVideoAttributes;
+
+ adaptor->nImages = VMWARE_VID_NUM_IMAGES;
+ adaptor->pImages = vmwareVideoImages;
+
+ adaptor->PutVideo = NULL;
+ adaptor->PutStill = NULL;
+ adaptor->GetVideo = NULL;
+ adaptor->GetStill = NULL;
+ adaptor->StopVideo = vmwareStopVideo;
+ adaptor->SetPortAttribute = vmwareSetPortAttribute;
+ adaptor->GetPortAttribute = vmwareGetPortAttribute;
+ adaptor->QueryBestSize = vmwareQueryBestSize;
+ adaptor->PutImage = vmwareXvPutImage;
+ adaptor->QueryImageAttributes = vmwareQueryImageAttributes;
+
+ return adaptor;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoInitStream --
+ *
+ * Initializes a video stream in response to the first PutImage() on a
+ * video stream. The process goes as follows:
+ * - Figure out characteristics according to format
+ * - Allocate offscreen memory
+ * - Pass on video to Play() functions
+ *
+ * Results:
+ * Success or XvBadAlloc on failure.
+ *
+ * Side effects:
+ * Video stream is initialized and its first frame sent to the host
+ * (done by VideoPlay() function called at the end)
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
+ short src_x, short src_y, short drw_x,
+ short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int format,
+ unsigned char *buf, short width,
+ short height, RegionPtr clipBoxes,
+ DrawablePtr draw)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ int i;
+
+ TRACEPOINT
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initializing Xv video-stream with id:%d format:%d\n",
+ pVid->streamId, format);
+
+ pVid->size = vmwareVideoInitAttributes(pScrn, pVid, format, width,
+ height);
+
+ if (pVid->size == -1) {
+ VmwareLog(("Could not initialize 0x%x video stream\n", format));
+ return XvBadAlloc;
+ }
+
+ pVid->play = vmwareVideoPlay;
+
+ pVid->fbarea = vmwareOffscreenAllocate(pVMWARE,
+ pVid->size * VMWARE_VID_NUM_BUFFERS);
+
+ if (!pVid->fbarea) {
+ VmwareLog(("Could not allocate offscreen memory\n"));
+ vmwareVideoEndStream(pScrn, pVid);
+ return BadAlloc;
+ }
+
+ pVid->bufs[0].dataOffset = pVid->fbarea->offset;
+ pVid->bufs[0].data = pVMWARE->FbBase + pVid->bufs[0].dataOffset;
+
+ for (i = 1; i < VMWARE_VID_NUM_BUFFERS; ++i) {
+ pVid->bufs[i].dataOffset = pVid->bufs[i-1].dataOffset + pVid->size;
+ pVid->bufs[i].data = pVMWARE->FbBase + pVid->bufs[i].dataOffset;
+ }
+ pVid->currBuf = 0;
+
+ REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
+
+ if (pVid->isAutoPaintColorkey) {
+ BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
+ int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
+
+#if HAVE_FILLKEYHELPERDRAWABLE
+ xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
+#else
+ xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
+#endif
+ /**
+ * Force update to paint the colorkey before the overlay flush.
+ */
+
+ while(nBoxes--)
+ vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
+ }
+
+ VmwareLog(("Got offscreen region, offset %d, size %d "
+ "(yuv size in bytes: %d)\n",
+ pVid->fbarea->offset, pVid->fbarea->size, pVid->size));
+
+ return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
+ drw_w, drw_h, format, buf, width, height, clipBoxes,
+ draw);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoInitAttributes --
+ *
+ * Fetches the format specific attributes using QueryImageAttributes().
+ *
+ * Results:
+ * size of the YUV frame on success and -1 on error.
+ *
+ * Side effects:
+ * The video stream gets the format specific attributes(fmtData).
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
+ int format, unsigned short width,
+ unsigned short height)
+{
+ int size;
+ VMWAREVideoFmtData *fmtData;
+
+ TRACEPOINT
+
+ fmtData = calloc(1, sizeof(VMWAREVideoFmtData));
+ if (!fmtData) {
+ return -1;
+ }
+
+ size = vmwareQueryImageAttributes(pScrn, format, &width, &height,
+ fmtData->pitches, fmtData->offsets);
+ if (size == -1) {
+ free(fmtData);
+ return -1;
+ }
+
+ pVid->fmt_priv = fmtData;
+ return size;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoPlay --
+ *
+ * Sends all the attributes associated with the video frame using the
+ * FIFO ESCAPE mechanism to the host.
+ *
+ * Results:
+ * Always returns Success.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
+ short src_x, short src_y, short drw_x,
+ short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int format,
+ unsigned char *buf, short width,
+ short height, RegionPtr clipBoxes,
+ DrawablePtr draw)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ uint32 *fifoItem;
+ int i, regId;
+ struct PACKED _item {
+ uint32 regId;
+ uint32 value;
+ };
+
+ struct PACKED _body {
+ uint32 escape;
+ uint32 streamId;
+ struct _item items[SVGA_VIDEO_NUM_REGS];
+ };
+
+ struct PACKED _cmdSetRegs {
+ uint32 cmd;
+ uint32 nsid;
+ uint32 size;
+ struct _body body;
+ };
+
+ struct _cmdSetRegs cmdSetRegs;
+ struct _item *items;
+ int size;
+ VMWAREVideoFmtData *fmtData;
+ unsigned short w, h;
+
+ w = width;
+ h = height;
+ fmtData = pVid->fmt_priv;
+
+ size = vmwareQueryImageAttributes(pScrn, format, &w, &h,
+ fmtData->pitches, fmtData->offsets);
+
+ if (size > pVid->size) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Increase in size of Xv video "
+ "frame streamId:%d.\n", pVid->streamId);
+ vmwareStopVideo(pScrn, pVid, TRUE);
+ return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w,
+ src_h, drw_w, drw_h, format, buf, width, height,
+ clipBoxes, draw);
+ }
+
+ pVid->size = size;
+ memcpy(pVid->bufs[pVid->currBuf].data, buf, pVid->size);
+
+ cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
+ cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
+ cmdSetRegs.size = sizeof(cmdSetRegs.body);
+ cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
+ cmdSetRegs.body.streamId = pVid->streamId;
+
+ items = cmdSetRegs.body.items;
+ for (i = SVGA_VIDEO_ENABLED; i < SVGA_VIDEO_NUM_REGS; i++) {
+ items[i].regId = i;
+ }
+
+ items[SVGA_VIDEO_ENABLED].value = TRUE;
+ items[SVGA_VIDEO_DATA_OFFSET].value =
+ pVid->bufs[pVid->currBuf].dataOffset;
+ items[SVGA_VIDEO_SIZE].value = pVid->size;
+ items[SVGA_VIDEO_FORMAT].value = format;
+ items[SVGA_VIDEO_WIDTH].value = w;
+ items[SVGA_VIDEO_HEIGHT].value = h;
+ items[SVGA_VIDEO_SRC_X].value = src_x;
+ items[SVGA_VIDEO_SRC_Y].value = src_y;
+ items[SVGA_VIDEO_SRC_WIDTH].value = src_w;
+ items[SVGA_VIDEO_SRC_HEIGHT].value = src_h;
+ items[SVGA_VIDEO_DST_X].value = drw_x;
+ items[SVGA_VIDEO_DST_Y].value = drw_y;
+ items[SVGA_VIDEO_DST_WIDTH]. value = drw_w;
+ items[SVGA_VIDEO_DST_HEIGHT].value = drw_h;
+ items[SVGA_VIDEO_COLORKEY].value = pVid->colorKey;
+ items[SVGA_VIDEO_FLAGS].value = pVid->flags;
+
+ for (i = 0, regId = SVGA_VIDEO_PITCH_1; i < 3; i++, regId++) {
+ items[regId].value = fmtData->pitches[i];
+ }
+
+ fifoItem = (uint32 *) &cmdSetRegs;
+ for (i = 0; i < sizeof(cmdSetRegs) / sizeof(uint32); i++) {
+ vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
+ }
+
+ /*
+ * Update the clipList and paint the colorkey, if required.
+ */
+ if (!vmwareIsRegionEqual(&pVid->clipBoxes, clipBoxes)) {
+ REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
+ if (pVid->isAutoPaintColorkey) {
+ BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
+ int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
+
+#if HAVE_FILLKEYHELPERDRAWABLE
+ xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
+#else
+ xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
+#endif
+ /**
+ * Force update to paint the colorkey before the overlay flush.
+ */
+
+ while(nBoxes--)
+ vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
+
+ }
+ }
+
+ vmwareVideoFlush(pVMWARE, pVid->streamId);
+
+ pVid->currBuf = ++pVid->currBuf & (VMWARE_VID_NUM_BUFFERS - 1);
+
+ return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoFlush --
+ *
+ * Sends the VIDEO_FLUSH command (FIFO ESCAPE mechanism) asking the host
+ * to play the video stream or end it.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId)
+{
+ struct PACKED _body {
+ uint32 escape;
+ uint32 streamId;
+ };
+
+ struct PACKED _cmdFlush {
+ uint32 cmd;
+ uint32 nsid;
+ uint32 size;
+ struct _body body;
+ };
+
+ struct _cmdFlush cmdFlush;
+ uint32 *fifoItem;
+ int i;
+
+ cmdFlush.cmd = SVGA_CMD_ESCAPE;
+ cmdFlush.nsid = SVGA_ESCAPE_NSID_VMWARE;
+ cmdFlush.size = sizeof(cmdFlush.body);
+ cmdFlush.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
+ cmdFlush.body.streamId = streamId;
+
+ fifoItem = (uint32 *) &cmdFlush;
+ for (i = 0; i < sizeof(cmdFlush) / sizeof(uint32); i++) {
+ vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoSetOneReg --
+ *
+ * Sets one video register using the FIFO ESCAPE mechanidm.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
+ uint32 regId, uint32 value)
+{
+ struct PACKED _item {
+ uint32 regId;
+ uint32 value;
+ };
+
+ struct PACKED _body {
+ uint32 escape;
+ uint32 streamId;
+ struct _item item;
+ };
+
+ struct PACKED _cmdSetRegs {
+ uint32 cmd;
+ uint32 nsid;
+ uint32 size;
+ struct _body body;
+ };
+
+ struct _cmdSetRegs cmdSetRegs;
+ int i;
+ uint32 *fifoItem;
+
+ cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
+ cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
+ cmdSetRegs.size = sizeof(cmdSetRegs.body);
+ cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
+ cmdSetRegs.body.streamId = streamId;
+ cmdSetRegs.body.item.regId = regId;
+ cmdSetRegs.body.item.value = value;
+
+ fifoItem = (uint32 *) &cmdSetRegs;
+ for (i = 0; i < sizeof(cmdSetRegs) / sizeof(uint32); i++) {
+ vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareVideoEndStream --
+ *
+ * Frees up all resources (if any) taken by a video stream.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Same as above.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid)
+{
+ uint32 id, colorKey, flags;
+ Bool isAutoPaintColorkey;
+
+ if (pVid->fmt_priv) {
+ free(pVid->fmt_priv);
+ }
+
+ if (pVid->fbarea) {
+ vmwareOffscreenFree(pVid->fbarea);
+ pVid->fbarea = NULL;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Terminating Xv video-stream id:%d\n", pVid->streamId);
+ /*
+ * reset stream for next video
+ */
+ id = pVid->streamId;
+ colorKey = pVid->colorKey;
+ flags = pVid->flags;
+ isAutoPaintColorkey = pVid->isAutoPaintColorkey;
+
+ memset(pVid, 0, sizeof(*pVid));
+
+ pVid->streamId = id;
+ pVid->play = vmwareVideoInitStream;
+ pVid->colorKey = colorKey;
+ pVid->flags = flags;
+ pVid->isAutoPaintColorkey = isAutoPaintColorkey;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareXvPutImage --
+ *
+ * Main video playback function. It copies the passed data which is in
+ * the specified format (e.g. FOURCC_YV12) into the overlay.
+ *
+ * If sync is TRUE the driver should not return from this
+ * function until it is through reading the data from buf.
+ *
+ * There are two function prototypes to cope with the API change in X.org
+ * 7.1
+ *
+ * Results:
+ * Success or XvBadAlloc on failure
+ *
+ * Side effects:
+ * Video stream will be played(initialized if 1st frame) on success
+ * or will fail on error.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
+static int
+vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int format,
+ unsigned char *buf, short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data,
+ DrawablePtr dst)
+#else
+static int
+vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int format,
+ unsigned char *buf, short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data)
+#endif
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWAREVideoPtr pVid = data;
+
+ TRACEPOINT
+
+ if (!vmwareVideoEnabled(pVMWARE)) {
+ return XvBadAlloc;
+ }
+
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
+ return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
+ drw_w, drw_h, format, buf, width, height, clipBoxes,
+ dst);
+#else
+ return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
+ drw_w, drw_h, format, buf, width, height, clipBoxes,
+ NULL);
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareStopVideo --
+ *
+ * Called when we should stop playing video for a particular stream. If
+ * Cleanup is FALSE, the "stop" operation is only temporary, and thus we
+ * don't do anything. If Cleanup is TRUE we kill the video stream by
+ * sending a message to the host and freeing up the stream.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * See above.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup)
+{
+ VMWAREVideoPtr pVid = data;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ TRACEPOINT
+
+ if (!vmwareVideoEnabled(pVMWARE)) {
+ return;
+ }
+
+ REGION_EMPTY(pScrn->pScreen, &pVid->clipBoxes);
+
+ if (!Cleanup) {
+ VmwareLog(("vmwareStopVideo: Cleanup is FALSE.\n"));
+ return;
+ }
+ vmwareVideoSetOneReg(pVMWARE, pVid->streamId,
+ SVGA_VIDEO_ENABLED, FALSE);
+
+ vmwareVideoFlush(pVMWARE, pVid->streamId);
+ vmwareVideoEndStream(pScrn, pVid);
+
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareQueryImageAttributes --
+ *
+ * From the spec: This function is called to let the driver specify how data
+ * for a particular image of size width by height should be stored.
+ * Sometimes only the size and corrected width and height are needed. In
+ * that case pitches and offsets are NULL.
+ *
+ * Results:
+ * The size of the memory required for the image, or -1 on error.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
+ unsigned short *width, unsigned short *height,
+ int *pitches, int *offsets)
+{
+ INT32 size, tmp;
+
+ TRACEPOINT
+
+ if (*width > VMWARE_VID_MAX_WIDTH) {
+ *width = VMWARE_VID_MAX_WIDTH;
+ }
+ if (*height > VMWARE_VID_MAX_HEIGHT) {
+ *height = VMWARE_VID_MAX_HEIGHT;
+ }
+
+ *width = (*width + 1) & ~1;
+ if (offsets != NULL) {
+ offsets[0] = 0;
+ }
+
+ switch (format) {
+ case FOURCC_YV12:
+ *height = (*height + 1) & ~1;
+ size = (*width + 3) & ~3;
+ if (pitches) {
+ pitches[0] = size;
+ }
+ size *= *height;
+ if (offsets) {
+ offsets[1] = size;
+ }
+ tmp = ((*width >> 1) + 3) & ~3;
+ if (pitches) {
+ pitches[1] = pitches[2] = tmp;
+ }
+ tmp *= (*height >> 1);
+ size += tmp;
+ if (offsets) {
+ offsets[2] = size;
+ }
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ size = *width * 2;
+ if (pitches) {
+ pitches[0] = size;
+ }
+ size *= *height;
+ break;
+ default:
+ VmwareLog(("Query for invalid video format %d\n", format));
+ return -1;
+ }
+ return size;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareSetPortAttribute --
+ *
+ * From the spec: A port may have particular attributes such as colorKey, hue,
+ * saturation, brightness or contrast. Xv clients set these
+ * attribute values by sending attribute strings (Atoms) to the server.
+ *
+ * Results:
+ * Success if the attribute exists and XvBadAlloc otherwise.
+ *
+ * Side effects:
+ * The respective attribute gets the new value.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, pointer data)
+{
+ VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
+ Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+
+ if (attribute == xvColorKey) {
+ VmwareLog(("Set colorkey:0x%x\n", value));
+ pVid->colorKey = value;
+ } else if (attribute == xvAutoPaint) {
+ VmwareLog(("Set autoPaint: %s\n", value? "TRUE": "FALSE"));
+ pVid->isAutoPaintColorkey = value;
+ } else {
+ return XvBadAlloc;
+ }
+
+ return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareGetPortAttribute --
+ *
+ * From the spec: A port may have particular attributes such as hue,
+ * saturation, brightness or contrast. Xv clients get these
+ * attribute values by sending attribute strings (Atoms) to the server
+ *
+ * Results:
+ * Success if the attribute exists and XvBadAlloc otherwise.
+ *
+ * Side effects:
+ * "value" contains the requested attribute on success.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 *value, pointer data)
+{
+ VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
+ Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+
+ if (attribute == xvColorKey) {
+ *value = pVid->colorKey;
+ } else if (attribute == xvAutoPaint) {
+ *value = pVid->isAutoPaintColorkey;
+ } else {
+ return XvBadAlloc;
+ }
+
+ return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareQueryBestSize --
+ *
+ * From the spec: QueryBestSize provides the client with a way to query what
+ * the destination dimensions would end up being if they were to request
+ * that an area vid_w by vid_h from the video stream be scaled to rectangle
+ * of drw_w by drw_h on the screen. Since it is not expected that all
+ * hardware will be able to get the target dimensions exactly, it is
+ * important that the driver provide this function.
+ *
+ * This function seems to never be called, but to be on the safe side
+ * we apply the same logic that QueryImageAttributes has for width
+ * and height
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
+ short vid_w, short vid_h, short drw_w,
+ short drw_h, unsigned int *p_w,
+ unsigned int *p_h, pointer data)
+{
+ *p_w = (drw_w + 1) & ~1;
+ *p_h = drw_h;
+
+ return;
+}
+
diff --git a/src/vmwarexinerama.c b/src/vmwarexinerama.c
new file mode 100644
index 0000000..954abdc
--- /dev/null
+++ b/src/vmwarexinerama.c
@@ -0,0 +1,728 @@
+/*
+ * Copyright 2006 by VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwarexinerama.c --
+ *
+ * The implementation of the Xinerama protocol extension.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include <X11/X.h>
+#include <X11/extensions/panoramiXproto.h>
+
+#include "vmware.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+/*
+ * LookupWindow was removed with video abi 11.
+ */
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 4)
+#ifndef DixGetAttrAccess
+#define DixGetAttrAccess (1<<4)
+#endif
+#endif
+
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 2)
+static inline int
+dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
+{
+ *pWin = LookupWindow(id, client);
+ if (!*pWin)
+ return BadWindow;
+ return Success;
+}
+#endif
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaQueryVersion --
+ *
+ * Implementation of QueryVersion command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaQueryVersion(ClientPtr client)
+{
+ xPanoramiXQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = 1;
+ rep.minorVersion = 0;
+ if(client->swapped) {
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swaps(&rep.majorVersion, n);
+ _swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaGetState --
+ *
+ * Implementation of GetState command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+ register int n;
+ ExtensionEntry *ext;
+ ScrnInfoPtr pScrn;
+ VMWAREPtr pVMWARE;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+ pScrn = ext->extPrivate;
+ pVMWARE = VMWAREPTR(pScrn);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = pVMWARE->xinerama;
+ rep.window = stuff->window;
+ if(client->swapped) {
+ _swaps (&rep.sequenceNumber, n);
+ _swapl (&rep.length, n);
+ _swapl (&rep.window, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaGetScreenCount --
+ *
+ * Implementation of GetScreenCount command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+ register int n;
+ ExtensionEntry *ext;
+ ScrnInfoPtr pScrn;
+ VMWAREPtr pVMWARE;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+ pScrn = ext->extPrivate;
+ pVMWARE = VMWAREPTR(pScrn);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.ScreenCount = pVMWARE->xineramaNumOutputs;
+ rep.window = stuff->window;
+
+ if(client->swapped) {
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.window, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaGetScreenSize --
+ *
+ * Implementation of GetScreenSize command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenSizeReply rep;
+ register int n;
+ ExtensionEntry *ext;
+ ScrnInfoPtr pScrn;
+ VMWAREPtr pVMWARE;
+ int rc;
+
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+ pScrn = ext->extPrivate;
+ pVMWARE = VMWAREPTR(pScrn);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.width = pVMWARE->xineramaState[stuff->screen].width;
+ rep.height = pVMWARE->xineramaState[stuff->screen].height;
+ rep.window = stuff->window;
+ rep.screen = stuff->screen;
+ if(client->swapped) {
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.width, n);
+ _swapl(&rep.height, n);
+ _swapl(&rep.window, n);
+ _swapl(&rep.screen, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaIsActive --
+ *
+ * Implementation of IsActive command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaIsActive(ClientPtr client)
+{
+ xXineramaIsActiveReply rep;
+ ExtensionEntry *ext;
+ ScrnInfoPtr pScrn;
+ VMWAREPtr pVMWARE;
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+ pScrn = ext->extPrivate;
+ pVMWARE = VMWAREPTR(pScrn);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = pVMWARE->xinerama;
+ if(client->swapped) {
+ register int n;
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.state, n);
+ }
+ WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaQueryScreens --
+ *
+ * Implementation of QueryScreens command handler. Initialises and
+ * sends a reply.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Writes reply to client.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaQueryScreens(ClientPtr client)
+{
+ xXineramaQueryScreensReply rep;
+ ExtensionEntry *ext;
+ ScrnInfoPtr pScrn;
+ VMWAREPtr pVMWARE;
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) {
+ return BadMatch;
+ }
+ pScrn = ext->extPrivate;
+ pVMWARE = VMWAREPTR(pScrn);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.number = pVMWARE->xinerama ? pVMWARE->xineramaNumOutputs : 0;
+ rep.length = rep.number * sz_XineramaScreenInfo >> 2;
+ if(client->swapped) {
+ register int n;
+ _swaps(&rep.sequenceNumber, n);
+ _swapl(&rep.length, n);
+ _swapl(&rep.number, n);
+ }
+ WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
+
+ if(pVMWARE->xinerama) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < pVMWARE->xineramaNumOutputs; i++) {
+ scratch.x_org = pVMWARE->xineramaState[i].x_org;
+ scratch.y_org = pVMWARE->xineramaState[i].y_org;
+ scratch.width = pVMWARE->xineramaState[i].width;
+ scratch.height = pVMWARE->xineramaState[i].height;
+ if(client->swapped) {
+ register int n;
+ _swaps(&scratch.x_org, n);
+ _swaps(&scratch.y_org, n);
+ _swaps(&scratch.width, n);
+ _swaps(&scratch.height, n);
+ }
+ WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
+ }
+ }
+
+ return client->noClientException;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaDispatch --
+ *
+ * Dispatcher for Xinerama commands. Calls the correct handler for
+ * each command type.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of individual command handlers.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+VMwareXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return VMwareXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return VMwareXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return VMwareXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return VMwareXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return VMwareXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return VMwareXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaQueryVersion --
+ *
+ * Wrapper for QueryVersion handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaQueryVersion (ClientPtr client)
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+ register int n;
+ _swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ return VMwareXineramaQueryVersion(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaGetState --
+ *
+ * Wrapper for GetState handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ register int n;
+ _swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ return VMwareXineramaGetState(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaGetScreenCount --
+ *
+ * Wrapper for GetScreenCount handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ register int n;
+ _swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ return VMwareXineramaGetScreenCount(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaGetScreenSize --
+ *
+ * Wrapper for GetScreenSize handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ register int n;
+ _swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ return VMwareXineramaGetScreenSize(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaIsActive --
+ *
+ * Wrapper for IsActive handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaIsActive(ClientPtr client)
+{
+ REQUEST(xXineramaIsActiveReq);
+ register int n;
+ _swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+ return VMwareXineramaIsActive(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaQueryScreens --
+ *
+ * Wrapper for QueryScreens handler that handles input from other-endian
+ * clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of unswapped implementation.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaQueryScreens(ClientPtr client)
+{
+ REQUEST(xXineramaQueryScreensReq);
+ register int n;
+ _swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+ return VMwareXineramaQueryScreens(client);
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * SVMwareXineramaDispatch --
+ *
+ * Wrapper for dispatcher that handles input from other-endian clients.
+ *
+ * Results:
+ * Standard response codes.
+ *
+ * Side effects:
+ * Side effects of individual command handlers.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static int
+SVMwareXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return SVMwareXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SVMwareXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SVMwareXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SVMwareXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return SVMwareXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return SVMwareXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareXineramaResetProc --
+ *
+ * Cleanup handler called when the extension is removed.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+VMwareXineramaResetProc(ExtensionEntry* extEntry)
+{
+ /* Called by CloseDownExtensions() */
+
+ ScrnInfoPtr pScrn = extEntry->extPrivate;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ if (pVMWARE->xineramaState) {
+ free(pVMWARE->xineramaState);
+ pVMWARE->xineramaState = NULL;
+ pVMWARE->xineramaNumOutputs = 0;
+ pVMWARE->xinerama = FALSE;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------------
+ *
+ * VMwareCtrl_ExitInit --
+ *
+ * Initialiser for the Xinerama protocol extension.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Protocol extension will be registered if successful.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+void
+VMwareXinerama_ExtInit(ScrnInfoPtr pScrn)
+{
+ ExtensionEntry *myext;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Built-in Xinerama active, not initializing VMware Xinerama\n");
+ pVMWARE->xinerama = FALSE;
+ return;
+ }
+#endif
+
+ if (!(myext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) {
+ if (!(myext = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
+ VMwareXineramaDispatch,
+ SVMwareXineramaDispatch,
+ VMwareXineramaResetProc,
+ StandardMinorOpcode))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to add VMware Xinerama extension.\n");
+ return;
+ }
+
+ pVMWARE->xinerama = TRUE;
+
+ myext->extPrivate = pScrn;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initialized VMware Xinerama extension.\n");
+ }
+}