diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/render | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/render')
-rw-r--r-- | xorg-server/render/Makefile.am | 20 | ||||
-rw-r--r-- | xorg-server/render/Makefile.in | 701 | ||||
-rw-r--r-- | xorg-server/render/animcur.c | 409 | ||||
-rw-r--r-- | xorg-server/render/filter.c | 323 | ||||
-rw-r--r-- | xorg-server/render/glyph.c | 770 | ||||
-rw-r--r-- | xorg-server/render/glyphstr.h | 151 | ||||
-rw-r--r-- | xorg-server/render/miindex.c | 358 | ||||
-rw-r--r-- | xorg-server/render/mipict.c | 651 | ||||
-rw-r--r-- | xorg-server/render/mipict.h | 229 | ||||
-rw-r--r-- | xorg-server/render/mirect.c | 185 | ||||
-rw-r--r-- | xorg-server/render/mitrap.c | 189 | ||||
-rw-r--r-- | xorg-server/render/mitri.c | 191 | ||||
-rw-r--r-- | xorg-server/render/picture.c | 1845 | ||||
-rw-r--r-- | xorg-server/render/picture.h | 222 | ||||
-rw-r--r-- | xorg-server/render/picturestr.h | 679 | ||||
-rw-r--r-- | xorg-server/render/render.c | 3317 | ||||
-rw-r--r-- | xorg-server/render/renderedge.c | 91 | ||||
-rw-r--r-- | xorg-server/render/renderedge.h | 105 |
18 files changed, 10436 insertions, 0 deletions
diff --git a/xorg-server/render/Makefile.am b/xorg-server/render/Makefile.am new file mode 100644 index 000000000..e53c7c746 --- /dev/null +++ b/xorg-server/render/Makefile.am @@ -0,0 +1,20 @@ +noinst_LTLIBRARIES = librender.la + +AM_CFLAGS = $(DIX_CFLAGS) + +librender_la_SOURCES = \ + animcur.c \ + filter.c \ + glyph.c \ + miindex.c \ + mipict.c \ + mirect.c \ + mitrap.c \ + mitri.c \ + picture.c \ + render.c \ + renderedge.c + +if XORG +sdk_HEADERS = picture.h mipict.h glyphstr.h picturestr.h renderedge.h +endif diff --git a/xorg-server/render/Makefile.in b/xorg-server/render/Makefile.in new file mode 100644 index 000000000..6dcee4b9d --- /dev/null +++ b/xorg-server/render/Makefile.in @@ -0,0 +1,701 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = render +DIST_COMMON = $(am__sdk_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \ + $(top_builddir)/include/xorg-server.h \ + $(top_builddir)/include/dix-config.h \ + $(top_builddir)/include/xgl-config.h \ + $(top_builddir)/include/xorg-config.h \ + $(top_builddir)/include/xkb-config.h \ + $(top_builddir)/include/xwin-config.h \ + $(top_builddir)/include/kdrive-config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +librender_la_LIBADD = +am_librender_la_OBJECTS = animcur.lo filter.lo glyph.lo miindex.lo \ + mipict.lo mirect.lo mitrap.lo mitri.lo picture.lo render.lo \ + renderedge.lo +librender_la_OBJECTS = $(am_librender_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(librender_la_SOURCES) +DIST_SOURCES = $(librender_la_SOURCES) +am__sdk_HEADERS_DIST = picture.h mipict.h glyphstr.h picturestr.h \ + renderedge.h +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 = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(sdkdir)" +sdkHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(sdk_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ +ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +APPDEFAULTDIR = @APPDEFAULTDIR@ +APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ +APP_MAN_DIR = @APP_MAN_DIR@ +APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASE_FONT_PATH = @BASE_FONT_PATH@ +BUILD_DATE = @BUILD_DATE@ +BUILD_TIME = @BUILD_TIME@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DARWIN_LIBS = @DARWIN_LIBS@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ +DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ +DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DGA_CFLAGS = @DGA_CFLAGS@ +DGA_LIBS = @DGA_LIBS@ +DIX_CFLAGS = @DIX_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@ +DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@ +DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@ +DMXMODULES_LIBS = @DMXMODULES_LIBS@ +DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@ +DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@ +DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@ +DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@ +DRIPROTO_LIBS = @DRIPROTO_LIBS@ +DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ +DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FILE_MAN_DIR = @FILE_MAN_DIR@ +FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ +GLX_DEFINES = @GLX_DEFINES@ +GL_CFLAGS = @GL_CFLAGS@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +HAL_CFLAGS = @HAL_CFLAGS@ +HAL_LIBS = @HAL_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDRIVE_CFLAGS = @KDRIVE_CFLAGS@ +KDRIVE_INCS = @KDRIVE_INCS@ +KDRIVE_LIBS = @KDRIVE_LIBS@ +KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ +KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ +KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ +LAUNCHD = @LAUNCHD@ +LDFLAGS = @LDFLAGS@ +LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAN_DIR = @LIB_MAN_DIR@ +LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MESA_SOURCE = @MESA_SOURCE@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +MKDIR_P = @MKDIR_P@ +MKFONTDIR = @MKFONTDIR@ +MKFONTSCALE = @MKFONTSCALE@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCCLD = @OBJCCLD@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCLINK = @OBJCLINK@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ +PCIACCESS_LIBS = @PCIACCESS_LIBS@ +PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PROJECTROOT = @PROJECTROOT@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +RAWCPP = @RAWCPP@ +RAWCPPFLAGS = @RAWCPPFLAGS@ +SED = @SED@ +SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@ +SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ +STRIP = @STRIP@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ +VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@ +VENDOR_NAME = @VENDOR_NAME@ +VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ +VENDOR_RELEASE = @VENDOR_RELEASE@ +VERSION = @VERSION@ +X11APP_ARCHS = @X11APP_ARCHS@ +X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ +X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XDMCP_CFLAGS = @XDMCP_CFLAGS@ +XDMCP_LIBS = @XDMCP_LIBS@ +XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@ +XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@ +XDMX_CFLAGS = @XDMX_CFLAGS@ +XDMX_LIBS = @XDMX_LIBS@ +XDMX_SYS_LIBS = @XDMX_SYS_LIBS@ +XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@ +XEGL_LIBS = @XEGL_LIBS@ +XEGL_SYS_LIBS = @XEGL_SYS_LIBS@ +XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ +XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@ +XEPHYR_INCS = @XEPHYR_INCS@ +XEPHYR_LIBS = @XEPHYR_LIBS@ +XF86CONFIGFILE = @XF86CONFIGFILE@ +XF86MISC_CFLAGS = @XF86MISC_CFLAGS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@ +XGLMODULES_LIBS = @XGLMODULES_LIBS@ +XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@ +XGLXMODULES_LIBS = @XGLXMODULES_LIBS@ +XGLX_LIBS = @XGLX_LIBS@ +XGLX_SYS_LIBS = @XGLX_SYS_LIBS@ +XGL_LIBS = @XGL_LIBS@ +XGL_MODULE_PATH = @XGL_MODULE_PATH@ +XGL_SYS_LIBS = @XGL_SYS_LIBS@ +XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ +XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ +XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ +XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ +XLIB_CFLAGS = @XLIB_CFLAGS@ +XLIB_LIBS = @XLIB_LIBS@ +XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ +XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ +XNEST_LIBS = @XNEST_LIBS@ +XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ +XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@ +XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@ +XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@ +XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_INCS = @XORG_INCS@ +XORG_LIBS = @XORG_LIBS@ +XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ +XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ +XORG_OS = @XORG_OS@ +XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ +XORG_SYS_LIBS = @XORG_SYS_LIBS@ +XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@ +XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@ +XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@ +XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@ +XPRINT_CFLAGS = @XPRINT_CFLAGS@ +XPRINT_LIBS = @XPRINT_LIBS@ +XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@ +XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ +XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@ +XSDL_INCS = @XSDL_INCS@ +XSDL_LIBS = @XSDL_LIBS@ +XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@ +XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@ +XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@ +XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@ +XSERVER_LIBS = @XSERVER_LIBS@ +XSERVER_SYS_LIBS = @XSERVER_SYS_LIBS@ +XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ +XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ +XVFB_LIBS = @XVFB_LIBS@ +XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ +XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@ +XWINMODULES_LIBS = @XWINMODULES_LIBS@ +XWIN_LIBS = @XWIN_LIBS@ +XWIN_SERVER_NAME = @XWIN_SERVER_NAME@ +XWIN_SYS_LIBS = @XWIN_SYS_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +__XCONFIGFILE__ = @__XCONFIGFILE__@ +abi_ansic = @abi_ansic@ +abi_extension = @abi_extension@ +abi_font = @abi_font@ +abi_videodrv = @abi_videodrv@ +abi_xinput = @abi_xinput@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverdir = @driverdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +extdir = @extdir@ +ft_config = @ft_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +launchagentsdir = @launchagentsdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logdir = @logdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sdkdir = @sdkdir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +xglmoduledir = @xglmoduledir@ +xpconfigdir = @xpconfigdir@ +noinst_LTLIBRARIES = librender.la +AM_CFLAGS = $(DIX_CFLAGS) +librender_la_SOURCES = \ + animcur.c \ + filter.c \ + glyph.c \ + miindex.c \ + mipict.c \ + mirect.c \ + mitrap.c \ + mitri.c \ + picture.c \ + render.c \ + renderedge.c + +@XORG_TRUE@sdk_HEADERS = picture.h mipict.h glyphstr.h picturestr.h renderedge.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 \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign render/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign render/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_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 +librender.la: $(librender_la_OBJECTS) $(librender_la_DEPENDENCIES) + $(LINK) $(librender_la_OBJECTS) $(librender_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/animcur.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyph.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miindex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mipict.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mirect.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mitrap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mitri.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/picture.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renderedge.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-sdkHEADERS: $(sdk_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(sdkdir)" || $(MKDIR_P) "$(DESTDIR)$(sdkdir)" + @list='$(sdk_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(sdkHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(sdkdir)/$$f'"; \ + $(sdkHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(sdkdir)/$$f"; \ + done + +uninstall-sdkHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(sdk_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(sdkdir)/$$f'"; \ + rm -f "$(DESTDIR)$(sdkdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(sdkdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-sdkHEADERS + +install-dvi: install-dvi-am + +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 + +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-sdkHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES 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-sdkHEADERS install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-sdkHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/xorg-server/render/animcur.c b/xorg-server/render/animcur.c new file mode 100644 index 000000000..125928931 --- /dev/null +++ b/xorg-server/render/animcur.c @@ -0,0 +1,409 @@ +/* + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Animated cursors for X. Not specific to Render in any way, but + * stuck there because Render has the other cool cursor extension. + * Besides, everyone has Render. + * + * Implemented as a simple layer over the core cursor code; it + * creates composite cursors out of a set of static cursors and + * delta times between each image. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xmd.h> +#include "servermd.h" +#include "scrnintstr.h" +#include "dixstruct.h" +#include "cursorstr.h" +#include "dixfontstr.h" +#include "opaque.h" +#include "picturestr.h" +#include "xace.h" + +typedef struct _AnimCurElt { + CursorPtr pCursor; /* cursor to show */ + CARD32 delay; /* in ms */ +} AnimCurElt; + +typedef struct _AnimCur { + int nelt; /* number of elements in the elts array */ + AnimCurElt *elts; /* actually allocated right after the structure */ +} AnimCurRec, *AnimCurPtr; + +typedef struct _AnimScrPriv { + CursorPtr pCursor; + int elt; + CARD32 time; + + CloseScreenProcPtr CloseScreen; + + ScreenBlockHandlerProcPtr BlockHandler; + + CursorLimitsProcPtr CursorLimits; + DisplayCursorProcPtr DisplayCursor; + SetCursorPositionProcPtr SetCursorPosition; + RealizeCursorProcPtr RealizeCursor; + UnrealizeCursorProcPtr UnrealizeCursor; + RecolorCursorProcPtr RecolorCursor; +} AnimCurScreenRec, *AnimCurScreenPtr; + +typedef struct _AnimCurState { + CursorPtr pCursor; + ScreenPtr pScreen; + int elt; + CARD32 time; +} AnimCurStateRec, *AnimCurStatePtr; + +static AnimCurStateRec animCurState; + +static unsigned char empty[4]; + +static CursorBits animCursorBits = { + empty, empty, 2, 1, 1, 0, 0, 1 +}; + +static int AnimCurGeneration; +static DevPrivateKey AnimCurScreenPrivateKey = &AnimCurScreenPrivateKey; + +#define IsAnimCur(c) ((c)->bits == &animCursorBits) +#define GetAnimCur(c) ((AnimCurPtr) ((c) + 1)) +#define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey)) +#define GetAnimCurScreenIfSet(s) GetAnimCurScreen(s) +#define SetAnimCurScreen(s,p) dixSetPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey, p) + +#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) +#define Unwrap(as,s,elt) ((s)->elt = (as)->elt) + +static Bool +AnimCurDisplayCursor (ScreenPtr pScreen, + CursorPtr pCursor); + +static Bool +AnimCurSetCursorPosition (ScreenPtr pScreen, + int x, + int y, + Bool generateEvent); + +static Bool +AnimCurCloseScreen (int index, ScreenPtr pScreen) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap(as, pScreen, CloseScreen); + + Unwrap(as, pScreen, BlockHandler); + + Unwrap(as, pScreen, CursorLimits); + Unwrap(as, pScreen, DisplayCursor); + Unwrap(as, pScreen, SetCursorPosition); + Unwrap(as, pScreen, RealizeCursor); + Unwrap(as, pScreen, UnrealizeCursor); + Unwrap(as, pScreen, RecolorCursor); + SetAnimCurScreen(pScreen,0); + ret = (*pScreen->CloseScreen) (index, pScreen); + xfree (as); + return ret; +} + +static void +AnimCurCursorLimits (ScreenPtr pScreen, + CursorPtr pCursor, + BoxPtr pHotBox, + BoxPtr pTopLeftBox) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + + Unwrap (as, pScreen, CursorLimits); + if (IsAnimCur(pCursor)) + { + AnimCurPtr ac = GetAnimCur(pCursor); + + (*pScreen->CursorLimits) (pScreen, ac->elts[0].pCursor, pHotBox, pTopLeftBox); + } + else + { + (*pScreen->CursorLimits) (pScreen, pCursor, pHotBox, pTopLeftBox); + } + Wrap (as, pScreen, CursorLimits, AnimCurCursorLimits); +} + +/* + * This has to be a screen block handler instead of a generic + * block handler so that it is well ordered with respect to the DRI + * block handler responsible for releasing the hardware to DRI clients + */ + +static void +AnimCurScreenBlockHandler (int screenNum, + pointer blockData, + pointer pTimeout, + pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[screenNum]; + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + + if (pScreen == animCurState.pScreen) + { + CARD32 now = GetTimeInMillis (); + + if ((INT32) (now - animCurState.time) >= 0) + { + AnimCurPtr ac = GetAnimCur(animCurState.pCursor); + int elt = (animCurState.elt + 1) % ac->nelt; + DisplayCursorProcPtr DisplayCursor; + + /* + * Not a simple Unwrap/Wrap as this + * isn't called along the DisplayCursor + * wrapper chain. + */ + DisplayCursor = pScreen->DisplayCursor; + pScreen->DisplayCursor = as->DisplayCursor; + (void) (*pScreen->DisplayCursor) (pScreen, ac->elts[elt].pCursor); + as->DisplayCursor = pScreen->DisplayCursor; + pScreen->DisplayCursor = DisplayCursor; + + animCurState.elt = elt; + animCurState.time = now + ac->elts[elt].delay; + } + AdjustWaitForDelay (pTimeout, animCurState.time - now); + } + Unwrap (as, pScreen, BlockHandler); + (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); + Wrap (as, pScreen, BlockHandler, AnimCurScreenBlockHandler); +} + +static Bool +AnimCurDisplayCursor (ScreenPtr pScreen, + CursorPtr pCursor) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, DisplayCursor); + if (IsAnimCur(pCursor)) + { + if (pCursor != animCurState.pCursor) + { + AnimCurPtr ac = GetAnimCur(pCursor); + + ret = (*pScreen->DisplayCursor) (pScreen, ac->elts[0].pCursor); + if (ret) + { + animCurState.elt = 0; + animCurState.time = GetTimeInMillis () + ac->elts[0].delay; + animCurState.pCursor = pCursor; + animCurState.pScreen = pScreen; + } + } + else + ret = TRUE; + } + else + { + animCurState.pCursor = 0; + animCurState.pScreen = 0; + ret = (*pScreen->DisplayCursor) (pScreen, pCursor); + } + Wrap (as, pScreen, DisplayCursor, AnimCurDisplayCursor); + return ret; +} + +static Bool +AnimCurSetCursorPosition (ScreenPtr pScreen, + int x, + int y, + Bool generateEvent) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, SetCursorPosition); + if (animCurState.pCursor) + animCurState.pScreen = pScreen; + ret = (*pScreen->SetCursorPosition) (pScreen, x, y, generateEvent); + Wrap (as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); + return ret; +} + +static Bool +AnimCurRealizeCursor (ScreenPtr pScreen, + CursorPtr pCursor) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, RealizeCursor); + if (IsAnimCur(pCursor)) + ret = TRUE; + else + ret = (*pScreen->RealizeCursor) (pScreen, pCursor); + Wrap (as, pScreen, RealizeCursor, AnimCurRealizeCursor); + return ret; +} + +static Bool +AnimCurUnrealizeCursor (ScreenPtr pScreen, + CursorPtr pCursor) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, UnrealizeCursor); + if (IsAnimCur(pCursor)) + { + AnimCurPtr ac = GetAnimCur(pCursor); + int i; + + if (pScreen->myNum == 0) + for (i = 0; i < ac->nelt; i++) + FreeCursor (ac->elts[i].pCursor, 0); + ret = TRUE; + } + else + ret = (*pScreen->UnrealizeCursor) (pScreen, pCursor); + Wrap (as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); + return ret; +} + +static void +AnimCurRecolorCursor (ScreenPtr pScreen, + CursorPtr pCursor, + Bool displayed) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + + Unwrap (as, pScreen, RecolorCursor); + if (IsAnimCur(pCursor)) + { + AnimCurPtr ac = GetAnimCur(pCursor); + int i; + + for (i = 0; i < ac->nelt; i++) + (*pScreen->RecolorCursor) (pScreen, ac->elts[i].pCursor, + displayed && + animCurState.elt == i); + } + else + (*pScreen->RecolorCursor) (pScreen, pCursor, displayed); + Wrap (as, pScreen, RecolorCursor, AnimCurRecolorCursor); +} + +Bool +AnimCurInit (ScreenPtr pScreen) +{ + AnimCurScreenPtr as; + + if (AnimCurGeneration != serverGeneration) + { + AnimCurGeneration = serverGeneration; + animCurState.pCursor = 0; + animCurState.pScreen = 0; + animCurState.elt = 0; + animCurState.time = 0; + } + as = (AnimCurScreenPtr) xalloc (sizeof (AnimCurScreenRec)); + if (!as) + return FALSE; + Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen); + + Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); + + Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits); + Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor); + Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); + Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor); + Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); + Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor); + SetAnimCurScreen(pScreen,as); + return TRUE; +} + +int +AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid) +{ + CursorPtr pCursor; + int rc, i; + AnimCurPtr ac; + + for (i = 0; i < screenInfo.numScreens; i++) + if (!GetAnimCurScreenIfSet (screenInfo.screens[i])) + return BadImplementation; + + for (i = 0; i < ncursor; i++) + if (IsAnimCur (cursors[i])) + return BadMatch; + + pCursor = (CursorPtr) xalloc (sizeof (CursorRec) + + sizeof (AnimCurRec) + + ncursor * sizeof (AnimCurElt)); + if (!pCursor) + return BadAlloc; + pCursor->bits = &animCursorBits; + pCursor->refcnt = 1; + + pCursor->foreRed = cursors[0]->foreRed; + pCursor->foreGreen = cursors[0]->foreGreen; + pCursor->foreBlue = cursors[0]->foreBlue; + + pCursor->backRed = cursors[0]->backRed; + pCursor->backGreen = cursors[0]->backGreen; + pCursor->backBlue = cursors[0]->backBlue; + + pCursor->id = cid; + pCursor->devPrivates = NULL; + + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor, + RT_NONE, NULL, DixCreateAccess); + if (rc != Success) { + dixFreePrivates(pCursor->devPrivates); + xfree(pCursor); + return rc; + } + + /* + * Fill in the AnimCurRec + */ + animCursorBits.refcnt++; + ac = GetAnimCur (pCursor); + ac->nelt = ncursor; + ac->elts = (AnimCurElt *) (ac + 1); + + for (i = 0; i < ncursor; i++) + { + cursors[i]->refcnt++; + ac->elts[i].pCursor = cursors[i]; + ac->elts[i].delay = deltas[i]; + } + + *ppCursor = pCursor; + return Success; +} diff --git a/xorg-server/render/filter.c b/xorg-server/render/filter.c new file mode 100644 index 000000000..aa3eb1a9e --- /dev/null +++ b/xorg-server/render/filter.c @@ -0,0 +1,323 @@ +/* + * Copyright © 2002 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#include "picturestr.h" + +static char **filterNames; +static int nfilterNames; + +/* + * standard but not required filters don't have constant indices + */ + +int +PictureGetFilterId (char *filter, int len, Bool makeit) +{ + int i; + char *name; + char **names; + + if (len < 0) + len = strlen (filter); + for (i = 0; i < nfilterNames; i++) + if (!CompareISOLatin1Lowered ((unsigned char *) filterNames[i], -1, (unsigned char *) filter, len)) + return i; + if (!makeit) + return -1; + name = xalloc (len + 1); + if (!name) + return -1; + memcpy (name, filter, len); + name[len] = '\0'; + if (filterNames) + names = xrealloc (filterNames, (nfilterNames + 1) * sizeof (char *)); + else + names = xalloc (sizeof (char *)); + if (!names) + { + xfree (name); + return -1; + } + filterNames = names; + i = nfilterNames++; + filterNames[i] = name; + return i; +} + +static Bool +PictureSetDefaultIds (void) +{ + /* careful here -- this list must match the #define values */ + + if (PictureGetFilterId (FilterNearest, -1, TRUE) != PictFilterNearest) + return FALSE; + if (PictureGetFilterId (FilterBilinear, -1, TRUE) != PictFilterBilinear) + return FALSE; + + if (PictureGetFilterId (FilterFast, -1, TRUE) != PictFilterFast) + return FALSE; + if (PictureGetFilterId (FilterGood, -1, TRUE) != PictFilterGood) + return FALSE; + if (PictureGetFilterId (FilterBest, -1, TRUE) != PictFilterBest) + return FALSE; + + if (PictureGetFilterId (FilterConvolution, -1, TRUE) != PictFilterConvolution) + return FALSE; + return TRUE; +} + +char * +PictureGetFilterName (int id) +{ + if (0 <= id && id < nfilterNames) + return filterNames[id]; + else + return 0; +} + +static void +PictureFreeFilterIds (void) +{ + int i; + + for (i = 0; i < nfilterNames; i++) + xfree (filterNames[i]); + xfree (filterNames); + nfilterNames = 0; + filterNames = 0; +} + +_X_EXPORT int +PictureAddFilter (ScreenPtr pScreen, + char *filter, + PictFilterValidateParamsProcPtr ValidateParams) +{ + PictureScreenPtr ps = GetPictureScreen(pScreen); + int id = PictureGetFilterId (filter, -1, TRUE); + int i; + PictFilterPtr filters; + + if (id < 0) + return -1; + /* + * It's an error to attempt to reregister a filter + */ + for (i = 0; i < ps->nfilters; i++) + if (ps->filters[i].id == id) + return -1; + if (ps->filters) + filters = xrealloc (ps->filters, (ps->nfilters + 1) * sizeof (PictFilterRec)); + else + filters = xalloc (sizeof (PictFilterRec)); + if (!filters) + return -1; + ps->filters = filters; + i = ps->nfilters++; + ps->filters[i].name = PictureGetFilterName (id); + ps->filters[i].id = id; + ps->filters[i].ValidateParams = ValidateParams; + return id; +} + +_X_EXPORT Bool +PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias) +{ + PictureScreenPtr ps = GetPictureScreen(pScreen); + int filter_id = PictureGetFilterId (filter, -1, FALSE); + int alias_id = PictureGetFilterId (alias, -1, TRUE); + int i; + + if (filter_id < 0 || alias_id < 0) + return FALSE; + for (i = 0; i < ps->nfilterAliases; i++) + if (ps->filterAliases[i].alias_id == alias_id) + break; + if (i == ps->nfilterAliases) + { + PictFilterAliasPtr aliases; + + if (ps->filterAliases) + aliases = xrealloc (ps->filterAliases, + (ps->nfilterAliases + 1) * + sizeof (PictFilterAliasRec)); + else + aliases = xalloc (sizeof (PictFilterAliasRec)); + if (!aliases) + return FALSE; + ps->filterAliases = aliases; + ps->filterAliases[i].alias = PictureGetFilterName (alias_id); + ps->filterAliases[i].alias_id = alias_id; + ps->nfilterAliases++; + } + ps->filterAliases[i].filter_id = filter_id; + return TRUE; +} + +PictFilterPtr +PictureFindFilter (ScreenPtr pScreen, char *name, int len) +{ + PictureScreenPtr ps = GetPictureScreen(pScreen); + int id = PictureGetFilterId (name, len, FALSE); + int i; + + if (id < 0) + return 0; + /* Check for an alias, allow them to recurse */ + for (i = 0; i < ps->nfilterAliases; i++) + if (ps->filterAliases[i].alias_id == id) + { + id = ps->filterAliases[i].filter_id; + i = 0; + } + /* find the filter */ + for (i = 0; i < ps->nfilters; i++) + if (ps->filters[i].id == id) + return &ps->filters[i]; + return 0; +} + +static Bool +convolutionFilterValidateParams (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams) +{ + if (nparams < 3) + return FALSE; + + if (xFixedFrac (params[0]) || xFixedFrac (params[1])) + return FALSE; + + nparams -= 2; + if ((xFixedToInt (params[0]) * xFixedToInt (params[1])) > nparams) + return FALSE; + + return TRUE; +} + + +Bool +PictureSetDefaultFilters (ScreenPtr pScreen) +{ + if (!filterNames) + if (!PictureSetDefaultIds ()) + return FALSE; + if (PictureAddFilter (pScreen, FilterNearest, 0) < 0) + return FALSE; + if (PictureAddFilter (pScreen, FilterBilinear, 0) < 0) + return FALSE; + + if (!PictureSetFilterAlias (pScreen, FilterNearest, FilterFast)) + return FALSE; + if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterGood)) + return FALSE; + if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterBest)) + return FALSE; + + if (PictureAddFilter (pScreen, FilterConvolution, convolutionFilterValidateParams) < 0) + return FALSE; + + return TRUE; +} + +void +PictureResetFilters (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen(pScreen); + + xfree (ps->filters); + xfree (ps->filterAliases); + PictureFreeFilterIds (); +} + +int +SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams) +{ + PictFilterPtr pFilter; + xFixed *new_params; + int i, s, result; + + pFilter = PictureFindFilter (screenInfo.screens[0], name, len); + + if (pPicture->pDrawable == NULL) { + /* For source pictures, the picture isn't tied to a screen. So, ensure + * that all screens can handle a filter we set for the picture. + */ + for (s = 0; s < screenInfo.numScreens; s++) { + if (PictureFindFilter (screenInfo.screens[s], name, len)->id != + pFilter->id) + { + return BadMatch; + } + } + } + + if (!pFilter) + return BadName; + if (pFilter->ValidateParams) + { + if (!(*pFilter->ValidateParams) (pPicture, pFilter->id, params, nparams)) + return BadMatch; + } + else if (nparams) + return BadMatch; + + if (nparams != pPicture->filter_nparams) + { + new_params = xalloc (nparams * sizeof (xFixed)); + if (!new_params && nparams) + return BadAlloc; + xfree (pPicture->filter_params); + pPicture->filter_params = new_params; + pPicture->filter_nparams = nparams; + } + for (i = 0; i < nparams; i++) + pPicture->filter_params[i] = params[i]; + pPicture->filter = pFilter->id; + + if (pPicture->pDrawable) { + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter, + params, nparams); + return result; + } + return Success; +} diff --git a/xorg-server/render/glyph.c b/xorg-server/render/glyph.c new file mode 100644 index 000000000..286e39d63 --- /dev/null +++ b/xorg-server/render/glyph.c @@ -0,0 +1,770 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stddef.h> /* buggy openssl/sha.h wants size_t */ +#include <openssl/sha.h> + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#include "picturestr.h" +#include "glyphstr.h" +#include "mipict.h" + +/* + * From Knuth -- a good choice for hash/rehash values is p, p-2 where + * p and p-2 are both prime. These tables are sized to have an extra 10% + * free to avoid exponential performance degradation as the hash table fills + */ +static GlyphHashSetRec glyphHashSets[] = { + { 32, 43, 41 }, + { 64, 73, 71 }, + { 128, 151, 149 }, + { 256, 283, 281 }, + { 512, 571, 569 }, + { 1024, 1153, 1151 }, + { 2048, 2269, 2267 }, + { 4096, 4519, 4517 }, + { 8192, 9013, 9011 }, + { 16384, 18043, 18041 }, + { 32768, 36109, 36107 }, + { 65536, 72091, 72089 }, + { 131072, 144409, 144407 }, + { 262144, 288361, 288359 }, + { 524288, 576883, 576881 }, + { 1048576, 1153459, 1153457 }, + { 2097152, 2307163, 2307161 }, + { 4194304, 4613893, 4613891 }, + { 8388608, 9227641, 9227639 }, + { 16777216, 18455029, 18455027 }, + { 33554432, 36911011, 36911009 }, + { 67108864, 73819861, 73819859 }, + { 134217728, 147639589, 147639587 }, + { 268435456, 295279081, 295279079 }, + { 536870912, 590559793, 590559791 } +}; + +#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0])) + +static const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 }; + +static GlyphHashRec globalGlyphs[GlyphFormatNum]; + +static void +FreeGlyphPrivates (GlyphPtr glyph) +{ + ScreenPtr pScreen; + int i; + + for (i = 0; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + dixFreePrivates(*GetGlyphPrivatesForScreen(glyph, pScreen)); + } + + dixFreePrivates(glyph->devPrivates); + glyph->devPrivates = NULL; +} + +void +GlyphUninit (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen (pScreen); + GlyphPtr glyph; + int fdepth, i; + + for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) + { + if (!globalGlyphs[fdepth].hashSet) + continue; + + for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) + { + glyph = globalGlyphs[fdepth].table[i].glyph; + if (glyph && glyph != DeletedGlyph) + { + (*ps->UnrealizeGlyph) (pScreen, glyph); + FreeGlyphPrivates(glyph); + } + } + } + + for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) + { + if (!globalGlyphs[fdepth].hashSet) + continue; + + for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) + glyph = globalGlyphs[fdepth].table[i].glyph; + } +} + +GlyphHashSetPtr +FindGlyphHashSet (CARD32 filled) +{ + int i; + + for (i = 0; i < NGLYPHHASHSETS; i++) + if (glyphHashSets[i].entries >= filled) + return &glyphHashSets[i]; + return 0; +} + +GlyphRefPtr +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]) +{ + CARD32 elt, step, s; + GlyphPtr glyph; + GlyphRefPtr table, gr, del; + CARD32 tableSize = hash->hashSet->size; + + table = hash->table; + elt = signature % tableSize; + step = 0; + del = 0; + for (;;) + { + gr = &table[elt]; + s = gr->signature; + glyph = gr->glyph; + if (!glyph) + { + if (del) + gr = del; + break; + } + if (glyph == DeletedGlyph) + { + if (!del) + del = gr; + else if (gr == del) + break; + } + else if (s == signature && + (!match || + memcmp (glyph->sha1, sha1, 20) == 0)) + { + break; + } + if (!step) + { + step = signature % hash->hashSet->rehash; + if (!step) + step = 1; + } + elt += step; + if (elt >= tableSize) + elt -= tableSize; + } + return gr; +} + +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]) +{ + SHA_CTX ctx; + int success; + + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo)); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, bits, size); + if (! success) + return BadAlloc; + + success = SHA1_Final (sha1, &ctx); + if (! success) + return BadAlloc; + + return Success; +} + +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format) +{ + GlyphRefPtr gr; + CARD32 signature = *(CARD32 *) sha1; + + gr = FindGlyphRef (&globalGlyphs[format], + signature, TRUE, sha1); + + if (gr->glyph && gr->glyph != DeletedGlyph) + return gr->glyph; + else + return NULL; +} + +#ifdef CHECK_DUPLICATES +void +DuplicateRef (GlyphPtr glyph, char *where) +{ + ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where); +} + +void +CheckDuplicates (GlyphHashPtr hash, char *where) +{ + GlyphPtr g; + int i, j; + + for (i = 0; i < hash->hashSet->size; i++) + { + g = hash->table[i].glyph; + if (!g || g == DeletedGlyph) + continue; + for (j = i + 1; j < hash->hashSet->size; j++) + if (hash->table[j].glyph == g) + DuplicateRef (g, where); + } +} +#else +#define CheckDuplicates(a,b) +#define DuplicateRef(a,b) +#endif + +void +FreeGlyph (GlyphPtr glyph, int format) +{ + CheckDuplicates (&globalGlyphs[format], "FreeGlyph"); + if (--glyph->refcnt == 0) + { + PictureScreenPtr ps; + GlyphRefPtr gr; + int i; + int first; + CARD32 signature; + + first = -1; + for (i = 0; i < globalGlyphs[format].hashSet->size; i++) + if (globalGlyphs[format].table[i].glyph == glyph) + { + if (first != -1) + DuplicateRef (glyph, "FreeGlyph check"); + first = i; + } + + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[format], signature, + TRUE, glyph->sha1); + if (gr - globalGlyphs[format].table != first) + DuplicateRef (glyph, "Found wrong one"); + if (gr->glyph && gr->glyph != DeletedGlyph) + { + gr->glyph = DeletedGlyph; + gr->signature = 0; + globalGlyphs[format].tableEntries--; + } + + for (i = 0; i < screenInfo.numScreens; i++) + { + ScreenPtr pScreen = screenInfo.screens[i]; + + FreePicture ((pointer) GlyphPicture (glyph)[i], 0); + + ps = GetPictureScreenIfSet (pScreen); + if (ps) + (*ps->UnrealizeGlyph) (pScreen, glyph); + } + + FreeGlyphPrivates(glyph); + xfree (glyph); + } +} + +void +AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) +{ + GlyphRefPtr gr; + CARD32 signature; + + CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); + /* Locate existing matching glyph */ + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) + { + PictureScreenPtr ps; + int i; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + FreeGlyphPrivates(glyph); + xfree (glyph); + glyph = gr->glyph; + } + else if (gr->glyph != glyph) + { + gr->glyph = glyph; + gr->signature = signature; + globalGlyphs[glyphSet->fdepth].tableEntries++; + } + + /* Insert/replace glyphset value */ + gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0); + ++glyph->refcnt; + if (gr->glyph && gr->glyph != DeletedGlyph) + FreeGlyph (gr->glyph, glyphSet->fdepth); + else + glyphSet->hash.tableEntries++; + gr->glyph = glyph; + gr->signature = id; + CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom"); +} + +Bool +DeleteGlyph (GlyphSetPtr glyphSet, Glyph id) +{ + GlyphRefPtr gr; + GlyphPtr glyph; + + gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0); + glyph = gr->glyph; + if (glyph && glyph != DeletedGlyph) + { + gr->glyph = DeletedGlyph; + glyphSet->hash.tableEntries--; + FreeGlyph (glyph, glyphSet->fdepth); + return TRUE; + } + return FALSE; +} + +GlyphPtr +FindGlyph (GlyphSetPtr glyphSet, Glyph id) +{ + GlyphPtr glyph; + + glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph; + if (glyph == DeletedGlyph) + glyph = 0; + return glyph; +} + +GlyphPtr +AllocateGlyph (xGlyphInfo *gi, int fdepth) +{ + PictureScreenPtr ps; + int size; + GlyphPtr glyph; + int i; + + size = screenInfo.numScreens * sizeof (PicturePtr); + glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); + if (!glyph) + return 0; + glyph->refcnt = 0; + glyph->size = size + sizeof (xGlyphInfo); + glyph->info = *gi; + glyph->devPrivates = NULL; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + + if (ps) + { + if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) + goto bail; + } + } + + return glyph; + +bail: + while (i--) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + FreeGlyphPrivates(glyph); + xfree (glyph); + return 0; +} + +Bool +AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet) +{ + hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec)); + if (!hash->table) + return FALSE; + memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec)); + hash->hashSet = hashSet; + hash->tableEntries = 0; + return TRUE; +} + +Bool +ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) +{ + CARD32 tableEntries; + GlyphHashSetPtr hashSet; + GlyphHashRec newHash; + GlyphRefPtr gr; + GlyphPtr glyph; + int i; + int oldSize; + CARD32 s; + + tableEntries = hash->tableEntries + change; + hashSet = FindGlyphHashSet (tableEntries); + if (hashSet == hash->hashSet) + return TRUE; + if (global) + CheckDuplicates (hash, "ResizeGlyphHash top"); + if (!AllocateGlyphHash (&newHash, hashSet)) + return FALSE; + if (hash->table) + { + oldSize = hash->hashSet->size; + for (i = 0; i < oldSize; i++) + { + glyph = hash->table[i].glyph; + if (glyph && glyph != DeletedGlyph) + { + s = hash->table[i].signature; + gr = FindGlyphRef (&newHash, s, global, glyph->sha1); + gr->signature = s; + gr->glyph = glyph; + ++newHash.tableEntries; + } + } + xfree (hash->table); + } + *hash = newHash; + if (global) + CheckDuplicates (hash, "ResizeGlyphHash bottom"); + return TRUE; +} + +Bool +ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change) +{ + return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) && + ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE)); +} + +GlyphSetPtr +AllocateGlyphSet (int fdepth, PictFormatPtr format) +{ + GlyphSetPtr glyphSet; + int size; + + if (!globalGlyphs[fdepth].hashSet) + { + if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0])) + return FALSE; + } + + size = sizeof (GlyphSetRec); + glyphSet = xalloc (size); + if (!glyphSet) + return FALSE; + bzero((char *)glyphSet, size); + + if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0])) + { + xfree (glyphSet); + return FALSE; + } + glyphSet->refcnt = 1; + glyphSet->fdepth = fdepth; + glyphSet->format = format; + return glyphSet; +} + +int +FreeGlyphSet (pointer value, + XID gid) +{ + GlyphSetPtr glyphSet = (GlyphSetPtr) value; + + if (--glyphSet->refcnt == 0) + { + CARD32 i, tableSize = glyphSet->hash.hashSet->size; + GlyphRefPtr table = glyphSet->hash.table; + GlyphPtr glyph; + + for (i = 0; i < tableSize; i++) + { + glyph = table[i].glyph; + if (glyph && glyph != DeletedGlyph) + FreeGlyph (glyph, glyphSet->fdepth); + } + if (!globalGlyphs[glyphSet->fdepth].tableEntries) + { + xfree (globalGlyphs[glyphSet->fdepth].table); + globalGlyphs[glyphSet->fdepth].table = 0; + globalGlyphs[glyphSet->fdepth].hashSet = 0; + } + else + ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE); + xfree (table); + dixFreePrivates(glyphSet->devPrivates); + xfree (glyphSet); + } + return Success; +} + +static void +GlyphExtents (int nlist, + GlyphListPtr list, + GlyphPtr *glyphs, + BoxPtr extents) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + + x = 0; + y = 0; + extents->x1 = MAXSHORT; + extents->x2 = MINSHORT; + extents->y1 = MAXSHORT; + extents->y2 = MINSHORT; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + glyph = *glyphs++; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + if (x1 < extents->x1) + extents->x1 = x1; + if (x2 > extents->x2) + extents->x2 = x2; + if (y1 < extents->y1) + extents->y1 = y1; + if (y2 > extents->y2) + extents->y2 = y2; + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } +} + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +_X_EXPORT void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr lists, + GlyphPtr *glyphs) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); +} + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + +_X_EXPORT void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + PicturePtr pPicture; + PixmapPtr pMaskPixmap = 0; + PicturePtr pMask; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int xDst = list->xOff, yDst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = {0, 0, 0, 0}; + CARD32 component_alpha; + + if (maskFormat) + { + GCPtr pGC; + xRectangle rect; + + GlyphExtents (nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + maskFormat->depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pMaskPixmap) + return; + component_alpha = NeedsComponent(maskFormat->format); + pMask = CreatePicture (0, &pMaskPixmap->drawable, + maskFormat, CPComponentAlpha, &component_alpha, + serverClient, &error); + if (!pMask) + { + (*pScreen->DestroyPixmap) (pMaskPixmap); + return; + } + pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); + ValidateGC (&pMaskPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); + FreeScratchGC (pGC); + x = -extents.x1; + y = -extents.y1; + } + else + { + pMask = pDst; + x = 0; + y = 0; + } + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + pPicture = GlyphPicture (glyph)[pScreen->myNum]; + + if (maskFormat) + { + CompositePicture (PictOpAdd, + pPicture, + None, + pMask, + 0, 0, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + else + { + CompositePicture (op, + pSrc, + pPicture, + pDst, + xSrc + (x - glyph->info.x) - xDst, + ySrc + (y - glyph->info.y) - yDst, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + if (maskFormat) + { + x = extents.x1; + y = extents.y1; + CompositePicture (op, + pSrc, + pMask, + pDst, + xSrc + x - xDst, + ySrc + y - yDst, + 0, 0, + x, y, + width, height); + FreePicture ((pointer) pMask, (XID) 0); + (*pScreen->DestroyPixmap) (pMaskPixmap); + } +} diff --git a/xorg-server/render/glyphstr.h b/xorg-server/render/glyphstr.h new file mode 100644 index 000000000..67b21fe63 --- /dev/null +++ b/xorg-server/render/glyphstr.h @@ -0,0 +1,151 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _GLYPHSTR_H_ +#define _GLYPHSTR_H_ + +#include <X11/extensions/renderproto.h> +#include "picture.h" +#include "screenint.h" +#include "regionstr.h" +#include "miscstruct.h" +#include "privates.h" + +#define GlyphFormat1 0 +#define GlyphFormat4 1 +#define GlyphFormat8 2 +#define GlyphFormat16 3 +#define GlyphFormat32 4 +#define GlyphFormatNum 5 + +typedef struct _Glyph { + CARD32 refcnt; + PrivateRec *devPrivates; + unsigned char sha1[20]; + CARD32 size; /* info + bitmap */ + xGlyphInfo info; + /* per-screen pixmaps follow */ +} GlyphRec, *GlyphPtr; + +#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1)) + +typedef struct _GlyphRef { + CARD32 signature; + GlyphPtr glyph; +} GlyphRefRec, *GlyphRefPtr; + +#define DeletedGlyph ((GlyphPtr) 1) + +typedef struct _GlyphHashSet { + CARD32 entries; + CARD32 size; + CARD32 rehash; +} GlyphHashSetRec, *GlyphHashSetPtr; + +typedef struct _GlyphHash { + GlyphRefPtr table; + GlyphHashSetPtr hashSet; + CARD32 tableEntries; +} GlyphHashRec, *GlyphHashPtr; + +typedef struct _GlyphSet { + CARD32 refcnt; + PictFormatPtr format; + int fdepth; + GlyphHashRec hash; + int maxPrivate; + PrivateRec *devPrivates; +} GlyphSetRec, *GlyphSetPtr; + +#define GlyphSetGetPrivate(pGlyphSet,k) \ + dixLookupPrivate(&(pGlyphSet)->devPrivates, k) + +#define GlyphSetSetPrivate(pGlyphSet,k,ptr) \ + dixSetPrivate(&(pGlyphSet)->devPrivates, k, ptr) + +typedef struct _GlyphList { + INT16 xOff; + INT16 yOff; + CARD8 len; + PictFormatPtr format; +} GlyphListRec, *GlyphListPtr; + +GlyphHashSetPtr +FindGlyphHashSet (CARD32 filled); + +void +GlyphUninit (ScreenPtr pScreen); + +GlyphHashSetPtr +FindGlyphHashSet (CARD32 filled); + +GlyphRefPtr +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]); + +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format); + +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]); + +void +FreeGlyph (GlyphPtr glyph, int format); + +void +AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id); + +Bool +DeleteGlyph (GlyphSetPtr glyphSet, Glyph id); + +GlyphPtr +FindGlyph (GlyphSetPtr glyphSet, Glyph id); + +GlyphPtr +AllocateGlyph (xGlyphInfo *gi, int format); + +Bool +AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet); + +Bool +ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global); + +Bool +ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change); + +GlyphSetPtr +AllocateGlyphSet (int fdepth, PictFormatPtr format); + +int +FreeGlyphSet (pointer value, + XID gid); + + + +#endif /* _GLYPHSTR_H_ */ diff --git a/xorg-server/render/miindex.c b/xorg-server/render/miindex.c new file mode 100644 index 000000000..4e0cf0084 --- /dev/null +++ b/xorg-server/render/miindex.c @@ -0,0 +1,358 @@ +/* + * + * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _MIINDEX_H_ +#define _MIINDEX_H_ + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" +#include "colormapst.h" + +#define NUM_CUBE_LEVELS 4 +#define NUM_GRAY_LEVELS 13 + +static Bool +miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump) +{ + int r, g, b; + unsigned short red, green, blue; + Pixel pixel; + Bool used[MI_MAX_INDEXED]; + int needed; + int policy; + int cube, gray; + int i, n; + + if (pColormap->mid != pColormap->pScreen->defColormap) + { + policy = PictureCmapPolicyAll; + } + else + { + int avail = pColormap->pVisual->ColormapEntries; + policy = PictureCmapPolicy; + if (policy == PictureCmapPolicyDefault) + { + if (avail >= 256 && (pColormap->pVisual->class|DynamicClass) == PseudoColor) + policy = PictureCmapPolicyColor; + else if (avail >= 64) + policy = PictureCmapPolicyGray; + else + policy = PictureCmapPolicyMono; + } + } + /* + * Make sure enough cells are free for the chosen policy + */ + for (;;) + { + switch (policy) { + case PictureCmapPolicyAll: + needed = 0; + break; + case PictureCmapPolicyColor: + needed = 71; + break; + case PictureCmapPolicyGray: + needed = 11; + break; + case PictureCmapPolicyMono: + default: + needed = 0; + break; + } + if (needed <= pColormap->freeRed) + break; + policy--; + } + + /* + * Compute size of cube and gray ramps + */ + cube = gray = 0; + switch (policy) { + case PictureCmapPolicyAll: + /* + * Allocate as big a cube as possible + */ + if ((pColormap->pVisual->class|DynamicClass) == PseudoColor) + { + for (cube = 1; cube * cube * cube < pColormap->pVisual->ColormapEntries; cube++) + ; + cube--; + if (cube == 1) + cube = 0; + } + else + cube = 0; + /* + * Figure out how many gray levels to use so that they + * line up neatly with the cube + */ + if (cube) + { + needed = pColormap->pVisual->ColormapEntries - (cube*cube*cube); + /* levels to fill in with */ + gray = needed / (cube - 1); + /* total levels */ + gray = (gray + 1) * (cube - 1) + 1; + } + else + gray = pColormap->pVisual->ColormapEntries; + break; + + case PictureCmapPolicyColor: + cube = NUM_CUBE_LEVELS; + /* fall through ... */ + case PictureCmapPolicyGray: + gray = NUM_GRAY_LEVELS; + break; + case PictureCmapPolicyMono: + default: + gray = 2; + break; + } + + memset (used, '\0', pColormap->pVisual->ColormapEntries * sizeof (Bool)); + for (r = 0; r < cube; r++) + for (g = 0; g < cube; g++) + for (b = 0; b < cube; b++) + { + pixel = 0; + red = (r * 65535 + (cube-1)/2) / (cube - 1); + green = (g * 65535 + (cube-1)/2) / (cube - 1); + blue = (b * 65535 + (cube-1)/2) / (cube - 1); + if (AllocColor (pColormap, &red, &green, + &blue, &pixel, 0) != Success) + return FALSE; + used[pixel] = TRUE; + } + for (g = 0; g < gray; g++) + { + pixel = 0; + red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1); + if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success) + return FALSE; + used[pixel] = TRUE; + } + n = 0; + for (i = 0; i < pColormap->pVisual->ColormapEntries; i++) + if (used[i]) + pixels[n++] = i; + + *nump = n; + + return TRUE; +} + +/* 0 <= red, green, blue < 32 */ +static Pixel +FindBestColor (miIndexedPtr pIndexed, Pixel *pixels, int num, + int red, int green, int blue) +{ + Pixel best = pixels[0]; + int bestDist = 1 << 30; + int dist; + int dr, dg, db; + while (num--) + { + Pixel pixel = *pixels++; + CARD32 v = pIndexed->rgba[pixel]; + + dr = ((v >> 19) & 0x1f); + dg = ((v >> 11) & 0x1f); + db = ((v >> 3) & 0x1f); + dr = dr - red; + dg = dg - green; + db = db - blue; + dist = dr * dr + dg * dg + db * db; + if (dist < bestDist) + { + bestDist = dist; + best = pixel; + } + } + return best; +} + +/* 0 <= gray < 32768 */ +static Pixel +FindBestGray (miIndexedPtr pIndexed, Pixel *pixels, int num, int gray) +{ + Pixel best = pixels[0]; + int bestDist = 1 << 30; + int dist; + int dr; + int r; + + while (num--) + { + Pixel pixel = *pixels++; + CARD32 v = pIndexed->rgba[pixel]; + + r = v & 0xff; + r = r | (r << 8); + dr = gray - (r >> 1); + dist = dr * dr; + if (dist < bestDist) + { + bestDist = dist; + best = pixel; + } + } + return best; +} + +Bool +miInitIndexed (ScreenPtr pScreen, + PictFormatPtr pFormat) +{ + ColormapPtr pColormap = pFormat->index.pColormap; + VisualPtr pVisual = pColormap->pVisual; + miIndexedPtr pIndexed; + Pixel pixels[MI_MAX_INDEXED]; + xrgb rgb[MI_MAX_INDEXED]; + int num; + int i; + Pixel p, r, g, b; + + if (pVisual->ColormapEntries > MI_MAX_INDEXED) + return FALSE; + + if (pVisual->class & DynamicClass) + { + if (!miBuildRenderColormap (pColormap, pixels, &num)) + return FALSE; + } + else + { + num = pVisual->ColormapEntries; + for (p = 0; p < num; p++) + pixels[p] = p; + } + + pIndexed = xalloc (sizeof (miIndexedRec)); + if (!pIndexed) + return FALSE; + + pFormat->index.nvalues = num; + pFormat->index.pValues = xalloc (num * sizeof (xIndexValue)); + if (!pFormat->index.pValues) + { + xfree (pIndexed); + return FALSE; + } + + + /* + * Build mapping from pixel value to ARGB + */ + QueryColors (pColormap, num, pixels, rgb); + for (i = 0; i < num; i++) + { + p = pixels[i]; + pFormat->index.pValues[i].pixel = p; + pFormat->index.pValues[i].red = rgb[i].red; + pFormat->index.pValues[i].green = rgb[i].green; + pFormat->index.pValues[i].blue = rgb[i].blue; + pFormat->index.pValues[i].alpha = 0xffff; + pIndexed->rgba[p] = (0xff000000 | + ((rgb[i].red & 0xff00) << 8) | + ((rgb[i].green & 0xff00) ) | + ((rgb[i].blue & 0xff00) >> 8)); + } + + /* + * Build mapping from RGB to pixel value. This could probably be + * done a bit quicker... + */ + switch (pVisual->class | DynamicClass) { + case GrayScale: + pIndexed->color = FALSE; + for (r = 0; r < 32768; r++) + pIndexed->ent[r] = FindBestGray (pIndexed, pixels, num, r); + break; + case PseudoColor: + pIndexed->color = TRUE; + p = 0; + for (r = 0; r < 32; r++) + for (g = 0; g < 32; g++) + for (b = 0; b < 32; b++) + { + pIndexed->ent[p] = FindBestColor (pIndexed, pixels, num, + r, g, b); + p++; + } + break; + } + pFormat->index.devPrivate = pIndexed; + return TRUE; +} + +void +miCloseIndexed (ScreenPtr pScreen, + PictFormatPtr pFormat) +{ + if (pFormat->index.devPrivate) + { + xfree (pFormat->index.devPrivate); + pFormat->index.devPrivate = 0; + } + if (pFormat->index.pValues) + { + xfree (pFormat->index.pValues); + pFormat->index.pValues = 0; + } +} + +void +miUpdateIndexed (ScreenPtr pScreen, + PictFormatPtr pFormat, + int ndef, + xColorItem *pdef) +{ + miIndexedPtr pIndexed = pFormat->index.devPrivate; + + if (pIndexed) + { + while (ndef--) + { + pIndexed->rgba[pdef->pixel] = (0xff000000 | + ((pdef->red & 0xff00) << 8) | + ((pdef->green & 0xff00) ) | + ((pdef->blue & 0xff00) >> 8)); + pdef++; + } + } +} + +#endif /* _MIINDEX_H_ */ diff --git a/xorg-server/render/mipict.c b/xorg-server/render/mipict.c new file mode 100644 index 000000000..87dccbbda --- /dev/null +++ b/xorg-server/render/mipict.c @@ -0,0 +1,651 @@ +/* + * + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" + +#ifndef __GNUC__ +#define __inline +#endif + +int +miCreatePicture (PicturePtr pPicture) +{ + return Success; +} + +void +miDestroyPicture (PicturePtr pPicture) +{ + if (pPicture->freeCompClip) + REGION_DESTROY(pPicture->pDrawable->pScreen, pPicture->pCompositeClip); +} + +void +miDestroyPictureClip (PicturePtr pPicture) +{ + switch (pPicture->clientClipType) { + case CT_NONE: + return; + case CT_PIXMAP: + (*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip)); + break; + default: + /* + * we know we'll never have a list of rectangles, since ChangeClip + * immediately turns them into a region + */ + REGION_DESTROY(pPicture->pDrawable->pScreen, pPicture->clientClip); + break; + } + pPicture->clientClip = NULL; + pPicture->clientClipType = CT_NONE; +} + +int +miChangePictureClip (PicturePtr pPicture, + int type, + pointer value, + int n) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + pointer clientClip; + int clientClipType; + + switch (type) { + case CT_PIXMAP: + /* convert the pixmap to a region */ + clientClip = (pointer) BITMAP_TO_REGION(pScreen, (PixmapPtr) value); + if (!clientClip) + return BadAlloc; + clientClipType = CT_REGION; + (*pScreen->DestroyPixmap) ((PixmapPtr) value); + break; + case CT_REGION: + clientClip = value; + clientClipType = CT_REGION; + break; + case CT_NONE: + clientClip = 0; + clientClipType = CT_NONE; + break; + default: + clientClip = (pointer) RECTS_TO_REGION(pScreen, n, + (xRectangle *) value, + type); + if (!clientClip) + return BadAlloc; + clientClipType = CT_REGION; + xfree(value); + break; + } + (*ps->DestroyPictureClip) (pPicture); + pPicture->clientClip = clientClip; + pPicture->clientClipType = clientClipType; + pPicture->stateChanges |= CPClipMask; + return Success; +} + +void +miChangePicture (PicturePtr pPicture, + Mask mask) +{ + return; +} + +void +miValidatePicture (PicturePtr pPicture, + Mask mask) +{ + DrawablePtr pDrawable = pPicture->pDrawable; + + if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) || + (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS))) + { + if (pDrawable->type == DRAWABLE_WINDOW) + { + WindowPtr pWin = (WindowPtr) pDrawable; + RegionPtr pregWin; + Bool freeTmpClip, freeCompClip; + + if (pPicture->subWindowMode == IncludeInferiors) + { + pregWin = NotClippedByChildren(pWin); + freeTmpClip = TRUE; + } + else + { + pregWin = &pWin->clipList; + freeTmpClip = FALSE; + } + freeCompClip = pPicture->freeCompClip; + + /* + * if there is no client clip, we can get by with just keeping the + * pointer we got, and remembering whether or not should destroy + * (or maybe re-use) it later. this way, we avoid unnecessary + * copying of regions. (this wins especially if many clients clip + * by children and have no client clip.) + */ + if (pPicture->clientClipType == CT_NONE) + { + if (freeCompClip) + REGION_DESTROY(pScreen, pPicture->pCompositeClip); + pPicture->pCompositeClip = pregWin; + pPicture->freeCompClip = freeTmpClip; + } + else + { + /* + * we need one 'real' region to put into the composite clip. if + * pregWin the current composite clip are real, we can get rid of + * one. if pregWin is real and the current composite clip isn't, + * use pregWin for the composite clip. if the current composite + * clip is real and pregWin isn't, use the current composite + * clip. if neither is real, create a new region. + */ + + REGION_TRANSLATE(pScreen, pPicture->clientClip, + pDrawable->x + pPicture->clipOrigin.x, + pDrawable->y + pPicture->clipOrigin.y); + + if (freeCompClip) + { + REGION_INTERSECT(pScreen, pPicture->pCompositeClip, + pregWin, pPicture->clientClip); + if (freeTmpClip) + REGION_DESTROY(pScreen, pregWin); + } + else if (freeTmpClip) + { + REGION_INTERSECT(pScreen, pregWin, pregWin, pPicture->clientClip); + pPicture->pCompositeClip = pregWin; + } + else + { + pPicture->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0); + REGION_INTERSECT(pScreen, pPicture->pCompositeClip, + pregWin, pPicture->clientClip); + } + pPicture->freeCompClip = TRUE; + REGION_TRANSLATE(pScreen, pPicture->clientClip, + -(pDrawable->x + pPicture->clipOrigin.x), + -(pDrawable->y + pPicture->clipOrigin.y)); + } + } /* end of composite clip for a window */ + else + { + BoxRec pixbounds; + + /* XXX should we translate by drawable.x/y here ? */ + /* If you want pixmaps in offscreen memory, yes */ + pixbounds.x1 = pDrawable->x; + pixbounds.y1 = pDrawable->y; + pixbounds.x2 = pDrawable->x + pDrawable->width; + pixbounds.y2 = pDrawable->y + pDrawable->height; + + if (pPicture->freeCompClip) + { + REGION_RESET(pScreen, pPicture->pCompositeClip, &pixbounds); + } + else + { + pPicture->freeCompClip = TRUE; + pPicture->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1); + } + + if (pPicture->clientClipType == CT_REGION) + { + if(pDrawable->x || pDrawable->y) { + REGION_TRANSLATE(pScreen, pPicture->clientClip, + pDrawable->x + pPicture->clipOrigin.x, + pDrawable->y + pPicture->clipOrigin.y); + REGION_INTERSECT(pScreen, pPicture->pCompositeClip, + pPicture->pCompositeClip, pPicture->clientClip); + REGION_TRANSLATE(pScreen, pPicture->clientClip, + -(pDrawable->x + pPicture->clipOrigin.x), + -(pDrawable->y + pPicture->clipOrigin.y)); + } else { + REGION_TRANSLATE(pScreen, pPicture->pCompositeClip, + -pPicture->clipOrigin.x, -pPicture->clipOrigin.y); + REGION_INTERSECT(pScreen, pPicture->pCompositeClip, + pPicture->pCompositeClip, pPicture->clientClip); + REGION_TRANSLATE(pScreen, pPicture->pCompositeClip, + pPicture->clipOrigin.x, pPicture->clipOrigin.y); + } + } + } /* end of composite clip for pixmap */ + } +} + +int +miChangePictureTransform (PicturePtr pPicture, + PictTransform *transform) +{ + return Success; +} + +int +miChangePictureFilter (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams) +{ + return Success; +} + +#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v)) + +static inline pixman_bool_t +miClipPictureReg (pixman_region16_t * pRegion, + pixman_region16_t * pClip, + int dx, + int dy) +{ + if (pixman_region_n_rects(pRegion) == 1 && + pixman_region_n_rects(pClip) == 1) + { + pixman_box16_t * pRbox = pixman_region_rectangles(pRegion, NULL); + pixman_box16_t * pCbox = pixman_region_rectangles(pClip, NULL); + int v; + + if (pRbox->x1 < (v = pCbox->x1 + dx)) + pRbox->x1 = BOUND(v); + if (pRbox->x2 > (v = pCbox->x2 + dx)) + pRbox->x2 = BOUND(v); + if (pRbox->y1 < (v = pCbox->y1 + dy)) + pRbox->y1 = BOUND(v); + if (pRbox->y2 > (v = pCbox->y2 + dy)) + pRbox->y2 = BOUND(v); + if (pRbox->x1 >= pRbox->x2 || + pRbox->y1 >= pRbox->y2) + { + pixman_region_init (pRegion); + } + } + else if (!pixman_region_not_empty (pClip)) + return FALSE; + else + { + if (dx || dy) + pixman_region_translate (pRegion, -dx, -dy); + if (!pixman_region_intersect (pRegion, pRegion, pClip)) + return FALSE; + if (dx || dy) + pixman_region_translate(pRegion, dx, dy); + } + return pixman_region_not_empty(pRegion); +} + +static __inline Bool +miClipPictureSrc (RegionPtr pRegion, + PicturePtr pPicture, + int dx, + int dy) +{ + /* XXX what to do with clipping from transformed pictures? */ + if (pPicture->transform || !pPicture->pDrawable) + return TRUE; + if (pPicture->repeat) + { + if (pPicture->clientClipType != CT_NONE) + { + pixman_region_translate ( pRegion, + dx - pPicture->clipOrigin.x, + dy - pPicture->clipOrigin.y); + if (!REGION_INTERSECT (pScreen, pRegion, pRegion, + (RegionPtr) pPicture->pCompositeClip)) // clientClip)) + return FALSE; + pixman_region_translate ( pRegion, + - (dx - pPicture->clipOrigin.x), + - (dy - pPicture->clipOrigin.y)); + } + return TRUE; + } + else + { + return miClipPictureReg (pRegion, + pPicture->pCompositeClip, + dx, + dy); + } +} + +void +miCompositeSourceValidate (PicturePtr pPicture, + INT16 x, + INT16 y, + CARD16 width, + CARD16 height) +{ + DrawablePtr pDrawable = pPicture->pDrawable; + ScreenPtr pScreen; + + if (!pDrawable) + return; + + pScreen = pDrawable->pScreen; + + if (pScreen->SourceValidate) + { + x -= pPicture->pDrawable->x; + y -= pPicture->pDrawable->y; + if (pPicture->transform) + { + xPoint points[4]; + int i; + int xmin, ymin, xmax, ymax; + +#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; } + VectorSet (0, x, y); + VectorSet (1, x + width, y); + VectorSet (2, x, y + height); + VectorSet (3, x + width, y + height); + xmin = ymin = 32767; + xmax = ymax = -32737; + for (i = 0; i < 4; i++) + { + PictVector t; + t.vector[0] = IntToxFixed (points[i].x); + t.vector[1] = IntToxFixed (points[i].y); + t.vector[2] = xFixed1; + if (PictureTransformPoint (pPicture->transform, &t)) + { + int tx = xFixedToInt (t.vector[0]); + int ty = xFixedToInt (t.vector[1]); + if (tx < xmin) xmin = tx; + if (tx > xmax) xmax = tx; + if (ty < ymin) ymin = ty; + if (ty > ymax) ymax = ty; + } + } + x = xmin; + y = ymin; + width = xmax - xmin; + height = ymax - ymin; + } + (*pScreen->SourceValidate) (pDrawable, x, y, width, height); + } +} + +/* + * returns FALSE if the final region is empty. Indistinguishable from + * an allocation failure, but rendering ignores those anyways. + */ + +_X_EXPORT Bool +miComputeCompositeRegion (RegionPtr pRegion, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + + int v; + + pRegion->extents.x1 = xDst; + v = xDst + width; + pRegion->extents.x2 = BOUND(v); + pRegion->extents.y1 = yDst; + v = yDst + height; + pRegion->extents.y2 = BOUND(v); + pRegion->data = 0; + /* Check for empty operation */ + if (pRegion->extents.x1 >= pRegion->extents.x2 || + pRegion->extents.y1 >= pRegion->extents.y2) + { + pixman_region_init (pRegion); + return FALSE; + } + /* clip against dst */ + if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0)) + { + pixman_region_fini (pRegion); + return FALSE; + } + if (pDst->alphaMap) + { + if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip, + -pDst->alphaOrigin.x, + -pDst->alphaOrigin.y)) + { + pixman_region_fini (pRegion); + return FALSE; + } + } + /* clip against src */ + if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc)) + { + pixman_region_fini (pRegion); + return FALSE; + } + if (pSrc->alphaMap) + { + if (!miClipPictureSrc (pRegion, pSrc->alphaMap, + xDst - (xSrc + pSrc->alphaOrigin.x), + yDst - (ySrc + pSrc->alphaOrigin.y))) + { + pixman_region_fini (pRegion); + return FALSE; + } + } + /* clip against mask */ + if (pMask) + { + if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask)) + { + pixman_region_fini (pRegion); + return FALSE; + } + if (pMask->alphaMap) + { + if (!miClipPictureSrc (pRegion, pMask->alphaMap, + xDst - (xMask + pMask->alphaOrigin.x), + yDst - (yMask + pMask->alphaOrigin.y))) + { + pixman_region_fini (pRegion); + return FALSE; + } + } + } + + + miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height); + if (pMask) + miCompositeSourceValidate (pMask, xMask, yMask, width, height); + + return TRUE; +} + +void +miRenderColorToPixel (PictFormatPtr format, + xRenderColor *color, + CARD32 *pixel) +{ + CARD32 r, g, b, a; + miIndexedPtr pIndexed; + + switch (format->type) { + case PictTypeDirect: + r = color->red >> (16 - Ones (format->direct.redMask)); + g = color->green >> (16 - Ones (format->direct.greenMask)); + b = color->blue >> (16 - Ones (format->direct.blueMask)); + a = color->alpha >> (16 - Ones (format->direct.alphaMask)); + r = r << format->direct.red; + g = g << format->direct.green; + b = b << format->direct.blue; + a = a << format->direct.alpha; + *pixel = r|g|b|a; + break; + case PictTypeIndexed: + pIndexed = (miIndexedPtr) (format->index.devPrivate); + if (pIndexed->color) + { + r = color->red >> 11; + g = color->green >> 11; + b = color->blue >> 11; + *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b); + } + else + { + r = color->red >> 8; + g = color->green >> 8; + b = color->blue >> 8; + *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b); + } + break; + } +} + +static CARD16 +miFillColor (CARD32 pixel, int bits) +{ + while (bits < 16) + { + pixel |= pixel << bits; + bits <<= 1; + } + return (CARD16) pixel; +} + +Bool +miIsSolidAlpha (PicturePtr pSrc) +{ + ScreenPtr pScreen; + char line[1]; + + if (!pSrc->pDrawable) + return FALSE; + + pScreen = pSrc->pDrawable->pScreen; + + /* Alpha-only */ + if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A) + return FALSE; + /* repeat */ + if (!pSrc->repeat) + return FALSE; + /* 1x1 */ + if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1) + return FALSE; + line[0] = 1; + (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line); + switch (pSrc->pDrawable->bitsPerPixel) { + case 1: + return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80; + case 4: + return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0; + case 8: + return (CARD8) line[0] == 0xff; + default: + return FALSE; + } +} + +void +miRenderPixelToColor (PictFormatPtr format, + CARD32 pixel, + xRenderColor *color) +{ + CARD32 r, g, b, a; + miIndexedPtr pIndexed; + + switch (format->type) { + case PictTypeDirect: + r = (pixel >> format->direct.red) & format->direct.redMask; + g = (pixel >> format->direct.green) & format->direct.greenMask; + b = (pixel >> format->direct.blue) & format->direct.blueMask; + a = (pixel >> format->direct.alpha) & format->direct.alphaMask; + color->red = miFillColor (r, Ones (format->direct.redMask)); + color->green = miFillColor (g, Ones (format->direct.greenMask)); + color->blue = miFillColor (b, Ones (format->direct.blueMask)); + color->alpha = miFillColor (a, Ones (format->direct.alphaMask)); + break; + case PictTypeIndexed: + pIndexed = (miIndexedPtr) (format->index.devPrivate); + pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)]; + r = (pixel >> 16) & 0xff; + g = (pixel >> 8) & 0xff; + b = (pixel ) & 0xff; + color->red = miFillColor (r, 8); + color->green = miFillColor (g, 8); + color->blue = miFillColor (b, 8); + color->alpha = 0xffff; + break; + } +} + +_X_EXPORT Bool +miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) +{ + PictureScreenPtr ps; + + if (!PictureInit (pScreen, formats, nformats)) + return FALSE; + ps = GetPictureScreen(pScreen); + ps->CreatePicture = miCreatePicture; + ps->DestroyPicture = miDestroyPicture; + ps->ChangePictureClip = miChangePictureClip; + ps->DestroyPictureClip = miDestroyPictureClip; + ps->ChangePicture = miChangePicture; + ps->ValidatePicture = miValidatePicture; + ps->InitIndexed = miInitIndexed; + ps->CloseIndexed = miCloseIndexed; + ps->UpdateIndexed = miUpdateIndexed; + ps->ChangePictureTransform = miChangePictureTransform; + ps->ChangePictureFilter = miChangePictureFilter; + ps->RealizeGlyph = miRealizeGlyph; + ps->UnrealizeGlyph = miUnrealizeGlyph; + + /* MI rendering routines */ + ps->Composite = 0; /* requires DDX support */ + ps->Glyphs = miGlyphs; + ps->CompositeRects = miCompositeRects; + ps->Trapezoids = miTrapezoids; + ps->Triangles = miTriangles; + ps->TriStrip = miTriStrip; + ps->TriFan = miTriFan; + + ps->RasterizeTrapezoid = 0; /* requires DDX support */ + ps->AddTraps = 0; /* requires DDX support */ + ps->AddTriangles = 0; /* requires DDX support */ + + return TRUE; +} diff --git a/xorg-server/render/mipict.h b/xorg-server/render/mipict.h new file mode 100644 index 000000000..60baf7f66 --- /dev/null +++ b/xorg-server/render/mipict.h @@ -0,0 +1,229 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _MIPICT_H_ +#define _MIPICT_H_ + +#include "picturestr.h" + +#define MI_MAX_INDEXED 256 /* XXX depth must be <= 8 */ + +#if MI_MAX_INDEXED <= 256 +typedef CARD8 miIndexType; +#endif + +typedef struct _miIndexed { + Bool color; + CARD32 rgba[MI_MAX_INDEXED]; + miIndexType ent[32768]; +} miIndexedRec, *miIndexedPtr; + +#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \ + (((s) >> 6) & 0x03e0) | \ + (((s) >> 9) & 0x7c00)) +#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15]) +#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24)) + +#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)]) + +int +miCreatePicture (PicturePtr pPicture); + +void +miDestroyPicture (PicturePtr pPicture); + +void +miDestroyPictureClip (PicturePtr pPicture); + +int +miChangePictureClip (PicturePtr pPicture, + int type, + pointer value, + int n); + +void +miChangePicture (PicturePtr pPicture, + Mask mask); + +void +miValidatePicture (PicturePtr pPicture, + Mask mask); + +int +miChangePictureTransform (PicturePtr pPicture, + PictTransform *transform); + +int +miChangePictureFilter (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams); + +Bool +miClipPicture (RegionPtr pRegion, + PicturePtr pPicture, + INT16 xReg, + INT16 yReg, + INT16 xPict, + INT16 yPict); + +void +miCompositeSourceValidate (PicturePtr pPicture, + INT16 x, + INT16 y, + CARD16 width, + CARD16 height); +Bool +miComputeCompositeRegion (RegionPtr pRegion, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +Bool +miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats); + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph); + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph); + +void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs); + +void +miRenderColorToPixel (PictFormatPtr pPict, + xRenderColor *color, + CARD32 *pixel); + +void +miRenderPixelToColor (PictFormatPtr pPict, + CARD32 pixel, + xRenderColor *color); + +Bool +miIsSolidAlpha (PicturePtr pSrc); + +void +miCompositeRects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects); + +void +miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box); + +void +miTrapezoids (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps); + +void +miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds); + +void +miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds); + +void +miRasterizeTriangle (PicturePtr pMask, + xTriangle *tri, + int x_off, + int y_off); + +void +miTriangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntri, + xTriangle *tris); + +void +miTriStrip (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points); + +void +miTriFan (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points); + +PicturePtr +miCreateAlphaPicture (ScreenPtr pScreen, + PicturePtr pDst, + PictFormatPtr pPictFormat, + CARD16 width, + CARD16 height); + +Bool +miInitIndexed (ScreenPtr pScreen, + PictFormatPtr pFormat); + +void +miCloseIndexed (ScreenPtr pScreen, + PictFormatPtr pFormat); + +void +miUpdateIndexed (ScreenPtr pScreen, + PictFormatPtr pFormat, + int ndef, + xColorItem *pdef); + +#endif /* _MIPICT_H_ */ diff --git a/xorg-server/render/mirect.c b/xorg-server/render/mirect.c new file mode 100644 index 000000000..38f4faf67 --- /dev/null +++ b/xorg-server/render/mirect.c @@ -0,0 +1,185 @@ +/* + * + * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" + +static void +miColorRects (PicturePtr pDst, + PicturePtr pClipPict, + xRenderColor *color, + int nRect, + xRectangle *rects, + int xoff, + int yoff) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + CARD32 pixel; + GCPtr pGC; + CARD32 tmpval[5]; + RegionPtr pClip; + unsigned long mask; + + miRenderColorToPixel (pDst->pFormat, color, &pixel); + + pGC = GetScratchGC (pDst->pDrawable->depth, pScreen); + if (!pGC) + return; + tmpval[0] = GXcopy; + tmpval[1] = pixel; + tmpval[2] = pDst->subWindowMode; + mask = GCFunction | GCForeground | GCSubwindowMode; + if (pClipPict->clientClipType == CT_REGION) + { + tmpval[3] = pDst->clipOrigin.x - xoff; + tmpval[4] = pDst->clipOrigin.y - yoff; + mask |= GCClipXOrigin|GCClipYOrigin; + + pClip = REGION_CREATE (pScreen, NULL, 1); + REGION_COPY (pScreen, pClip, + (RegionPtr) pClipPict->clientClip); + (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); + } + + ChangeGC (pGC, mask, tmpval); + ValidateGC (pDst->pDrawable, pGC); + if (xoff || yoff) + { + int i; + for (i = 0; i < nRect; i++) + { + rects[i].x -= xoff; + rects[i].y -= yoff; + } + } + (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects); + if (xoff || yoff) + { + int i; + for (i = 0; i < nRect; i++) + { + rects[i].x += xoff; + rects[i].y += yoff; + } + } + FreeScratchGC (pGC); +} + +_X_EXPORT void +miCompositeRects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + + if (color->alpha == 0xffff) + { + if (op == PictOpOver) + op = PictOpSrc; + } + if (op == PictOpClear) + color->red = color->green = color->blue = color->alpha = 0; + + if (op == PictOpSrc || op == PictOpClear) + { + miColorRects (pDst, pDst, color, nRect, rects, 0, 0); + if (pDst->alphaMap) + miColorRects (pDst->alphaMap, pDst, + color, nRect, rects, + pDst->alphaOrigin.x, + pDst->alphaOrigin.y); + } + else + { + PictFormatPtr rgbaFormat; + PixmapPtr pPixmap; + PicturePtr pSrc; + xRectangle one; + int error; + Pixel pixel; + GCPtr pGC; + CARD32 tmpval[2]; + + rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); + if (!rgbaFormat) + goto bail1; + + pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) + goto bail2; + + miRenderColorToPixel (rgbaFormat, color, &pixel); + + pGC = GetScratchGC (rgbaFormat->depth, pScreen); + if (!pGC) + goto bail3; + tmpval[0] = GXcopy; + tmpval[1] = pixel; + + ChangeGC (pGC, GCFunction | GCForeground, tmpval); + ValidateGC (&pPixmap->drawable, pGC); + one.x = 0; + one.y = 0; + one.width = 1; + one.height = 1; + (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one); + + tmpval[0] = xTrue; + pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat, + CPRepeat, tmpval, serverClient, &error); + + if (!pSrc) + goto bail4; + + while (nRect--) + { + CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0, + rects->x, + rects->y, + rects->width, + rects->height); + rects++; + } + + FreePicture ((pointer) pSrc, 0); +bail4: + FreeScratchGC (pGC); +bail3: + (*pScreen->DestroyPixmap) (pPixmap); +bail2: +bail1: + ; + } +} diff --git a/xorg-server/render/mitrap.c b/xorg-server/render/mitrap.c new file mode 100644 index 000000000..8bdc8a8d0 --- /dev/null +++ b/xorg-server/render/mitrap.c @@ -0,0 +1,189 @@ +/* + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "servermd.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" + +PicturePtr +miCreateAlphaPicture (ScreenPtr pScreen, + PicturePtr pDst, + PictFormatPtr pPictFormat, + CARD16 width, + CARD16 height) +{ + PixmapPtr pPixmap; + PicturePtr pPicture; + GCPtr pGC; + int error; + xRectangle rect; + + if (width > 32767 || height > 32767) + return 0; + + if (!pPictFormat) + { + if (pDst->polyEdge == PolyEdgeSharp) + pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1); + else + pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8); + if (!pPictFormat) + return 0; + } + + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + pPictFormat->depth, 0); + if (!pPixmap) + return 0; + pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); + if (!pGC) + { + (*pScreen->DestroyPixmap) (pPixmap); + return 0; + } + ValidateGC (&pPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect); + FreeScratchGC (pGC); + pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat, + 0, 0, serverClient, &error); + (*pScreen->DestroyPixmap) (pPixmap); + return pPicture; +} + +static xFixed +miLineFixedX (xLineFixed *l, xFixed y, Bool ceil) +{ + xFixed dx = l->p2.x - l->p1.x; + xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx; + xFixed dy = l->p2.y - l->p1.y; + if (ceil) + ex += (dy - 1); + return l->p1.x + (xFixed) (ex / dy); +} + +void +miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box) +{ + box->y1 = MAXSHORT; + box->y2 = MINSHORT; + box->x1 = MAXSHORT; + box->x2 = MINSHORT; + for (; ntrap; ntrap--, traps++) + { + INT16 x1, y1, x2, y2; + + if (!xTrapezoidValid(traps)) + continue; + y1 = xFixedToInt (traps->top); + if (y1 < box->y1) + box->y1 = y1; + + y2 = xFixedToInt (xFixedCeil (traps->bottom)); + if (y2 > box->y2) + box->y2 = y2; + + x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE), + miLineFixedX (&traps->left, traps->bottom, FALSE))); + if (x1 < box->x1) + box->x1 = x1; + + x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE), + miLineFixedX (&traps->right, traps->bottom, TRUE)))); + if (x2 > box->x2) + box->x2 = x2; + } +} + +void +miTrapezoids (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + /* + * Check for solid alpha add + */ + if (op == PictOpAdd && miIsSolidAlpha (pSrc)) + { + for (; ntrap; ntrap--, traps++) + (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0); + } + else if (maskFormat) + { + PicturePtr pPicture; + BoxRec bounds; + INT16 xDst, yDst; + INT16 xRel, yRel; + + xDst = traps[0].left.p1.x >> 16; + yDst = traps[0].left.p1.y >> 16; + + miTrapezoidBounds (ntrap, traps, &bounds); + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return; + pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!pPicture) + return; + for (; ntrap; ntrap--, traps++) + (*ps->RasterizeTrapezoid) (pPicture, traps, + -bounds.x1, -bounds.y1); + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + CompositePicture (op, pSrc, pPicture, pDst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + FreePicture (pPicture, 0); + } + else + { + if (pDst->polyEdge == PolyEdgeSharp) + maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1); + else + maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8); + for (; ntrap; ntrap--, traps++) + miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps); + } +} diff --git a/xorg-server/render/mitri.c b/xorg-server/render/mitri.c new file mode 100644 index 000000000..a92c19b7e --- /dev/null +++ b/xorg-server/render/mitri.c @@ -0,0 +1,191 @@ +/* + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "mi.h" +#include "picturestr.h" +#include "mipict.h" + +void +miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds) +{ + bounds->x1 = xFixedToInt (points->x); + bounds->x2 = xFixedToInt (xFixedCeil (points->x)); + bounds->y1 = xFixedToInt (points->y); + bounds->y2 = xFixedToInt (xFixedCeil (points->y)); + points++; + npoint--; + while (npoint-- > 0) + { + INT16 x1 = xFixedToInt (points->x); + INT16 x2 = xFixedToInt (xFixedCeil (points->x)); + INT16 y1 = xFixedToInt (points->y); + INT16 y2 = xFixedToInt (xFixedCeil (points->y)); + + if (x1 < bounds->x1) + bounds->x1 = x1; + else if (x2 > bounds->x2) + bounds->x2 = x2; + if (y1 < bounds->y1) + bounds->y1 = y1; + else if (y2 > bounds->y2) + bounds->y2 = y2; + points++; + } +} + +void +miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds) +{ + miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds); +} + +void +miTriangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntri, + xTriangle *tris) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + /* + * Check for solid alpha add + */ + if (op == PictOpAdd && miIsSolidAlpha (pSrc)) + { + (*ps->AddTriangles) (pDst, 0, 0, ntri, tris); + } + else if (maskFormat) + { + BoxRec bounds; + PicturePtr pPicture; + INT16 xDst, yDst; + INT16 xRel, yRel; + + xDst = tris[0].p1.x >> 16; + yDst = tris[0].p1.y >> 16; + + miTriangleBounds (ntri, tris, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + return; + pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!pPicture) + return; + (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris); + + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + CompositePicture (op, pSrc, pPicture, pDst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + FreePicture (pPicture, 0); + } + else + { + if (pDst->polyEdge == PolyEdgeSharp) + maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1); + else + maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8); + + for (; ntri; ntri--, tris++) + miTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); + } +} + +void +miTriStrip (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + xTriangle *tris, *tri; + int ntri; + + if (npoint < 3) + return; + ntri = npoint - 2; + tris = xalloc (ntri * sizeof (xTriangle)); + if (!tris) + return; + for (tri = tris; npoint >= 3; npoint--, points++, tri++) + { + tri->p1 = points[0]; + tri->p2 = points[1]; + tri->p3 = points[2]; + } + (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + xfree (tris); +} + +void +miTriFan (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + xTriangle *tris, *tri; + xPointFixed *first; + int ntri; + + if (npoint < 3) + return; + ntri = npoint - 2; + tris = xalloc (ntri * sizeof (xTriangle)); + if (!tris) + return; + first = points++; + for (tri = tris; npoint >= 3; npoint--, points++, tri++) + { + tri->p1 = *first; + tri->p2 = points[0]; + tri->p3 = points[1]; + } + (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + xfree (tris); +} diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c new file mode 100644 index 000000000..b7874bb64 --- /dev/null +++ b/xorg-server/render/picture.c @@ -0,0 +1,1845 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#include "picturestr.h" +#include "xace.h" +#include "registry.h" + +_X_EXPORT DevPrivateKey PictureScreenPrivateKey = &PictureScreenPrivateKey; +DevPrivateKey PictureWindowPrivateKey = &PictureWindowPrivateKey; +static int PictureGeneration; +RESTYPE PictureType; +RESTYPE PictFormatType; +RESTYPE GlyphSetType; +int PictureCmapPolicy = PictureCmapPolicyDefault; + +Bool +PictureDestroyWindow (WindowPtr pWindow) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + PicturePtr pPicture; + PictureScreenPtr ps = GetPictureScreen(pScreen); + Bool ret; + + while ((pPicture = GetPictureWindow(pWindow))) + { + SetPictureWindow(pWindow, pPicture->pNext); + if (pPicture->id) + FreeResource (pPicture->id, PictureType); + FreePicture ((pointer) pPicture, pPicture->id); + } + pScreen->DestroyWindow = ps->DestroyWindow; + ret = (*pScreen->DestroyWindow) (pWindow); + ps->DestroyWindow = pScreen->DestroyWindow; + pScreen->DestroyWindow = PictureDestroyWindow; + return ret; +} + +Bool +PictureCloseScreen (int index, ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen(pScreen); + Bool ret; + int n; + + pScreen->CloseScreen = ps->CloseScreen; + ret = (*pScreen->CloseScreen) (index, pScreen); + PictureResetFilters (pScreen); + for (n = 0; n < ps->nformats; n++) + if (ps->formats[n].type == PictTypeIndexed) + (*ps->CloseIndexed) (pScreen, &ps->formats[n]); + GlyphUninit (pScreen); + SetPictureScreen(pScreen, 0); + xfree (ps->formats); + xfree (ps); + return ret; +} + +void +PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef) +{ + ScreenPtr pScreen = pColormap->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + pScreen->StoreColors = ps->StoreColors; + (*pScreen->StoreColors) (pColormap, ndef, pdef); + ps->StoreColors = pScreen->StoreColors; + pScreen->StoreColors = PictureStoreColors; + + if (pColormap->class == PseudoColor || pColormap->class == GrayScale) + { + PictFormatPtr format = ps->formats; + int nformats = ps->nformats; + + while (nformats--) + { + if (format->type == PictTypeIndexed && + format->index.pColormap == pColormap) + { + (*ps->UpdateIndexed) (pScreen, format, ndef, pdef); + break; + } + format++; + } + } +} + +static int +visualDepth (ScreenPtr pScreen, VisualPtr pVisual) +{ + int d, v; + DepthPtr pDepth; + + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + for (v = 0; v < pDepth->numVids; v++) + if (pDepth->vids[v] == pVisual->vid) + return pDepth->depth; + } + return 0; +} + +typedef struct _formatInit { + CARD32 format; + CARD8 depth; +} FormatInitRec, *FormatInitPtr; + +static int +addFormat (FormatInitRec formats[256], + int nformat, + CARD32 format, + CARD8 depth) +{ + int n; + + for (n = 0; n < nformat; n++) + if (formats[n].format == format && formats[n].depth == depth) + return nformat; + formats[nformat].format = format; + formats[nformat].depth = depth; + return ++nformat; +} + +#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1)) + +PictFormatPtr +PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp) +{ + int nformats, f; + PictFormatPtr pFormats; + FormatInitRec formats[1024]; + CARD32 format; + CARD8 depth; + VisualPtr pVisual; + int v; + int bpp; + int type; + int r, g, b; + int d; + DepthPtr pDepth; + + nformats = 0; + /* formats required by protocol */ + formats[nformats].format = PICT_a1; + formats[nformats].depth = 1; + nformats++; + formats[nformats].format = PICT_FORMAT(BitsPerPixel(8), + PICT_TYPE_A, + 8, 0, 0, 0); + formats[nformats].depth = 8; + nformats++; + formats[nformats].format = PICT_FORMAT(BitsPerPixel(4), + PICT_TYPE_A, + 4, 0, 0, 0); + formats[nformats].depth = 4; + nformats++; + formats[nformats].format = PICT_a8r8g8b8; + formats[nformats].depth = 32; + nformats++; + formats[nformats].format = PICT_x8r8g8b8; + formats[nformats].depth = 32; + nformats++; + + /* now look through the depths and visuals adding other formats */ + for (v = 0; v < pScreen->numVisuals; v++) + { + pVisual = &pScreen->visuals[v]; + depth = visualDepth (pScreen, pVisual); + if (!depth) + continue; + bpp = BitsPerPixel (depth); + switch (pVisual->class) { + case DirectColor: + case TrueColor: + r = Ones (pVisual->redMask); + g = Ones (pVisual->greenMask); + b = Ones (pVisual->blueMask); + type = PICT_TYPE_OTHER; + /* + * Current rendering code supports only two direct formats, + * fields must be packed together at the bottom of the pixel + * and must be either RGB or BGR + */ + if (pVisual->offsetBlue == 0 && + pVisual->offsetGreen == b && + pVisual->offsetRed == b + g) + { + type = PICT_TYPE_ARGB; + } + else if (pVisual->offsetRed == 0 && + pVisual->offsetGreen == r && + pVisual->offsetBlue == r + g) + { + type = PICT_TYPE_ABGR; + } + if (type != PICT_TYPE_OTHER) + { + format = PICT_FORMAT(bpp, type, 0, r, g, b); + nformats = addFormat (formats, nformats, format, depth); + } + break; + case StaticColor: + case PseudoColor: + format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v); + nformats = addFormat (formats, nformats, format, depth); + break; + case StaticGray: + case GrayScale: + format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v); + nformats = addFormat (formats, nformats, format, depth); + break; + } + } + /* + * Walk supported depths and add useful Direct formats + */ + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + bpp = BitsPerPixel (pDepth->depth); + format = 0; + switch (bpp) { + case 16: + /* depth 12 formats */ + if (pDepth->depth >= 12) + { + nformats = addFormat (formats, nformats, + PICT_x4r4g4b4, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x4b4g4r4, pDepth->depth); + } + /* depth 15 formats */ + if (pDepth->depth >= 15) + { + nformats = addFormat (formats, nformats, + PICT_x1r5g5b5, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x1b5g5r5, pDepth->depth); + } + /* depth 16 formats */ + if (pDepth->depth >= 16) + { + nformats = addFormat (formats, nformats, + PICT_a1r5g5b5, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_a1b5g5r5, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_r5g6b5, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_b5g6r5, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_a4r4g4b4, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_a4b4g4r4, pDepth->depth); + } + break; + case 24: + if (pDepth->depth >= 24) + { + nformats = addFormat (formats, nformats, + PICT_r8g8b8, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_b8g8r8, pDepth->depth); + } + break; + case 32: + if (pDepth->depth >= 24) + { + nformats = addFormat (formats, nformats, + PICT_x8r8g8b8, pDepth->depth); + nformats = addFormat (formats, nformats, + PICT_x8b8g8r8, pDepth->depth); + } + break; + } + } + + + pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec)); + if (!pFormats) + return 0; + memset (pFormats, '\0', nformats * sizeof (PictFormatRec)); + for (f = 0; f < nformats; f++) + { + pFormats[f].id = FakeClientID (0); + pFormats[f].depth = formats[f].depth; + format = formats[f].format; + pFormats[f].format = format; + switch (PICT_FORMAT_TYPE(format)) { + case PICT_TYPE_ARGB: + pFormats[f].type = PictTypeDirect; + + pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format)); + if (pFormats[f].direct.alphaMask) + pFormats[f].direct.alpha = (PICT_FORMAT_R(format) + + PICT_FORMAT_G(format) + + PICT_FORMAT_B(format)); + + pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format)); + pFormats[f].direct.red = (PICT_FORMAT_G(format) + + PICT_FORMAT_B(format)); + + pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format)); + pFormats[f].direct.green = PICT_FORMAT_B(format); + + pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format)); + pFormats[f].direct.blue = 0; + break; + + case PICT_TYPE_ABGR: + pFormats[f].type = PictTypeDirect; + + pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format)); + if (pFormats[f].direct.alphaMask) + pFormats[f].direct.alpha = (PICT_FORMAT_B(format) + + PICT_FORMAT_G(format) + + PICT_FORMAT_R(format)); + + pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format)); + pFormats[f].direct.blue = (PICT_FORMAT_G(format) + + PICT_FORMAT_R(format)); + + pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format)); + pFormats[f].direct.green = PICT_FORMAT_R(format); + + pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format)); + pFormats[f].direct.red = 0; + break; + + case PICT_TYPE_A: + pFormats[f].type = PictTypeDirect; + + pFormats[f].direct.alpha = 0; + pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format)); + + /* remaining fields already set to zero */ + break; + + case PICT_TYPE_COLOR: + case PICT_TYPE_GRAY: + pFormats[f].type = PictTypeIndexed; + pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid; + break; + } + } + *nformatp = nformats; + return pFormats; +} + +static VisualPtr +PictureFindVisual (ScreenPtr pScreen, VisualID visual) +{ + int i; + VisualPtr pVisual; + for (i = 0, pVisual = pScreen->visuals; + i < pScreen->numVisuals; + i++, pVisual++) + { + if (pVisual->vid == visual) + return pVisual; + } + return 0; +} + +Bool +PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (format->type != PictTypeIndexed || format->index.pColormap) + return TRUE; + + if (format->index.vid == pScreen->rootVisual) { + format->index.pColormap = + (ColormapPtr) LookupIDByType(pScreen->defColormap, RT_COLORMAP); + } else { + VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid); + if (CreateColormap(FakeClientID (0), pScreen, pVisual, + &format->index.pColormap, AllocNone, 0) + != Success) + return FALSE; + } + if (!ps->InitIndexed(pScreen, format)) + return FALSE; + return TRUE; +} + +static Bool +PictureInitIndexedFormats (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + PictFormatPtr format; + int nformat; + + if (!ps) + return FALSE; + format = ps->formats; + nformat = ps->nformats; + while (nformat--) + if (!PictureInitIndexedFormat(pScreen, format++)) + return FALSE; + return TRUE; +} + +Bool +PictureFinishInit (void) +{ + int s; + + for (s = 0; s < screenInfo.numScreens; s++) + { + if (!PictureInitIndexedFormats (screenInfo.screens[s])) + return FALSE; + (void) AnimCurInit (screenInfo.screens[s]); + } + + return TRUE; +} + +_X_EXPORT Bool +PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (!ps) + return FALSE; + ps->subpixel = subpixel; + return TRUE; + +} + +_X_EXPORT int +PictureGetSubpixelOrder (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (!ps) + return SubPixelUnknown; + return ps->subpixel; +} + +PictFormatPtr +PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + PictFormatPtr format; + int nformat; + int type; + + if (!ps) + return 0; + format = ps->formats; + nformat = ps->nformats; + switch (pVisual->class) { + case StaticGray: + case GrayScale: + case StaticColor: + case PseudoColor: + type = PictTypeIndexed; + break; + case TrueColor: + case DirectColor: + type = PictTypeDirect; + break; + default: + return 0; + } + while (nformat--) + { + if (format->depth == depth && format->type == type) + { + if (type == PictTypeIndexed) + { + if (format->index.vid == pVisual->vid) + return format; + } + else + { + if (format->direct.redMask << format->direct.red == + pVisual->redMask && + format->direct.greenMask << format->direct.green == + pVisual->greenMask && + format->direct.blueMask << format->direct.blue == + pVisual->blueMask) + { + return format; + } + } + } + format++; + } + return 0; +} + +PictFormatPtr +PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + PictFormatPtr format; + int nformat; + + if (!ps) + return 0; + format = ps->formats; + nformat = ps->nformats; + while (nformat--) + { + if (format->depth == depth && format->format == (f & 0xffffff)) + return format; + format++; + } + return 0; +} + +int +PictureParseCmapPolicy (const char *name) +{ + if ( strcmp (name, "default" ) == 0) + return PictureCmapPolicyDefault; + else if ( strcmp (name, "mono" ) == 0) + return PictureCmapPolicyMono; + else if ( strcmp (name, "gray" ) == 0) + return PictureCmapPolicyGray; + else if ( strcmp (name, "color" ) == 0) + return PictureCmapPolicyColor; + else if ( strcmp (name, "all" ) == 0) + return PictureCmapPolicyAll; + else + return PictureCmapPolicyInvalid; +} + +_X_EXPORT Bool +PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) +{ + PictureScreenPtr ps; + int n; + CARD32 type, a, r, g, b; + + if (PictureGeneration != serverGeneration) + { + PictureType = CreateNewResourceType (FreePicture); + if (!PictureType) + return FALSE; + PictFormatType = CreateNewResourceType (FreePictFormat); + if (!PictFormatType) + return FALSE; + GlyphSetType = CreateNewResourceType (FreeGlyphSet); + if (!GlyphSetType) + return FALSE; + PictureGeneration = serverGeneration; + RegisterResourceName (PictureType, "PICTURE"); + RegisterResourceName (PictFormatType, "PICTFORMAT"); + RegisterResourceName (GlyphSetType, "GLYPHSET"); + } + if (!formats) + { + formats = PictureCreateDefaultFormats (pScreen, &nformats); + if (!formats) + return FALSE; + } + for (n = 0; n < nformats; n++) + { + if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n))) + { + xfree (formats); + return FALSE; + } + if (formats[n].type == PictTypeIndexed) + { + VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid); + if ((pVisual->class | DynamicClass) == PseudoColor) + type = PICT_TYPE_COLOR; + else + type = PICT_TYPE_GRAY; + a = r = g = b = 0; + } + else + { + if ((formats[n].direct.redMask| + formats[n].direct.blueMask| + formats[n].direct.greenMask) == 0) + type = PICT_TYPE_A; + else if (formats[n].direct.red > formats[n].direct.blue) + type = PICT_TYPE_ARGB; + else + type = PICT_TYPE_ABGR; + a = Ones (formats[n].direct.alphaMask); + r = Ones (formats[n].direct.redMask); + g = Ones (formats[n].direct.greenMask); + b = Ones (formats[n].direct.blueMask); + } + formats[n].format = PICT_FORMAT(0,type,a,r,g,b); + } + ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec)); + if (!ps) + { + xfree (formats); + return FALSE; + } + SetPictureScreen(pScreen, ps); + + ps->formats = formats; + ps->fallback = formats; + ps->nformats = nformats; + + ps->filters = 0; + ps->nfilters = 0; + ps->filterAliases = 0; + ps->nfilterAliases = 0; + + ps->subpixel = SubPixelUnknown; + + ps->CloseScreen = pScreen->CloseScreen; + ps->DestroyWindow = pScreen->DestroyWindow; + ps->StoreColors = pScreen->StoreColors; + pScreen->DestroyWindow = PictureDestroyWindow; + pScreen->CloseScreen = PictureCloseScreen; + pScreen->StoreColors = PictureStoreColors; + + if (!PictureSetDefaultFilters (pScreen)) + { + PictureResetFilters (pScreen); + SetPictureScreen(pScreen, 0); + xfree (formats); + xfree (ps); + return FALSE; + } + + return TRUE; +} + +void +SetPictureToDefaults (PicturePtr pPicture) +{ + pPicture->refcnt = 1; + pPicture->repeat = 0; + pPicture->graphicsExposures = FALSE; + pPicture->subWindowMode = ClipByChildren; + pPicture->polyEdge = PolyEdgeSharp; + pPicture->polyMode = PolyModePrecise; + pPicture->freeCompClip = FALSE; + pPicture->clientClipType = CT_NONE; + pPicture->componentAlpha = FALSE; + pPicture->repeatType = RepeatNone; + + pPicture->alphaMap = 0; + pPicture->alphaOrigin.x = 0; + pPicture->alphaOrigin.y = 0; + + pPicture->clipOrigin.x = 0; + pPicture->clipOrigin.y = 0; + pPicture->clientClip = 0; + + pPicture->transform = 0; + + pPicture->dither = None; + pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE); + pPicture->filter_params = 0; + pPicture->filter_nparams = 0; + + pPicture->serialNumber = GC_CHANGE_SERIAL_BIT; + pPicture->stateChanges = (1 << (CPLastBit+1)) - 1; + pPicture->pSourcePict = 0; +} + +PicturePtr +CreatePicture (Picture pid, + DrawablePtr pDrawable, + PictFormatPtr pFormat, + Mask vmask, + XID *vlist, + ClientPtr client, + int *error) +{ + PicturePtr pPicture; + PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen); + + pPicture = (PicturePtr)xalloc(sizeof(PictureRec)); + if (!pPicture) + { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pDrawable = pDrawable; + pPicture->pFormat = pFormat; + pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24); + pPicture->devPrivates = NULL; + + /* security creation/labeling check */ + *error = XaceHook(XACE_RESOURCE_ACCESS, client, pid, PictureType, pPicture, + RT_PIXMAP, pDrawable, DixCreateAccess|DixSetAttrAccess); + if (*error != Success) + goto out; + + if (pDrawable->type == DRAWABLE_PIXMAP) + { + ++((PixmapPtr)pDrawable)->refcnt; + pPicture->pNext = 0; + } + else + { + pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable)); + SetPictureWindow(((WindowPtr) pDrawable), pPicture); + } + + SetPictureToDefaults (pPicture); + + if (vmask) + *error = ChangePicture (pPicture, vmask, vlist, 0, client); + else + *error = Success; + if (*error == Success) + *error = (*ps->CreatePicture) (pPicture); +out: + if (*error != Success) + { + FreePicture (pPicture, (XID) 0); + pPicture = 0; + } + return pPicture; +} + +static CARD32 xRenderColorToCard32(xRenderColor c) +{ + return + (c.alpha >> 8 << 24) | + (c.red >> 8 << 16) | + (c.green & 0xff00) | + (c.blue >> 8); +} + +static unsigned int premultiply(unsigned int x) +{ + unsigned int a = x >> 24; + unsigned int t = (x & 0xff00ff) * a + 0x800080; + t = (t + ((t >> 8) & 0xff00ff)) >> 8; + t &= 0xff00ff; + + x = ((x >> 8) & 0xff) * a + 0x80; + x = (x + ((x >> 8) & 0xff)); + x &= 0xff00; + x |= t | (a << 24); + return x; +} + +static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a, + unsigned int y, unsigned int b) +{ + CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; + t >>= 8; + t &= 0xff00ff; + + x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; + x &= 0xff00ff00; + x |= t; + return x; +} + +CARD32 +PictureGradientColor (PictGradientStopPtr stop1, + PictGradientStopPtr stop2, + CARD32 x) +{ + CARD32 current_color, next_color; + int dist, idist; + + current_color = xRenderColorToCard32 (stop1->color); + next_color = xRenderColorToCard32 (stop2->color); + + dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x)); + idist = 256 - dist; + + return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist, + next_color, dist)); +} + +static void initGradient(SourcePictPtr pGradient, int stopCount, + xFixed *stopPoints, xRenderColor *stopColors, int *error) +{ + int i; + xFixed dpos; + + if (stopCount <= 0) { + *error = BadValue; + return; + } + + dpos = -1; + for (i = 0; i < stopCount; ++i) { + if (stopPoints[i] < dpos || stopPoints[i] > (1<<16)) { + *error = BadValue; + return; + } + dpos = stopPoints[i]; + } + + pGradient->gradient.stops = xalloc(stopCount*sizeof(PictGradientStop)); + if (!pGradient->gradient.stops) { + *error = BadAlloc; + return; + } + + pGradient->gradient.nstops = stopCount; + + for (i = 0; i < stopCount; ++i) { + pGradient->gradient.stops[i].x = stopPoints[i]; + pGradient->gradient.stops[i].color = stopColors[i]; + } + + pGradient->gradient.class = SourcePictClassUnknown; + pGradient->gradient.stopRange = 0xffff; + pGradient->gradient.colorTable = NULL; + pGradient->gradient.colorTableSize = 0; +} + +static PicturePtr createSourcePicture(void) +{ + PicturePtr pPicture; + pPicture = (PicturePtr) xalloc(sizeof(PictureRec)); + pPicture->pDrawable = 0; + pPicture->pFormat = 0; + pPicture->pNext = 0; + pPicture->format = PICT_a8r8g8b8; + pPicture->devPrivates = 0; + + SetPictureToDefaults(pPicture); + return pPicture; +} + +PicturePtr +CreateSolidPicture (Picture pid, xRenderColor *color, int *error) +{ + PicturePtr pPicture; + pPicture = createSourcePicture(); + if (!pPicture) { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + xfree(pPicture); + return 0; + } + pPicture->pSourcePict->type = SourcePictTypeSolidFill; + pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color); + return pPicture; +} + +PicturePtr +CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2, + int nStops, xFixed *stops, xRenderColor *colors, int *error) +{ + PicturePtr pPicture; + + if (nStops < 2) { + *error = BadValue; + return 0; + } + + pPicture = createSourcePicture(); + if (!pPicture) { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + xfree(pPicture); + return 0; + } + + pPicture->pSourcePict->linear.type = SourcePictTypeLinear; + pPicture->pSourcePict->linear.p1 = *p1; + pPicture->pSourcePict->linear.p2 = *p2; + + initGradient(pPicture->pSourcePict, nStops, stops, colors, error); + if (*error) { + xfree(pPicture); + return 0; + } + return pPicture; +} + +#define FixedToDouble(x) ((x)/65536.) + +PicturePtr +CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer, + xFixed innerRadius, xFixed outerRadius, + int nStops, xFixed *stops, xRenderColor *colors, int *error) +{ + PicturePtr pPicture; + PictRadialGradient *radial; + + if (nStops < 2) { + *error = BadValue; + return 0; + } + + pPicture = createSourcePicture(); + if (!pPicture) { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + xfree(pPicture); + return 0; + } + radial = &pPicture->pSourcePict->radial; + + radial->type = SourcePictTypeRadial; + radial->c1.x = inner->x; + radial->c1.y = inner->y; + radial->c1.radius = innerRadius; + radial->c2.x = outer->x; + radial->c2.y = outer->y; + radial->c2.radius = outerRadius; + radial->cdx = (radial->c2.x - radial->c1.x) / 65536.; + radial->cdy = (radial->c2.y - radial->c1.y) / 65536.; + radial->dr = (radial->c2.radius - radial->c1.radius) / 65536.; + radial->A = ( radial->cdx * radial->cdx + + radial->cdy * radial->cdy + - radial->dr * radial->dr); + + initGradient(pPicture->pSourcePict, nStops, stops, colors, error); + if (*error) { + xfree(pPicture); + return 0; + } + return pPicture; +} + +PicturePtr +CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle, + int nStops, xFixed *stops, xRenderColor *colors, int *error) +{ + PicturePtr pPicture; + + if (nStops < 2) { + *error = BadValue; + return 0; + } + + pPicture = createSourcePicture(); + if (!pPicture) { + *error = BadAlloc; + return 0; + } + + pPicture->id = pid; + pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient)); + if (!pPicture->pSourcePict) { + *error = BadAlloc; + xfree(pPicture); + return 0; + } + + pPicture->pSourcePict->conical.type = SourcePictTypeConical; + pPicture->pSourcePict->conical.center = *center; + pPicture->pSourcePict->conical.angle = angle; + + initGradient(pPicture->pSourcePict, nStops, stops, colors, error); + if (*error) { + xfree(pPicture); + return 0; + } + return pPicture; +} + +#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val) + +#define NEXT_PTR(_type) ((_type) ulist++->ptr) + +int +ChangePicture (PicturePtr pPicture, + Mask vmask, + XID *vlist, + DevUnion *ulist, + ClientPtr client) +{ + ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0; + PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0; + BITS32 index2; + int error = 0; + BITS32 maskQ; + + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + maskQ = vmask; + while (vmask && !error) + { + index2 = (BITS32) lowbit (vmask); + vmask &= ~index2; + pPicture->stateChanges |= index2; + switch (index2) + { + case CPRepeat: + { + unsigned int newr; + newr = NEXT_VAL(unsigned int); + if (newr <= RepeatReflect) + { + pPicture->repeat = (newr != RepeatNone); + pPicture->repeatType = newr; + } + else + { + client->errorValue = newr; + error = BadValue; + } + } + break; + case CPAlphaMap: + { + PicturePtr pAlpha; + + if (vlist) + { + Picture pid = NEXT_VAL(Picture); + + if (pid == None) + pAlpha = 0; + else + { + error = dixLookupResource((pointer *)&pAlpha, pid, + PictureType, client, + DixReadAccess); + if (error != Success) + { + client->errorValue = pid; + error = (error == BadValue) ? BadPixmap : error; + break; + } + if (pAlpha->pDrawable == NULL || + pAlpha->pDrawable->type != DRAWABLE_PIXMAP) + { + client->errorValue = pid; + error = BadMatch; + break; + } + } + } + else + pAlpha = NEXT_PTR(PicturePtr); + if (!error) + { + if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP) + pAlpha->refcnt++; + if (pPicture->alphaMap) + FreePicture ((pointer) pPicture->alphaMap, (XID) 0); + pPicture->alphaMap = pAlpha; + } + } + break; + case CPAlphaXOrigin: + pPicture->alphaOrigin.x = NEXT_VAL(INT16); + break; + case CPAlphaYOrigin: + pPicture->alphaOrigin.y = NEXT_VAL(INT16); + break; + case CPClipXOrigin: + pPicture->clipOrigin.x = NEXT_VAL(INT16); + break; + case CPClipYOrigin: + pPicture->clipOrigin.y = NEXT_VAL(INT16); + break; + case CPClipMask: + { + Pixmap pid; + PixmapPtr pPixmap; + int clipType; + if (!pScreen) + return BadDrawable; + + if (vlist) + { + pid = NEXT_VAL(Pixmap); + if (pid == None) + { + clipType = CT_NONE; + pPixmap = NullPixmap; + } + else + { + clipType = CT_PIXMAP; + error = dixLookupResource((pointer *)&pPixmap, pid, + RT_PIXMAP, client, + DixReadAccess); + if (error != Success) + { + client->errorValue = pid; + error = (error == BadValue) ? BadPixmap : error; + break; + } + } + } + else + { + pPixmap = NEXT_PTR(PixmapPtr); + if (pPixmap) + clipType = CT_PIXMAP; + else + clipType = CT_NONE; + } + + if (pPixmap) + { + if ((pPixmap->drawable.depth != 1) || + (pPixmap->drawable.pScreen != pScreen)) + { + error = BadMatch; + break; + } + else + { + clipType = CT_PIXMAP; + pPixmap->refcnt++; + } + } + error = (*ps->ChangePictureClip)(pPicture, clipType, + (pointer)pPixmap, 0); + break; + } + case CPGraphicsExposure: + { + unsigned int newe; + newe = NEXT_VAL(unsigned int); + if (newe <= xTrue) + pPicture->graphicsExposures = newe; + else + { + client->errorValue = newe; + error = BadValue; + } + } + break; + case CPSubwindowMode: + { + unsigned int news; + news = NEXT_VAL(unsigned int); + if (news == ClipByChildren || news == IncludeInferiors) + pPicture->subWindowMode = news; + else + { + client->errorValue = news; + error = BadValue; + } + } + break; + case CPPolyEdge: + { + unsigned int newe; + newe = NEXT_VAL(unsigned int); + if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth) + pPicture->polyEdge = newe; + else + { + client->errorValue = newe; + error = BadValue; + } + } + break; + case CPPolyMode: + { + unsigned int newm; + newm = NEXT_VAL(unsigned int); + if (newm == PolyModePrecise || newm == PolyModeImprecise) + pPicture->polyMode = newm; + else + { + client->errorValue = newm; + error = BadValue; + } + } + break; + case CPDither: + pPicture->dither = NEXT_VAL(Atom); + break; + case CPComponentAlpha: + { + unsigned int newca; + + newca = NEXT_VAL (unsigned int); + if (newca <= xTrue) + pPicture->componentAlpha = newca; + else + { + client->errorValue = newca; + error = BadValue; + } + } + break; + default: + client->errorValue = maskQ; + error = BadValue; + break; + } + } + if (ps) + (*ps->ChangePicture) (pPicture, maskQ); + return error; +} + +int +SetPictureClipRects (PicturePtr pPicture, + int xOrigin, + int yOrigin, + int nRect, + xRectangle *rects) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + RegionPtr clientClip; + int result; + + clientClip = RECTS_TO_REGION(pScreen, + nRect, rects, CT_UNSORTED); + if (!clientClip) + return BadAlloc; + result =(*ps->ChangePictureClip) (pPicture, CT_REGION, + (pointer) clientClip, 0); + if (result == Success) + { + pPicture->clipOrigin.x = xOrigin; + pPicture->clipOrigin.y = yOrigin; + pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask; + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + } + return result; +} + +int +SetPictureClipRegion (PicturePtr pPicture, + int xOrigin, + int yOrigin, + RegionPtr pRegion) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + RegionPtr clientClip; + int result; + int type; + + if (pRegion) + { + type = CT_REGION; + clientClip = REGION_CREATE (pScreen, + REGION_EXTENTS(pScreen, pRegion), + REGION_NUM_RECTS(pRegion)); + if (!clientClip) + return BadAlloc; + if (!REGION_COPY (pSCreen, clientClip, pRegion)) + { + REGION_DESTROY (pScreen, clientClip); + return BadAlloc; + } + } + else + { + type = CT_NONE; + clientClip = 0; + } + + result =(*ps->ChangePictureClip) (pPicture, type, + (pointer) clientClip, 0); + if (result == Success) + { + pPicture->clipOrigin.x = xOrigin; + pPicture->clipOrigin.y = yOrigin; + pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask; + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + } + return result; +} + +static Bool +transformIsIdentity(PictTransform *t) +{ + return ((t->matrix[0][0] == t->matrix[1][1]) && + (t->matrix[0][0] == t->matrix[2][2]) && + (t->matrix[0][0] != 0) && + (t->matrix[0][1] == 0) && + (t->matrix[0][2] == 0) && + (t->matrix[1][0] == 0) && + (t->matrix[1][2] == 0) && + (t->matrix[2][0] == 0) && + (t->matrix[2][1] == 0)); +} + +int +SetPictureTransform (PicturePtr pPicture, + PictTransform *transform) +{ + if (transform && transformIsIdentity (transform)) + transform = 0; + + if (transform) + { + if (!pPicture->transform) + { + pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform)); + if (!pPicture->transform) + return BadAlloc; + } + *pPicture->transform = *transform; + } + else + { + if (pPicture->transform) + { + xfree (pPicture->transform); + pPicture->transform = 0; + } + } + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + + if (pPicture->pDrawable != NULL) { + int result; + PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen); + + result = (*ps->ChangePictureTransform) (pPicture, transform); + + return result; + } + + return Success; +} + +void +CopyPicture (PicturePtr pSrc, + Mask mask, + PicturePtr pDst) +{ + PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen); + Mask origMask = mask; + + pDst->serialNumber |= GC_CHANGE_SERIAL_BIT; + pDst->stateChanges |= mask; + + while (mask) { + Mask bit = lowbit(mask); + + switch (bit) + { + case CPRepeat: + pDst->repeat = pSrc->repeat; + pDst->repeatType = pSrc->repeatType; + break; + case CPAlphaMap: + if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP) + pSrc->alphaMap->refcnt++; + if (pDst->alphaMap) + FreePicture ((pointer) pDst->alphaMap, (XID) 0); + pDst->alphaMap = pSrc->alphaMap; + break; + case CPAlphaXOrigin: + pDst->alphaOrigin.x = pSrc->alphaOrigin.x; + break; + case CPAlphaYOrigin: + pDst->alphaOrigin.y = pSrc->alphaOrigin.y; + break; + case CPClipXOrigin: + pDst->clipOrigin.x = pSrc->clipOrigin.x; + break; + case CPClipYOrigin: + pDst->clipOrigin.y = pSrc->clipOrigin.y; + break; + case CPClipMask: + switch (pSrc->clientClipType) { + case CT_NONE: + (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0); + break; + case CT_REGION: + if (!pSrc->clientClip) { + (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0); + } else { + RegionPtr clientClip; + RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip; + + clientClip = REGION_CREATE(pSrc->pDrawable->pScreen, + REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip), + REGION_NUM_RECTS(srcClientClip)); + (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0); + } + break; + default: + /* XXX: CT_PIXMAP unimplemented */ + break; + } + break; + case CPGraphicsExposure: + pDst->graphicsExposures = pSrc->graphicsExposures; + break; + case CPPolyEdge: + pDst->polyEdge = pSrc->polyEdge; + break; + case CPPolyMode: + pDst->polyMode = pSrc->polyMode; + break; + case CPDither: + pDst->dither = pSrc->dither; + break; + case CPComponentAlpha: + pDst->componentAlpha = pSrc->componentAlpha; + break; + } + mask &= ~bit; + } + + (*ps->ChangePicture)(pDst, origMask); +} + +static void +ValidateOnePicture (PicturePtr pPicture) +{ + if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber) + { + PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen); + + (*ps->ValidatePicture) (pPicture, pPicture->stateChanges); + pPicture->stateChanges = 0; + pPicture->serialNumber = pPicture->pDrawable->serialNumber; + } +} + +void +ValidatePicture(PicturePtr pPicture) +{ + ValidateOnePicture (pPicture); + if (pPicture->alphaMap) + ValidateOnePicture (pPicture->alphaMap); +} + +int +FreePicture (pointer value, + XID pid) +{ + PicturePtr pPicture = (PicturePtr) value; + + if (--pPicture->refcnt == 0) + { + if (pPicture->transform) + xfree (pPicture->transform); + + if (pPicture->pSourcePict) + { + if (pPicture->pSourcePict->type != SourcePictTypeSolidFill) + xfree(pPicture->pSourcePict->linear.stops); + + xfree(pPicture->pSourcePict); + } + + if (pPicture->pDrawable) + { + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + if (pPicture->alphaMap) + FreePicture ((pointer) pPicture->alphaMap, (XID) 0); + (*ps->DestroyPicture) (pPicture); + (*ps->DestroyPictureClip) (pPicture); + if (pPicture->pDrawable->type == DRAWABLE_WINDOW) + { + WindowPtr pWindow = (WindowPtr) pPicture->pDrawable; + PicturePtr *pPrev; + + for (pPrev = (PicturePtr *)dixLookupPrivateAddr + (&pWindow->devPrivates, PictureWindowPrivateKey); + *pPrev; + pPrev = &(*pPrev)->pNext) + { + if (*pPrev == pPicture) + { + *pPrev = pPicture->pNext; + break; + } + } + } + else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP) + { + (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable); + } + } + dixFreePrivates(pPicture->devPrivates); + xfree (pPicture); + } + return Success; +} + +int +FreePictFormat (pointer pPictFormat, + XID pid) +{ + return Success; +} + +/** + * ReduceCompositeOp is used to choose simpler ops for cases where alpha + * channels are always one and so math on the alpha channel per pixel becomes + * unnecessary. It may also avoid destination reads sometimes if apps aren't + * being careful to avoid these cases. + */ +static CARD8 +ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, + INT16 xSrc, INT16 ySrc, CARD16 width, CARD16 height) +{ + Bool no_src_alpha, no_dst_alpha; + + /* Sampling off the edge of a RepeatNone picture introduces alpha + * even if the picture itself doesn't have alpha. We don't try to + * detect every case where we don't sample off the edge, just the + * simplest case where there is no transform on the source + * picture. + */ + no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) && + PICT_FORMAT_A(pSrc->format) == 0 && + (pSrc->repeatType != RepeatNone || + (!pSrc->transform && + xSrc >= 0 && ySrc >= 0 && + xSrc + width <= pSrc->pDrawable->width && + ySrc + height <= pSrc->pDrawable->height)) && + pSrc->alphaMap == NULL && + pMask == NULL; + no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) && + PICT_FORMAT_A(pDst->format) == 0 && + pDst->alphaMap == NULL; + + /* TODO, maybe: Conjoint and Disjoint op reductions? */ + + /* Deal with simplifications where the source alpha is always 1. */ + if (no_src_alpha) + { + switch (op) { + case PictOpOver: + op = PictOpSrc; + break; + case PictOpInReverse: + op = PictOpDst; + break; + case PictOpOutReverse: + op = PictOpClear; + break; + case PictOpAtop: + op = PictOpIn; + break; + case PictOpAtopReverse: + op = PictOpOverReverse; + break; + case PictOpXor: + op = PictOpOut; + break; + default: + break; + } + } + + /* Deal with simplifications when the destination alpha is always 1 */ + if (no_dst_alpha) + { + switch (op) { + case PictOpOverReverse: + op = PictOpDst; + break; + case PictOpIn: + op = PictOpSrc; + break; + case PictOpOut: + op = PictOpClear; + break; + case PictOpAtop: + op = PictOpOver; + break; + case PictOpXor: + op = PictOpOutReverse; + break; + default: + break; + } + } + + /* Reduce some con/disjoint ops to the basic names. */ + switch (op) { + case PictOpDisjointClear: + case PictOpConjointClear: + op = PictOpClear; + break; + case PictOpDisjointSrc: + case PictOpConjointSrc: + op = PictOpSrc; + break; + case PictOpDisjointDst: + case PictOpConjointDst: + op = PictOpDst; + break; + default: + break; + } + + return op; +} + +void +CompositePicture (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + if (pMask) + ValidatePicture (pMask); + ValidatePicture (pDst); + + op = ReduceCompositeOp (op, pSrc, pMask, pDst, xSrc, ySrc, width, height); + if (op == PictOpDst) + return; + + (*ps->Composite) (op, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height); +} + +void +CompositeRects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pDst); + (*ps->CompositeRects) (op, pDst, color, nRect, rects); +} + +void +CompositeTrapezoids (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps); +} + +void +CompositeTriangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntriangles, + xTriangle *triangles) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles); +} + +void +CompositeTriStrip (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points); +} + +void +CompositeTriFan (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points); +} + +void +AddTraps (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntrap, + xTrap *traps) +{ + PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen); + + ValidatePicture (pPicture); + (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps); +} + +_X_EXPORT Bool +PictureTransformPoint3d (PictTransformPtr transform, + PictVectorPtr vector) +{ + PictVector result; + int i, j; + xFixed_32_32 partial; + xFixed_48_16 v; + + for (j = 0; j < 3; j++) + { + v = 0; + for (i = 0; i < 3; i++) + { + partial = ((xFixed_48_16) transform->matrix[j][i] * + (xFixed_48_16) vector->vector[i]); + v += partial >> 16; + } + if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) + return FALSE; + result.vector[j] = (xFixed) v; + } + if (!result.vector[2]) + return FALSE; + *vector = result; + return TRUE; +} + + +_X_EXPORT Bool +PictureTransformPoint (PictTransformPtr transform, + PictVectorPtr vector) +{ + PictVector result; + int i, j; + xFixed_32_32 partial; + xFixed_48_16 v; + + for (j = 0; j < 3; j++) + { + v = 0; + for (i = 0; i < 3; i++) + { + partial = ((xFixed_48_16) transform->matrix[j][i] * + (xFixed_48_16) vector->vector[i]); + v += partial >> 16; + } + if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) + return FALSE; + result.vector[j] = (xFixed) v; + } + if (!result.vector[2]) + return FALSE; + for (j = 0; j < 2; j++) + { + partial = (xFixed_48_16) result.vector[j] << 16; + v = partial / result.vector[2]; + if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) + return FALSE; + vector->vector[j] = (xFixed) v; + } + vector->vector[2] = xFixed1; + return TRUE; +} diff --git a/xorg-server/render/picture.h b/xorg-server/render/picture.h new file mode 100644 index 000000000..045b29944 --- /dev/null +++ b/xorg-server/render/picture.h @@ -0,0 +1,222 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _PICTURE_H_ +#define _PICTURE_H_ + +#include <pixman.h> + +typedef struct _DirectFormat *DirectFormatPtr; +typedef struct _PictFormat *PictFormatPtr; +typedef struct _Picture *PicturePtr; + +/* + * While the protocol is generous in format support, the + * sample implementation allows only packed RGB and GBR + * representations for data to simplify software rendering, + */ +#define PICT_FORMAT(bpp,type,a,r,g,b) PIXMAN_FORMAT(bpp, type, a, r, g, b) + +/* + * gray/color formats use a visual index instead of argb + */ +#define PICT_VISFORMAT(bpp,type,vi) (((bpp) << 24) | \ + ((type) << 16) | \ + ((vi))) + +#define PICT_FORMAT_BPP(f) PIXMAN_FORMAT_BPP(f) +#define PICT_FORMAT_TYPE(f) PIXMAN_FORMAT_TYPE(f) +#define PICT_FORMAT_A(f) PIXMAN_FORMAT_A(f) +#define PICT_FORMAT_R(f) PIXMAN_FORMAT_R(f) +#define PICT_FORMAT_G(f) PIXMAN_FORMAT_G(f) +#define PICT_FORMAT_B(f) PIXMAN_FORMAT_B(f) +#define PICT_FORMAT_RGB(f) PIXMAN_FORMAT_RGB(f) +#define PICT_FORMAT_VIS(f) PIXMAN_FORMAT_VIS(f) + +#define PICT_TYPE_OTHER PIXMAN_TYPE_OTHER +#define PICT_TYPE_A PIXMAN_TYPE_A +#define PICT_TYPE_ARGB PIXMAN_TYPE_ARGB +#define PICT_TYPE_ABGR PIXMAN_TYPE_ABGR +#define PICT_TYPE_COLOR PIXMAN_TYPE_COLOR +#define PICT_TYPE_GRAY PIXMAN_TYPE_GRAY + +#define PICT_FORMAT_COLOR(f) PIXMAN_FORMAT_COLOR(f) + +/* 32bpp formats */ +typedef enum _PictFormatShort { + PICT_a8r8g8b8 = PIXMAN_a8r8g8b8, + PICT_x8r8g8b8 = PIXMAN_x8r8g8b8, + PICT_a8b8g8r8 = PIXMAN_a8b8g8r8, + PICT_x8b8g8r8 = PIXMAN_x8b8g8r8, + +/* 24bpp formats */ + PICT_r8g8b8 = PIXMAN_r8g8b8, + PICT_b8g8r8 = PIXMAN_b8g8r8, + +/* 16bpp formats */ + PICT_r5g6b5 = PIXMAN_r5g6b5, + PICT_b5g6r5 = PIXMAN_b5g6r5, + + PICT_a1r5g5b5 = PIXMAN_a1r5g5b5, + PICT_x1r5g5b5 = PIXMAN_x1r5g5b5, + PICT_a1b5g5r5 = PIXMAN_a1b5g5r5, + PICT_x1b5g5r5 = PIXMAN_x1b5g5r5, + PICT_a4r4g4b4 = PIXMAN_a4r4g4b4, + PICT_x4r4g4b4 = PIXMAN_x4r4g4b4, + PICT_a4b4g4r4 = PIXMAN_a4b4g4r4, + PICT_x4b4g4r4 = PIXMAN_x4b4g4r4, + +/* 8bpp formats */ + PICT_a8 = PIXMAN_a8, + PICT_r3g3b2 = PIXMAN_r3g3b2, + PICT_b2g3r3 = PIXMAN_b2g3r3, + PICT_a2r2g2b2 = PIXMAN_a2r2g2b2, + PICT_a2b2g2r2 = PIXMAN_a2b2g2r2, + + PICT_c8 = PIXMAN_c8, + PICT_g8 = PIXMAN_g8, + + PICT_x4a4 = PIXMAN_x4a4, + + PICT_x4c4 = PIXMAN_x4c4, + PICT_x4g4 = PIXMAN_x4g4, + +/* 4bpp formats */ + PICT_a4 = PIXMAN_a4, + PICT_r1g2b1 = PIXMAN_r1g2b1, + PICT_b1g2r1 = PIXMAN_b1g2r1, + PICT_a1r1g1b1 = PIXMAN_a1r1g1b1, + PICT_a1b1g1r1 = PIXMAN_a1b1g1r1, + + PICT_c4 = PIXMAN_c4, + PICT_g4 = PIXMAN_g4, + +/* 1bpp formats */ + PICT_a1 = PIXMAN_a1, + + PICT_g1 = PIXMAN_g1 +} PictFormatShort; + +/* + * For dynamic indexed visuals (GrayScale and PseudoColor), these control the + * selection of colors allocated for drawing to Pictures. The default + * policy depends on the size of the colormap: + * + * Size Default Policy + * ---------------------------- + * < 64 PolicyMono + * < 256 PolicyGray + * 256 PolicyColor (only on PseudoColor) + * + * The actual allocation code lives in miindex.c, and so is + * austensibly server dependent, but that code does: + * + * PolicyMono Allocate no additional colors, use black and white + * PolicyGray Allocate 13 gray levels (11 cells used) + * PolicyColor Allocate a 4x4x4 cube and 13 gray levels (71 cells used) + * PolicyAll Allocate as big a cube as possible, fill with gray (all) + * + * Here's a picture to help understand how many colors are + * actually allocated (this is just the gray ramp): + * + * gray level + * all 0000 1555 2aaa 4000 5555 6aaa 8000 9555 aaaa bfff d555 eaaa ffff + * b/w 0000 ffff + * 4x4x4 5555 aaaa + * extra 1555 2aaa 4000 6aaa 8000 9555 bfff d555 eaaa + * + * The default colormap supplies two gray levels (black/white), the + * 4x4x4 cube allocates another two and nine more are allocated to fill + * in the 13 levels. When the 4x4x4 cube is not allocated, a total of + * 11 cells are allocated. + */ + +#define PictureCmapPolicyInvalid -1 +#define PictureCmapPolicyDefault 0 +#define PictureCmapPolicyMono 1 +#define PictureCmapPolicyGray 2 +#define PictureCmapPolicyColor 3 +#define PictureCmapPolicyAll 4 + +extern int PictureCmapPolicy; + +int PictureParseCmapPolicy (const char *name); + +extern int RenderErrBase; +extern DevPrivateKey RenderClientPrivateKey; + +/* Fixed point updates from Carl Worth, USC, Information Sciences Institute */ + +typedef pixman_fixed_32_32_t xFixed_32_32; + +typedef pixman_fixed_48_16_t xFixed_48_16; + +#define MAX_FIXED_48_16 pixman_max_fixed_48_16 +#define MIN_FIXED_48_16 pixman_min_fixed_48_16 + +typedef pixman_fixed_1_31_t xFixed_1_31; +typedef pixman_fixed_1_16_t xFixed_1_16; +typedef pixman_fixed_16_16_t xFixed_16_16; + +/* + * An unadorned "xFixed" is the same as xFixed_16_16, + * (since it's quite common in the code) + */ +typedef pixman_fixed_t xFixed; +#define XFIXED_BITS 16 + +#define xFixedToInt(f) pixman_fixed_to_int(f) +#define IntToxFixed(i) pixman_int_to_fixed(i) +#define xFixedE pixman_fixed_e +#define xFixed1 pixman_fixed_1 +#define xFixed1MinusE pixman_fixed_1_minus_e +#define xFixedFrac(f) pixman_fixed_frac(f) +#define xFixedFloor(f) pixman_fixed_floor(f) +#define xFixedCeil(f) pixman_fixed_ceil(f) + +#define xFixedFraction(f) pixman_fixed_fraction(f) +#define xFixedMod2(f) pixman_fixed_mod2(f) + +/* whether 't' is a well defined not obviously empty trapezoid */ +#define xTrapezoidValid(t) ((t)->left.p1.y != (t)->left.p2.y && \ + (t)->right.p1.y != (t)->right.p2.y && \ + (int) ((t)->bottom - (t)->top) > 0) + +/* + * Standard NTSC luminance conversions: + * + * y = r * 0.299 + g * 0.587 + b * 0.114 + * + * Approximate this for a bit more speed: + * + * y = (r * 153 + g * 301 + b * 58) / 512 + * + * This gives 17 bits of luminance; to get 15 bits, lop the low two + */ + +#define CvtR8G8B8toY15(s) (((((s) >> 16) & 0xff) * 153 + \ + (((s) >> 8) & 0xff) * 301 + \ + (((s) ) & 0xff) * 58) >> 2) + +#endif /* _PICTURE_H_ */ diff --git a/xorg-server/render/picturestr.h b/xorg-server/render/picturestr.h new file mode 100644 index 000000000..acd15c7fe --- /dev/null +++ b/xorg-server/render/picturestr.h @@ -0,0 +1,679 @@ +/* + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _PICTURESTR_H_ +#define _PICTURESTR_H_ + +#include "scrnintstr.h" +#include "glyphstr.h" +#include "resource.h" +#include "privates.h" + +typedef struct _DirectFormat { + CARD16 red, redMask; + CARD16 green, greenMask; + CARD16 blue, blueMask; + CARD16 alpha, alphaMask; +} DirectFormatRec; + +typedef struct _IndexFormat { + VisualID vid; + ColormapPtr pColormap; + int nvalues; + xIndexValue *pValues; + void *devPrivate; +} IndexFormatRec; + +typedef struct _PictFormat { + CARD32 id; + CARD32 format; /* except bpp */ + unsigned char type; + unsigned char depth; + DirectFormatRec direct; + IndexFormatRec index; +} PictFormatRec; + +typedef struct pixman_vector PictVector, *PictVectorPtr; +typedef struct pixman_transform PictTransform, *PictTransformPtr; + +#define PICT_GRADIENT_STOPTABLE_SIZE 1024 +#define SourcePictTypeSolidFill 0 +#define SourcePictTypeLinear 1 +#define SourcePictTypeRadial 2 +#define SourcePictTypeConical 3 + +#define SourcePictClassUnknown 0 +#define SourcePictClassHorizontal 1 +#define SourcePictClassVertical 2 + +typedef struct _PictSolidFill { + unsigned int type; + unsigned int class; + CARD32 color; +} PictSolidFill, *PictSolidFillPtr; + +typedef struct _PictGradientStop { + xFixed x; + xRenderColor color; +} PictGradientStop, *PictGradientStopPtr; + +typedef struct _PictGradient { + unsigned int type; + unsigned int class; + int nstops; + PictGradientStopPtr stops; + int stopRange; + CARD32 *colorTable; + int colorTableSize; +} PictGradient, *PictGradientPtr; + +typedef struct _PictLinearGradient { + unsigned int type; + unsigned int class; + int nstops; + PictGradientStopPtr stops; + int stopRange; + CARD32 *colorTable; + int colorTableSize; + xPointFixed p1; + xPointFixed p2; +} PictLinearGradient, *PictLinearGradientPtr; + +typedef struct _PictCircle { + xFixed x; + xFixed y; + xFixed radius; +} PictCircle, *PictCirclePtr; + +typedef struct _PictRadialGradient { + unsigned int type; + unsigned int class; + int nstops; + PictGradientStopPtr stops; + int stopRange; + CARD32 *colorTable; + int colorTableSize; + PictCircle c1; + PictCircle c2; + double cdx; + double cdy; + double dr; + double A; +} PictRadialGradient, *PictRadialGradientPtr; + +typedef struct _PictConicalGradient { + unsigned int type; + unsigned int class; + int nstops; + PictGradientStopPtr stops; + int stopRange; + CARD32 *colorTable; + int colorTableSize; + xPointFixed center; + xFixed angle; +} PictConicalGradient, *PictConicalGradientPtr; + +typedef union _SourcePict { + unsigned int type; + PictSolidFill solidFill; + PictGradient gradient; + PictLinearGradient linear; + PictRadialGradient radial; + PictConicalGradient conical; +} SourcePict, *SourcePictPtr; + +typedef struct _Picture { + DrawablePtr pDrawable; + PictFormatPtr pFormat; + PictFormatShort format; /* PICT_FORMAT */ + int refcnt; + CARD32 id; + PicturePtr pNext; /* chain on same drawable */ + + unsigned int repeat : 1; + unsigned int graphicsExposures : 1; + unsigned int subWindowMode : 1; + unsigned int polyEdge : 1; + unsigned int polyMode : 1; + unsigned int freeCompClip : 1; + unsigned int clientClipType : 2; + unsigned int componentAlpha : 1; + unsigned int repeatType : 2; + unsigned int unused : 21; + + PicturePtr alphaMap; + DDXPointRec alphaOrigin; + + DDXPointRec clipOrigin; + pointer clientClip; + + Atom dither; + + unsigned long stateChanges; + unsigned long serialNumber; + + RegionPtr pCompositeClip; + + PrivateRec *devPrivates; + + PictTransform *transform; + + int filter; + xFixed *filter_params; + int filter_nparams; + SourcePictPtr pSourcePict; +} PictureRec; + +typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id, + xFixed *params, int nparams); +typedef struct { + char *name; + int id; + PictFilterValidateParamsProcPtr ValidateParams; +} PictFilterRec, *PictFilterPtr; + +#define PictFilterNearest 0 +#define PictFilterBilinear 1 + +#define PictFilterFast 2 +#define PictFilterGood 3 +#define PictFilterBest 4 + +#define PictFilterConvolution 5 + +typedef struct { + char *alias; + int alias_id; + int filter_id; +} PictFilterAliasRec, *PictFilterAliasPtr; + +typedef int (*CreatePictureProcPtr) (PicturePtr pPicture); +typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture); +typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture, + int clipType, + pointer value, + int n); +typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture); + +typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture, + PictTransform *transform); + +typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams); + +typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture); + +typedef void (*ChangePictureProcPtr) (PicturePtr pPicture, + Mask mask); +typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture, + Mask mask); +typedef void (*CompositeProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +typedef void (*GlyphsProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlists, + GlyphListPtr lists, + GlyphPtr *glyphs); + +typedef void (*CompositeRectsProcPtr) (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects); + +typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask, + xTrapezoid *trap, + int x_off, + int y_off); + +typedef void (*TrapezoidsProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps); + +typedef void (*TrianglesProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntri, + xTriangle *tris); + +typedef void (*TriStripProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points); + +typedef void (*TriFanProcPtr) (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points); + +typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen, + PictFormatPtr pFormat); + +typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen, + PictFormatPtr pFormat); + +typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen, + PictFormatPtr pFormat, + int ndef, + xColorItem *pdef); + +typedef void (*AddTrapsProcPtr) (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntrap, + xTrap *traps); + +typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntri, + xTriangle *tris); + +typedef Bool (*RealizeGlyphProcPtr) (ScreenPtr pScreen, + GlyphPtr glyph); + +typedef void (*UnrealizeGlyphProcPtr) (ScreenPtr pScreen, + GlyphPtr glyph); + +typedef struct _PictureScreen { + PictFormatPtr formats; + PictFormatPtr fallback; + int nformats; + + CreatePictureProcPtr CreatePicture; + DestroyPictureProcPtr DestroyPicture; + ChangePictureClipProcPtr ChangePictureClip; + DestroyPictureClipProcPtr DestroyPictureClip; + + ChangePictureProcPtr ChangePicture; + ValidatePictureProcPtr ValidatePicture; + + CompositeProcPtr Composite; + GlyphsProcPtr Glyphs; /* unused */ + CompositeRectsProcPtr CompositeRects; + + DestroyWindowProcPtr DestroyWindow; + CloseScreenProcPtr CloseScreen; + + StoreColorsProcPtr StoreColors; + + InitIndexedProcPtr InitIndexed; + CloseIndexedProcPtr CloseIndexed; + UpdateIndexedProcPtr UpdateIndexed; + + int subpixel; + + PictFilterPtr filters; + int nfilters; + PictFilterAliasPtr filterAliases; + int nfilterAliases; + + /** + * Called immediately after a picture's transform is changed through the + * SetPictureTransform request. Not called for source-only pictures. + */ + ChangePictureTransformProcPtr ChangePictureTransform; + + /** + * Called immediately after a picture's transform is changed through the + * SetPictureFilter request. Not called for source-only pictures. + */ + ChangePictureFilterProcPtr ChangePictureFilter; + + DestroyPictureFilterProcPtr DestroyPictureFilter; + + TrapezoidsProcPtr Trapezoids; + TrianglesProcPtr Triangles; + TriStripProcPtr TriStrip; + TriFanProcPtr TriFan; + + RasterizeTrapezoidProcPtr RasterizeTrapezoid; + + AddTrianglesProcPtr AddTriangles; + + AddTrapsProcPtr AddTraps; + + RealizeGlyphProcPtr RealizeGlyph; + UnrealizeGlyphProcPtr UnrealizeGlyph; + +} PictureScreenRec, *PictureScreenPtr; + +extern DevPrivateKey PictureScreenPrivateKey; +extern DevPrivateKey PictureWindowPrivateKey; +extern RESTYPE PictureType; +extern RESTYPE PictFormatType; +extern RESTYPE GlyphSetType; + +#define GetPictureScreen(s) ((PictureScreenPtr)dixLookupPrivate(&(s)->devPrivates, PictureScreenPrivateKey)) +#define GetPictureScreenIfSet(s) GetPictureScreen(s) +#define SetPictureScreen(s,p) dixSetPrivate(&(s)->devPrivates, PictureScreenPrivateKey, p) +#define GetPictureWindow(w) ((PicturePtr)dixLookupPrivate(&(w)->devPrivates, PictureWindowPrivateKey)) +#define SetPictureWindow(w,p) dixSetPrivate(&(w)->devPrivates, PictureWindowPrivateKey, p) + +#define GetGlyphPrivatesForScreen(glyph, s) \ + ((PrivateRec **)dixLookupPrivateAddr(&(glyph)->devPrivates, s)) + +#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\ + pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\ + if (!pPicture) { \ + client->errorValue = pid; \ + return err; \ + } \ +} + +#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\ + if (pid == None) \ + pPicture = 0; \ + else { \ + VERIFY_PICTURE(pPicture, pid, client, mode, err); \ + } \ +} \ + +Bool +PictureDestroyWindow (WindowPtr pWindow); + +Bool +PictureCloseScreen (int Index, ScreenPtr pScreen); + +void +PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef); + +Bool +PictureInitIndexedFormat (ScreenPtr pScreen, PictFormatPtr format); + +Bool +PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel); + +int +PictureGetSubpixelOrder (ScreenPtr pScreen); + +PictFormatPtr +PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp); + +PictFormatPtr +PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual); + +PictFormatPtr +PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format); + +Bool +PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats); + +int +PictureGetFilterId (char *filter, int len, Bool makeit); + +char * +PictureGetFilterName (int id); + +int +PictureAddFilter (ScreenPtr pScreen, + char *filter, + PictFilterValidateParamsProcPtr ValidateParams); + +Bool +PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias); + +Bool +PictureSetDefaultFilters (ScreenPtr pScreen); + +void +PictureResetFilters (ScreenPtr pScreen); + +PictFilterPtr +PictureFindFilter (ScreenPtr pScreen, char *name, int len); + +int +SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams); + +Bool +PictureFinishInit (void); + +void +SetPictureToDefaults (PicturePtr pPicture); + +PicturePtr +CreatePicture (Picture pid, + DrawablePtr pDrawable, + PictFormatPtr pFormat, + Mask mask, + XID *list, + ClientPtr client, + int *error); + +int +ChangePicture (PicturePtr pPicture, + Mask vmask, + XID *vlist, + DevUnion *ulist, + ClientPtr client); + +int +SetPictureClipRects (PicturePtr pPicture, + int xOrigin, + int yOrigin, + int nRect, + xRectangle *rects); + +int +SetPictureClipRegion (PicturePtr pPicture, + int xOrigin, + int yOrigin, + RegionPtr pRegion); + +int +SetPictureTransform (PicturePtr pPicture, + PictTransform *transform); + +void +CopyPicture (PicturePtr pSrc, + Mask mask, + PicturePtr pDst); + +void +ValidatePicture(PicturePtr pPicture); + +int +FreePicture (pointer pPicture, + XID pid); + +int +FreePictFormat (pointer pPictFormat, + XID pid); + +void +CompositePicture (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr lists, + GlyphPtr *glyphs); + +void +CompositeRects (CARD8 op, + PicturePtr pDst, + xRenderColor *color, + int nRect, + xRectangle *rects); + +void +CompositeTrapezoids (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps); + +void +CompositeTriangles (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntriangles, + xTriangle *triangles); + +void +CompositeTriStrip (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points); + +void +CompositeTriFan (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoints, + xPointFixed *points); + +Bool +PictureTransformPoint (PictTransformPtr transform, + PictVectorPtr vector); + +Bool +PictureTransformPoint3d (PictTransformPtr transform, + PictVectorPtr vector); + +CARD32 +PictureGradientColor (PictGradientStopPtr stop1, + PictGradientStopPtr stop2, + CARD32 x); + +void RenderExtensionInit (void); + +Bool +AnimCurInit (ScreenPtr pScreen); + +int +AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid); + +void +AddTraps (PicturePtr pPicture, + INT16 xOff, + INT16 yOff, + int ntraps, + xTrap *traps); + +pixman_image_t * +PixmanImageFromPicture (PicturePtr pPict, + Bool hasClip); + +PicturePtr +CreateSolidPicture (Picture pid, + xRenderColor *color, + int *error); + +PicturePtr +CreateLinearGradientPicture (Picture pid, + xPointFixed *p1, + xPointFixed *p2, + int nStops, + xFixed *stops, + xRenderColor *colors, + int *error); + +PicturePtr +CreateRadialGradientPicture (Picture pid, + xPointFixed *inner, + xPointFixed *outer, + xFixed innerRadius, + xFixed outerRadius, + int nStops, + xFixed *stops, + xRenderColor *colors, + int *error); + +PicturePtr +CreateConicalGradientPicture (Picture pid, + xPointFixed *center, + xFixed angle, + int nStops, + xFixed *stops, + xRenderColor *colors, + int *error); + +#ifdef PANORAMIX +void PanoramiXRenderInit (void); +void PanoramiXRenderReset (void); +#endif + +#endif /* _PICTURESTR_H_ */ diff --git a/xorg-server/render/render.c b/xorg-server/render/render.c new file mode 100644 index 000000000..638aa46a3 --- /dev/null +++ b/xorg-server/render/render.c @@ -0,0 +1,3317 @@ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#define NEED_REPLIES +#define NEED_EVENTS +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "colormapst.h" +#include "extnsionst.h" +#include "servermd.h" +#include <X11/extensions/render.h> +#include <X11/extensions/renderproto.h> +#include "picturestr.h" +#include "glyphstr.h" +#include <X11/Xfuncproto.h> +#include "cursorstr.h" +#include "xace.h" + +#if HAVE_STDINT_H +#include <stdint.h> +#elif !defined(UINT32_MAX) +#define UINT32_MAX 0xffffffffU +#endif + +static int ProcRenderQueryVersion (ClientPtr pClient); +static int ProcRenderQueryPictFormats (ClientPtr pClient); +static int ProcRenderQueryPictIndexValues (ClientPtr pClient); +static int ProcRenderQueryDithers (ClientPtr pClient); +static int ProcRenderCreatePicture (ClientPtr pClient); +static int ProcRenderChangePicture (ClientPtr pClient); +static int ProcRenderSetPictureClipRectangles (ClientPtr pClient); +static int ProcRenderFreePicture (ClientPtr pClient); +static int ProcRenderComposite (ClientPtr pClient); +static int ProcRenderScale (ClientPtr pClient); +static int ProcRenderTrapezoids (ClientPtr pClient); +static int ProcRenderTriangles (ClientPtr pClient); +static int ProcRenderTriStrip (ClientPtr pClient); +static int ProcRenderTriFan (ClientPtr pClient); +static int ProcRenderColorTrapezoids (ClientPtr pClient); +static int ProcRenderColorTriangles (ClientPtr pClient); +static int ProcRenderTransform (ClientPtr pClient); +static int ProcRenderCreateGlyphSet (ClientPtr pClient); +static int ProcRenderReferenceGlyphSet (ClientPtr pClient); +static int ProcRenderFreeGlyphSet (ClientPtr pClient); +static int ProcRenderAddGlyphs (ClientPtr pClient); +static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient); +static int ProcRenderFreeGlyphs (ClientPtr pClient); +static int ProcRenderCompositeGlyphs (ClientPtr pClient); +static int ProcRenderFillRectangles (ClientPtr pClient); +static int ProcRenderCreateCursor (ClientPtr pClient); +static int ProcRenderSetPictureTransform (ClientPtr pClient); +static int ProcRenderQueryFilters (ClientPtr pClient); +static int ProcRenderSetPictureFilter (ClientPtr pClient); +static int ProcRenderCreateAnimCursor (ClientPtr pClient); +static int ProcRenderAddTraps (ClientPtr pClient); +static int ProcRenderCreateSolidFill (ClientPtr pClient); +static int ProcRenderCreateLinearGradient (ClientPtr pClient); +static int ProcRenderCreateRadialGradient (ClientPtr pClient); +static int ProcRenderCreateConicalGradient (ClientPtr pClient); + +static int ProcRenderDispatch (ClientPtr pClient); + +static int SProcRenderQueryVersion (ClientPtr pClient); +static int SProcRenderQueryPictFormats (ClientPtr pClient); +static int SProcRenderQueryPictIndexValues (ClientPtr pClient); +static int SProcRenderQueryDithers (ClientPtr pClient); +static int SProcRenderCreatePicture (ClientPtr pClient); +static int SProcRenderChangePicture (ClientPtr pClient); +static int SProcRenderSetPictureClipRectangles (ClientPtr pClient); +static int SProcRenderFreePicture (ClientPtr pClient); +static int SProcRenderComposite (ClientPtr pClient); +static int SProcRenderScale (ClientPtr pClient); +static int SProcRenderTrapezoids (ClientPtr pClient); +static int SProcRenderTriangles (ClientPtr pClient); +static int SProcRenderTriStrip (ClientPtr pClient); +static int SProcRenderTriFan (ClientPtr pClient); +static int SProcRenderColorTrapezoids (ClientPtr pClient); +static int SProcRenderColorTriangles (ClientPtr pClient); +static int SProcRenderTransform (ClientPtr pClient); +static int SProcRenderCreateGlyphSet (ClientPtr pClient); +static int SProcRenderReferenceGlyphSet (ClientPtr pClient); +static int SProcRenderFreeGlyphSet (ClientPtr pClient); +static int SProcRenderAddGlyphs (ClientPtr pClient); +static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient); +static int SProcRenderFreeGlyphs (ClientPtr pClient); +static int SProcRenderCompositeGlyphs (ClientPtr pClient); +static int SProcRenderFillRectangles (ClientPtr pClient); +static int SProcRenderCreateCursor (ClientPtr pClient); +static int SProcRenderSetPictureTransform (ClientPtr pClient); +static int SProcRenderQueryFilters (ClientPtr pClient); +static int SProcRenderSetPictureFilter (ClientPtr pClient); +static int SProcRenderCreateAnimCursor (ClientPtr pClient); +static int SProcRenderAddTraps (ClientPtr pClient); +static int SProcRenderCreateSolidFill (ClientPtr pClient); +static int SProcRenderCreateLinearGradient (ClientPtr pClient); +static int SProcRenderCreateRadialGradient (ClientPtr pClient); +static int SProcRenderCreateConicalGradient (ClientPtr pClient); + +static int SProcRenderDispatch (ClientPtr pClient); + +int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = { + ProcRenderQueryVersion, + ProcRenderQueryPictFormats, + ProcRenderQueryPictIndexValues, + ProcRenderQueryDithers, + ProcRenderCreatePicture, + ProcRenderChangePicture, + ProcRenderSetPictureClipRectangles, + ProcRenderFreePicture, + ProcRenderComposite, + ProcRenderScale, + ProcRenderTrapezoids, + ProcRenderTriangles, + ProcRenderTriStrip, + ProcRenderTriFan, + ProcRenderColorTrapezoids, + ProcRenderColorTriangles, + ProcRenderTransform, + ProcRenderCreateGlyphSet, + ProcRenderReferenceGlyphSet, + ProcRenderFreeGlyphSet, + ProcRenderAddGlyphs, + ProcRenderAddGlyphsFromPicture, + ProcRenderFreeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderFillRectangles, + ProcRenderCreateCursor, + ProcRenderSetPictureTransform, + ProcRenderQueryFilters, + ProcRenderSetPictureFilter, + ProcRenderCreateAnimCursor, + ProcRenderAddTraps, + ProcRenderCreateSolidFill, + ProcRenderCreateLinearGradient, + ProcRenderCreateRadialGradient, + ProcRenderCreateConicalGradient +}; + +int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = { + SProcRenderQueryVersion, + SProcRenderQueryPictFormats, + SProcRenderQueryPictIndexValues, + SProcRenderQueryDithers, + SProcRenderCreatePicture, + SProcRenderChangePicture, + SProcRenderSetPictureClipRectangles, + SProcRenderFreePicture, + SProcRenderComposite, + SProcRenderScale, + SProcRenderTrapezoids, + SProcRenderTriangles, + SProcRenderTriStrip, + SProcRenderTriFan, + SProcRenderColorTrapezoids, + SProcRenderColorTriangles, + SProcRenderTransform, + SProcRenderCreateGlyphSet, + SProcRenderReferenceGlyphSet, + SProcRenderFreeGlyphSet, + SProcRenderAddGlyphs, + SProcRenderAddGlyphsFromPicture, + SProcRenderFreeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderFillRectangles, + SProcRenderCreateCursor, + SProcRenderSetPictureTransform, + SProcRenderQueryFilters, + SProcRenderSetPictureFilter, + SProcRenderCreateAnimCursor, + SProcRenderAddTraps, + SProcRenderCreateSolidFill, + SProcRenderCreateLinearGradient, + SProcRenderCreateRadialGradient, + SProcRenderCreateConicalGradient +}; + +static void +RenderResetProc (ExtensionEntry *extEntry); + +int RenderErrBase; +DevPrivateKey RenderClientPrivateKey; + +typedef struct _RenderClient { + int major_version; + int minor_version; +} RenderClientRec, *RenderClientPtr; + +#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey)) + +static void +RenderClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + RenderClientPtr pRenderClient = GetRenderClient (pClient); + + pRenderClient->major_version = 0; + pRenderClient->minor_version = 0; +} + +void +RenderExtensionInit (void) +{ + ExtensionEntry *extEntry; + + if (!PictureType) + return; + if (!PictureFinishInit ()) + return; + if (!dixRequestPrivate(RenderClientPrivateKey, sizeof(RenderClientRec))) + return; + if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0)) + return; + + extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors, + ProcRenderDispatch, SProcRenderDispatch, + RenderResetProc, StandardMinorOpcode); + if (!extEntry) + return; + RenderErrBase = extEntry->errorBase; +} + +static void +RenderResetProc (ExtensionEntry *extEntry) +{ +} + +static int +ProcRenderQueryVersion (ClientPtr client) +{ + RenderClientPtr pRenderClient = GetRenderClient (client); + xRenderQueryVersionReply rep; + register int n; + REQUEST(xRenderQueryVersionReq); + + pRenderClient->major_version = stuff->majorVersion; + pRenderClient->minor_version = stuff->minorVersion; + + REQUEST_SIZE_MATCH(xRenderQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = RENDER_MAJOR; + rep.minorVersion = RENDER_MINOR; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +static VisualPtr +findVisual (ScreenPtr pScreen, VisualID vid) +{ + VisualPtr pVisual; + int v; + + for (v = 0; v < pScreen->numVisuals; v++) + { + pVisual = pScreen->visuals + v; + if (pVisual->vid == vid) + return pVisual; + } + return 0; +} + +extern char *ConnectionInfo; + +static int +ProcRenderQueryPictFormats (ClientPtr client) +{ + RenderClientPtr pRenderClient = GetRenderClient (client); + xRenderQueryPictFormatsReply *reply; + xPictScreen *pictScreen; + xPictDepth *pictDepth; + xPictVisual *pictVisual; + xPictFormInfo *pictForm; + CARD32 *pictSubpixel; + ScreenPtr pScreen; + VisualPtr pVisual; + DepthPtr pDepth; + int v, d; + PictureScreenPtr ps; + PictFormatPtr pFormat; + int nformat; + int ndepth; + int nvisual; + int rlength; + int s; + int n; + int numScreens; + int numSubpixel; +/* REQUEST(xRenderQueryPictFormatsReq); */ + + REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); + +#ifdef PANORAMIX + if (noPanoramiXExtension) + numScreens = screenInfo.numScreens; + else + numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; +#else + numScreens = screenInfo.numScreens; +#endif + ndepth = nformat = nvisual = 0; + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = pScreen->allowedDepths + d; + ++ndepth; + + for (v = 0; v < pDepth->numVids; v++) + { + pVisual = findVisual (pScreen, pDepth->vids[v]); + if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual)) + ++nvisual; + } + } + ps = GetPictureScreenIfSet(pScreen); + if (ps) + nformat += ps->nformats; + } + if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6) + numSubpixel = 0; + else + numSubpixel = numScreens; + + rlength = (sizeof (xRenderQueryPictFormatsReply) + + nformat * sizeof (xPictFormInfo) + + numScreens * sizeof (xPictScreen) + + ndepth * sizeof (xPictDepth) + + nvisual * sizeof (xPictVisual) + + numSubpixel * sizeof (CARD32)); + reply = (xRenderQueryPictFormatsReply *) xalloc (rlength); + if (!reply) + return BadAlloc; + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = (rlength - sizeof(xGenericReply)) >> 2; + reply->numFormats = nformat; + reply->numScreens = numScreens; + reply->numDepths = ndepth; + reply->numVisuals = nvisual; + reply->numSubpixel = numSubpixel; + + pictForm = (xPictFormInfo *) (reply + 1); + + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + { + for (nformat = 0, pFormat = ps->formats; + nformat < ps->nformats; + nformat++, pFormat++) + { + pictForm->id = pFormat->id; + pictForm->type = pFormat->type; + pictForm->depth = pFormat->depth; + pictForm->direct.red = pFormat->direct.red; + pictForm->direct.redMask = pFormat->direct.redMask; + pictForm->direct.green = pFormat->direct.green; + pictForm->direct.greenMask = pFormat->direct.greenMask; + pictForm->direct.blue = pFormat->direct.blue; + pictForm->direct.blueMask = pFormat->direct.blueMask; + pictForm->direct.alpha = pFormat->direct.alpha; + pictForm->direct.alphaMask = pFormat->direct.alphaMask; + if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap) + pictForm->colormap = pFormat->index.pColormap->mid; + else + pictForm->colormap = None; + if (client->swapped) + { + swapl (&pictForm->id, n); + swaps (&pictForm->direct.red, n); + swaps (&pictForm->direct.redMask, n); + swaps (&pictForm->direct.green, n); + swaps (&pictForm->direct.greenMask, n); + swaps (&pictForm->direct.blue, n); + swaps (&pictForm->direct.blueMask, n); + swaps (&pictForm->direct.alpha, n); + swaps (&pictForm->direct.alphaMask, n); + swapl (&pictForm->colormap, n); + } + pictForm++; + } + } + } + + pictScreen = (xPictScreen *) pictForm; + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + pictDepth = (xPictDepth *) (pictScreen + 1); + ndepth = 0; + for (d = 0; d < pScreen->numDepths; d++) + { + pictVisual = (xPictVisual *) (pictDepth + 1); + pDepth = pScreen->allowedDepths + d; + + nvisual = 0; + for (v = 0; v < pDepth->numVids; v++) + { + pVisual = findVisual (pScreen, pDepth->vids[v]); + if (pVisual && (pFormat = PictureMatchVisual (pScreen, + pDepth->depth, + pVisual))) + { + pictVisual->visual = pVisual->vid; + pictVisual->format = pFormat->id; + if (client->swapped) + { + swapl (&pictVisual->visual, n); + swapl (&pictVisual->format, n); + } + pictVisual++; + nvisual++; + } + } + pictDepth->depth = pDepth->depth; + pictDepth->nPictVisuals = nvisual; + if (client->swapped) + { + swaps (&pictDepth->nPictVisuals, n); + } + ndepth++; + pictDepth = (xPictDepth *) pictVisual; + } + pictScreen->nDepth = ndepth; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + pictScreen->fallback = ps->fallback->id; + else + pictScreen->fallback = 0; + if (client->swapped) + { + swapl (&pictScreen->nDepth, n); + swapl (&pictScreen->fallback, n); + } + pictScreen = (xPictScreen *) pictDepth; + } + pictSubpixel = (CARD32 *) pictScreen; + + for (s = 0; s < numSubpixel; s++) + { + pScreen = screenInfo.screens[s]; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + *pictSubpixel = ps->subpixel; + else + *pictSubpixel = SubPixelUnknown; + if (client->swapped) + { + swapl (pictSubpixel, n); + } + ++pictSubpixel; + } + + if (client->swapped) + { + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swapl (&reply->numFormats, n); + swapl (&reply->numScreens, n); + swapl (&reply->numDepths, n); + swapl (&reply->numVisuals, n); + swapl (&reply->numSubpixel, n); + } + WriteToClient(client, rlength, (char *) reply); + xfree (reply); + return client->noClientException; +} + +static int +ProcRenderQueryPictIndexValues (ClientPtr client) +{ + PictFormatPtr pFormat; + int num; + int rlength; + int i, n; + REQUEST(xRenderQueryPictIndexValuesReq); + xRenderQueryPictIndexValuesReply *reply; + xIndexValue *values; + + REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); + + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->format, + PictFormatType, + DixReadAccess); + + if (!pFormat) + { + client->errorValue = stuff->format; + return RenderErrBase + BadPictFormat; + } + if (pFormat->type != PictTypeIndexed) + { + client->errorValue = stuff->format; + return BadMatch; + } + num = pFormat->index.nvalues; + rlength = (sizeof (xRenderQueryPictIndexValuesReply) + + num * sizeof(xIndexValue)); + reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength); + if (!reply) + return BadAlloc; + + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = (rlength - sizeof(xGenericReply)) >> 2; + reply->numIndexValues = num; + + values = (xIndexValue *) (reply + 1); + + memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue)); + + if (client->swapped) + { + for (i = 0; i < num; i++) + { + swapl (&values[i].pixel, n); + swaps (&values[i].red, n); + swaps (&values[i].green, n); + swaps (&values[i].blue, n); + swaps (&values[i].alpha, n); + } + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swapl (&reply->numIndexValues, n); + } + + WriteToClient(client, rlength, (char *) reply); + xfree(reply); + return (client->noClientException); +} + +static int +ProcRenderQueryDithers (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderCreatePicture (ClientPtr client) +{ + PicturePtr pPicture; + DrawablePtr pDrawable; + PictFormatPtr pFormat; + int len, error, rc; + REQUEST(xRenderCreatePictureReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess|DixAddAccess); + if (rc != Success) + return rc; + + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->format, + PictFormatType, + DixReadAccess); + if (!pFormat) + { + client->errorValue = stuff->format; + return RenderErrBase + BadPictFormat; + } + if (pFormat->depth != pDrawable->depth) + return BadMatch; + len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2); + if (Ones(stuff->mask) != len) + return BadLength; + + pPicture = CreatePicture (stuff->pid, + pDrawable, + pFormat, + stuff->mask, + (XID *) (stuff + 1), + client, + &error); + if (!pPicture) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int +ProcRenderChangePicture (ClientPtr client) +{ + PicturePtr pPicture; + REQUEST(xRenderChangePictureReq); + int len; + + REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess, + RenderErrBase + BadPicture); + + len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2); + if (Ones(stuff->mask) != len) + return BadLength; + + return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1), + (DevUnion *) 0, client); +} + +static int +ProcRenderSetPictureClipRectangles (ClientPtr client) +{ + REQUEST(xRenderSetPictureClipRectanglesReq); + PicturePtr pPicture; + int nr; + int result; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess, + RenderErrBase + BadPicture); + if (!pPicture->pDrawable) + return BadDrawable; + + nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq); + if (nr & 4) + return BadLength; + nr >>= 3; + result = SetPictureClipRects (pPicture, + stuff->xOrigin, stuff->yOrigin, + nr, (xRectangle *) &stuff[1]); + if (client->noClientException != Success) + return(client->noClientException); + else + return(result); +} + +static int +ProcRenderFreePicture (ClientPtr client) +{ + PicturePtr pPicture; + REQUEST(xRenderFreePictureReq); + + REQUEST_SIZE_MATCH(xRenderFreePictureReq); + + VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess, + RenderErrBase + BadPicture); + FreeResource (stuff->picture, RT_NONE); + return(client->noClientException); +} + +static Bool +PictOpValid (CARD8 op) +{ + if (/*PictOpMinimum <= op && */ op <= PictOpMaximum) + return TRUE; + if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum) + return TRUE; + if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum) + return TRUE; + return FALSE; +} + +static int +ProcRenderComposite (ClientPtr client) +{ + PicturePtr pSrc, pMask, pDst; + REQUEST(xRenderCompositeReq); + + REQUEST_SIZE_MATCH(xRenderCompositeReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess, + RenderErrBase + BadPicture); + if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || + (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen)) + return BadMatch; + CompositePicture (stuff->op, + pSrc, + pMask, + pDst, + stuff->xSrc, + stuff->ySrc, + stuff->xMask, + stuff->yMask, + stuff->xDst, + stuff->yDst, + stuff->width, + stuff->height); + return Success; +} + +static int +ProcRenderScale (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderTrapezoids (ClientPtr client) +{ + int ntraps; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrapezoidsReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->maskFormat, + PictFormatType, + DixReadAccess); + if (!pFormat) + { + client->errorValue = stuff->maskFormat; + return RenderErrBase + BadPictFormat; + } + } + else + pFormat = 0; + ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); + if (ntraps % sizeof (xTrapezoid)) + return BadLength; + ntraps /= sizeof (xTrapezoid); + if (ntraps) + CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + ntraps, (xTrapezoid *) &stuff[1]); + return client->noClientException; +} + +static int +ProcRenderTriangles (ClientPtr client) +{ + int ntris; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->maskFormat, + PictFormatType, + DixReadAccess); + if (!pFormat) + { + client->errorValue = stuff->maskFormat; + return RenderErrBase + BadPictFormat; + } + } + else + pFormat = 0; + ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq); + if (ntris % sizeof (xTriangle)) + return BadLength; + ntris /= sizeof (xTriangle); + if (ntris) + CompositeTriangles (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + ntris, (xTriangle *) &stuff[1]); + return client->noClientException; +} + +static int +ProcRenderTriStrip (ClientPtr client) +{ + int npoints; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->maskFormat, + PictFormatType, + DixReadAccess); + if (!pFormat) + { + client->errorValue = stuff->maskFormat; + return RenderErrBase + BadPictFormat; + } + } + else + pFormat = 0; + npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); + if (npoints & 4) + return(BadLength); + npoints >>= 3; + if (npoints >= 3) + CompositeTriStrip (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + npoints, (xPointFixed *) &stuff[1]); + return client->noClientException; +} + +static int +ProcRenderTriFan (ClientPtr client) +{ + int npoints; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->maskFormat, + PictFormatType, + DixReadAccess); + if (!pFormat) + { + client->errorValue = stuff->maskFormat; + return RenderErrBase + BadPictFormat; + } + } + else + pFormat = 0; + npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); + if (npoints & 4) + return(BadLength); + npoints >>= 3; + if (npoints >= 3) + CompositeTriFan (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + npoints, (xPointFixed *) &stuff[1]); + return client->noClientException; +} + +static int +ProcRenderColorTrapezoids (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderColorTriangles (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderTransform (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderCreateGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + PictFormatPtr format; + int rc, f; + REQUEST(xRenderCreateGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); + + LEGAL_NEW_RESOURCE(stuff->gsid, client); + format = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->format, + PictFormatType, + DixReadAccess); + if (!format) + { + client->errorValue = stuff->format; + return RenderErrBase + BadPictFormat; + } + switch (format->depth) { + case 1: + f = GlyphFormat1; + break; + case 4: + f = GlyphFormat4; + break; + case 8: + f = GlyphFormat8; + break; + case 16: + f = GlyphFormat16; + break; + case 32: + f = GlyphFormat32; + break; + default: + return BadMatch; + } + if (format->type != PictTypeDirect) + return BadMatch; + glyphSet = AllocateGlyphSet (f, format); + if (!glyphSet) + return BadAlloc; + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType, + glyphSet, RT_NONE, NULL, DixCreateAccess); + if (rc != Success) + return rc; + if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) + return BadAlloc; + return Success; +} + +static int +ProcRenderReferenceGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + int rc; + REQUEST(xRenderReferenceGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); + + LEGAL_NEW_RESOURCE(stuff->gsid, client); + + rc = dixLookupResource((pointer *)&glyphSet, stuff->existing, GlyphSetType, + client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->existing; + return (rc == BadValue) ? RenderErrBase + BadGlyphSet : rc; + } + glyphSet->refcnt++; + if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) + return BadAlloc; + return client->noClientException; +} + +#define NLOCALDELTA 64 +#define NLOCALGLYPH 256 + +static int +ProcRenderFreeGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + int rc; + REQUEST(xRenderFreeGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); + rc = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixDestroyAccess); + if (rc != Success) + { + client->errorValue = stuff->glyphset; + return (rc == BadValue) ? RenderErrBase + BadGlyphSet : rc; + } + FreeResource (stuff->glyphset, RT_NONE); + return client->noClientException; +} + +typedef struct _GlyphNew { + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; +} GlyphNewRec, *GlyphNewPtr; + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +static int +ProcRenderAddGlyphs (ClientPtr client) +{ + GlyphSetPtr glyphSet; + REQUEST(xRenderAddGlyphsReq); + GlyphNewRec glyphsLocal[NLOCALGLYPH]; + GlyphNewPtr glyphsBase, glyphs, glyph_new; + int remain, nglyphs; + CARD32 *gids; + xGlyphInfo *gi; + CARD8 *bits; + int size; + int err; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; + + REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); + err = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixAddAccess); + if (err != Success) + { + client->errorValue = stuff->glyphset; + return (err == BadValue) ? RenderErrBase + BadGlyphSet : err; + } + + err = BadAlloc; + nglyphs = stuff->nglyphs; + if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) + return BadAlloc; + + component_alpha = NeedsComponent (glyphSet->format->format); + + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); + glyphsBase = glyphsLocal; + } + else + { + glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec)); + if (!glyphsBase) + return BadAlloc; + } + + remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq); + + glyphs = glyphsBase; + + gids = (CARD32 *) (stuff + 1); + gi = (xGlyphInfo *) (gids + nglyphs); + bits = (CARD8 *) (gi + nglyphs); + remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; + for (i = 0; i < nglyphs; i++) + { + size_t padded_width; + glyph_new = &glyphs[i]; + + padded_width = PixmapBytePad (gi[i].width, + glyphSet->format->depth); + + if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height) + break; + + size = gi[i].height * padded_width; + if (remain < size) + break; + + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; + + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, + glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) + { + glyph_new->found = TRUE; + } + else + { + GlyphPtr glyph; + + glyph_new->found = FALSE; + glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph) + { + err = BadAlloc; + goto bail; + } + + for (screen = 0; screen < screenInfo.numScreens; screen++) + { + int width = gi[i].width; + int height = gi[i].height; + int depth = glyphSet->format->depth; + ScreenPtr pScreen; + int error; + + pScreen = screenInfo.screens[screen]; + pSrcPix = GetScratchPixmapHeader (pScreen, + width, height, + depth, depth, + -1, bits); + if (! pSrcPix) + { + err = BadAlloc; + goto bail; + } + + pSrc = CreatePicture (0, &pSrcPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pSrc) + { + err = BadAlloc; + goto bail; + } + + pDstPix = (pScreen->CreatePixmap) (pScreen, + width, height, depth, + CREATE_PIXMAP_USAGE_GLYPH_PICTURE); + + GlyphPicture (glyph)[screen] = pDst = + CreatePicture (0, &pDstPix->drawable, + glyphSet->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + /* The picture takes a reference to the pixmap, so we + drop ours. */ + (pScreen->DestroyPixmap) (pDstPix); + + if (! pDst) + { + err = BadAlloc; + goto bail; + } + + CompositePicture (PictOpSrc, + pSrc, + None, + pDst, + 0, 0, + 0, 0, + 0, 0, + width, height); + + FreePicture ((pointer) pSrc, 0); + pSrc = NULL; + FreeScratchPixmapHeader (pSrcPix); + pSrcPix = NULL; + } + + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); + } + + glyph_new->id = gids[i]; + + if (size & 3) + size += 4 - (size & 3); + bits += size; + remain -= size; + } + if (remain || i < nglyphs) + { + err = BadLength; + goto bail; + } + if (!ResizeGlyphSet (glyphSet, nglyphs)) + { + err = BadAlloc; + goto bail; + } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); + + if (glyphsBase != glyphsLocal) + Xfree (glyphsBase); + return client->noClientException; +bail: + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + xfree (glyphs[i].glyph); + if (glyphsBase != glyphsLocal) + Xfree (glyphsBase); + return err; +} + +static int +ProcRenderAddGlyphsFromPicture (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderFreeGlyphs (ClientPtr client) +{ + REQUEST(xRenderFreeGlyphsReq); + GlyphSetPtr glyphSet; + int rc, nglyph; + CARD32 *gids; + CARD32 glyph; + + REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); + rc = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixRemoveAccess); + if (rc != Success) + { + client->errorValue = stuff->glyphset; + return (rc == BadValue) ? RenderErrBase + BadGlyphSet : rc; + } + nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2; + gids = (CARD32 *) (stuff + 1); + while (nglyph-- > 0) + { + glyph = *gids++; + if (!DeleteGlyph (glyphSet, glyph)) + { + client->errorValue = glyph; + return RenderErrBase + BadGlyph; + } + } + return client->noClientException; +} + +static int +ProcRenderCompositeGlyphs (ClientPtr client) +{ + GlyphSetPtr glyphSet; + GlyphSet gs; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + GlyphListRec listsLocal[NLOCALDELTA]; + GlyphListPtr lists, listsBase; + GlyphPtr glyphsLocal[NLOCALGLYPH]; + Glyph glyph; + GlyphPtr *glyphs, *glyphsBase; + xGlyphElt *elt; + CARD8 *buffer, *end; + int nglyph; + int nlist; + int space; + int size; + int n; + + REQUEST(xRenderCompositeGlyphsReq); + + REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: size = 1; break; + case X_RenderCompositeGlyphs16: size = 2; break; + case X_RenderCompositeGlyphs32: size = 4; break; + } + + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + pFormat = (PictFormatPtr) SecurityLookupIDByType (client, + stuff->maskFormat, + PictFormatType, + DixReadAccess); + if (!pFormat) + { + client->errorValue = stuff->maskFormat; + return RenderErrBase + BadPictFormat; + } + } + else + pFormat = 0; + + glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, + stuff->glyphset, + GlyphSetType, + DixUseAccess); + if (!glyphSet) + { + client->errorValue = stuff->glyphset; + return RenderErrBase + BadGlyphSet; + } + + buffer = (CARD8 *) (stuff + 1); + end = (CARD8 *) stuff + (client->req_len << 2); + nglyph = 0; + nlist = 0; + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + if (elt->len == 0xff) + { + buffer += 4; + } + else + { + nlist++; + nglyph += elt->len; + space = size * elt->len; + if (space & 3) + space += 4 - (space & 3); + buffer += space; + } + } + if (nglyph <= NLOCALGLYPH) + glyphsBase = glyphsLocal; + else + { + glyphsBase = (GlyphPtr *) xalloc (nglyph * sizeof (GlyphPtr)); + if (!glyphsBase) + return BadAlloc; + } + if (nlist <= NLOCALDELTA) + listsBase = listsLocal; + else + { + listsBase = (GlyphListPtr) xalloc (nlist * sizeof (GlyphListRec)); + if (!listsBase) + return BadAlloc; + } + buffer = (CARD8 *) (stuff + 1); + glyphs = glyphsBase; + lists = listsBase; + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + if (elt->len == 0xff) + { + if (buffer + sizeof (GlyphSet) < end) + { + memcpy(&gs, buffer, sizeof(GlyphSet)); + glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, + gs, + GlyphSetType, + DixUseAccess); + if (!glyphSet) + { + client->errorValue = gs; + if (glyphsBase != glyphsLocal) + xfree (glyphsBase); + if (listsBase != listsLocal) + xfree (listsBase); + return RenderErrBase + BadGlyphSet; + } + } + buffer += 4; + } + else + { + lists->xOff = elt->deltax; + lists->yOff = elt->deltay; + lists->format = glyphSet->format; + lists->len = 0; + n = elt->len; + while (n--) + { + if (buffer + size <= end) + { + switch (size) { + case 1: + glyph = *((CARD8 *)buffer); break; + case 2: + glyph = *((CARD16 *)buffer); break; + case 4: + default: + glyph = *((CARD32 *)buffer); break; + } + if ((*glyphs = FindGlyph (glyphSet, glyph))) + { + lists->len++; + glyphs++; + } + } + buffer += size; + } + space = size * elt->len; + if (space & 3) + buffer += 4 - (space & 3); + lists++; + } + } + if (buffer > end) + return BadLength; + + CompositeGlyphs (stuff->op, + pSrc, + pDst, + pFormat, + stuff->xSrc, + stuff->ySrc, + nlist, + listsBase, + glyphsBase); + + if (glyphsBase != glyphsLocal) + xfree (glyphsBase); + if (listsBase != listsLocal) + xfree (listsBase); + + return client->noClientException; +} + +static int +ProcRenderFillRectangles (ClientPtr client) +{ + PicturePtr pDst; + int things; + REQUEST(xRenderFillRectanglesReq); + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pDst->pDrawable) + return BadDrawable; + + things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); + if (things & 4) + return(BadLength); + things >>= 3; + + CompositeRects (stuff->op, + pDst, + &stuff->color, + things, + (xRectangle *) &stuff[1]); + + return client->noClientException; +} + +static void +SetBit (unsigned char *line, int x, int bit) +{ + unsigned char mask; + + if (screenInfo.bitmapBitOrder == LSBFirst) + mask = (1 << (x & 7)); + else + mask = (0x80 >> (x & 7)); + /* XXX assumes byte order is host byte order */ + line += (x >> 3); + if (bit) + *line |= mask; + else + *line &= ~mask; +} + +#define DITHER_DIM 2 + +static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = { + { 1, 3, }, + { 4, 2, }, +}; + +#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) + +static int +ProcRenderCreateCursor (ClientPtr client) +{ + REQUEST(xRenderCreateCursorReq); + PicturePtr pSrc; + ScreenPtr pScreen; + unsigned short width, height; + CARD32 *argbbits, *argb; + unsigned char *srcbits, *srcline; + unsigned char *mskbits, *mskline; + int stride; + int x, y; + int nbytes_mono; + CursorMetricRec cm; + CursorPtr pCursor; + CARD32 twocolor[3]; + int rc, ncolor; + + REQUEST_SIZE_MATCH (xRenderCreateCursorReq); + LEGAL_NEW_RESOURCE(stuff->cid, client); + + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + if (!pSrc->pDrawable) + return BadDrawable; + pScreen = pSrc->pDrawable->pScreen; + width = pSrc->pDrawable->width; + height = pSrc->pDrawable->height; + if (height && width > UINT32_MAX/(height*sizeof(CARD32))) + return BadAlloc; + if ( stuff->x > width + || stuff->y > height ) + return (BadMatch); + argbbits = xalloc (width * height * sizeof (CARD32)); + if (!argbbits) + return (BadAlloc); + + stride = BitmapBytePad(width); + nbytes_mono = stride*height; + srcbits = (unsigned char *)xalloc(nbytes_mono); + if (!srcbits) + { + xfree (argbbits); + return (BadAlloc); + } + mskbits = (unsigned char *)xalloc(nbytes_mono); + if (!mskbits) + { + xfree(argbbits); + xfree(srcbits); + return (BadAlloc); + } + bzero ((char *) mskbits, nbytes_mono); + bzero ((char *) srcbits, nbytes_mono); + + if (pSrc->format == PICT_a8r8g8b8) + { + (*pScreen->GetImage) (pSrc->pDrawable, + 0, 0, width, height, ZPixmap, + 0xffffffff, (pointer) argbbits); + } + else + { + PixmapPtr pPixmap; + PicturePtr pPicture; + PictFormatPtr pFormat; + int error; + + pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); + if (!pFormat) + { + xfree (argbbits); + xfree (srcbits); + xfree (mskbits); + return (BadImplementation); + } + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) + { + xfree (argbbits); + xfree (srcbits); + xfree (mskbits); + return (BadAlloc); + } + pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, + client, &error); + if (!pPicture) + { + xfree (argbbits); + xfree (srcbits); + xfree (mskbits); + return error; + } + (*pScreen->DestroyPixmap) (pPixmap); + CompositePicture (PictOpSrc, + pSrc, 0, pPicture, + 0, 0, 0, 0, 0, 0, width, height); + (*pScreen->GetImage) (pPicture->pDrawable, + 0, 0, width, height, ZPixmap, + 0xffffffff, (pointer) argbbits); + FreePicture (pPicture, 0); + } + /* + * Check whether the cursor can be directly supported by + * the core cursor code + */ + ncolor = 0; + argb = argbbits; + for (y = 0; ncolor <= 2 && y < height; y++) + { + for (x = 0; ncolor <= 2 && x < width; x++) + { + CARD32 p = *argb++; + CARD32 a = (p >> 24); + + if (a == 0) /* transparent */ + continue; + if (a == 0xff) /* opaque */ + { + int n; + for (n = 0; n < ncolor; n++) + if (p == twocolor[n]) + break; + if (n == ncolor) + twocolor[ncolor++] = p; + } + else + ncolor = 3; + } + } + + /* + * Convert argb image to two plane cursor + */ + srcline = srcbits; + mskline = mskbits; + argb = argbbits; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + CARD32 p = *argb++; + + if (ncolor <= 2) + { + CARD32 a = ((p >> 24)); + + SetBit (mskline, x, a != 0); + SetBit (srcline, x, a != 0 && p == twocolor[0]); + } + else + { + CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255; + CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255; + CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)]; + /* Set mask from dithered alpha value */ + SetBit(mskline, x, a > d); + /* Set src from dithered intensity value */ + SetBit(srcline, x, a > d && i <= d); + } + } + srcline += stride; + mskline += stride; + } + /* + * Dither to white and black if the cursor has more than two colors + */ + if (ncolor > 2) + { + twocolor[0] = 0xff000000; + twocolor[1] = 0xffffffff; + } + else + { + xfree (argbbits); + argbbits = 0; + } + +#define GetByte(p,s) (((p) >> (s)) & 0xff) +#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8)) + + cm.width = width; + cm.height = height; + cm.xhot = stuff->x; + cm.yhot = stuff->y; + rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm, + GetColor(twocolor[0], 16), + GetColor(twocolor[0], 8), + GetColor(twocolor[0], 0), + GetColor(twocolor[1], 16), + GetColor(twocolor[1], 8), + GetColor(twocolor[1], 0), + &pCursor, client, stuff->cid); + if (rc != Success) + return rc; + if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) + return BadAlloc; + + return client->noClientException; +} + +static int +ProcRenderSetPictureTransform (ClientPtr client) +{ + REQUEST(xRenderSetPictureTransformReq); + PicturePtr pPicture; + int result; + + REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess, + RenderErrBase + BadPicture); + result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform); + if (client->noClientException != Success) + return(client->noClientException); + else + return(result); +} + +static int +ProcRenderQueryFilters (ClientPtr client) +{ + REQUEST (xRenderQueryFiltersReq); + DrawablePtr pDrawable; + xRenderQueryFiltersReply *reply; + int nbytesName; + int nnames; + ScreenPtr pScreen; + PictureScreenPtr ps; + int i, j, len, total_bytes, rc; + INT16 *aliases; + char *names; + + REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + + pScreen = pDrawable->pScreen; + nbytesName = 0; + nnames = 0; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + { + for (i = 0; i < ps->nfilters; i++) + nbytesName += 1 + strlen (ps->filters[i].name); + for (i = 0; i < ps->nfilterAliases; i++) + nbytesName += 1 + strlen (ps->filterAliases[i].alias); + nnames = ps->nfilters + ps->nfilterAliases; + } + len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2); + total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2); + reply = (xRenderQueryFiltersReply *) xalloc (total_bytes); + if (!reply) + return BadAlloc; + aliases = (INT16 *) (reply + 1); + names = (char *) (aliases + ((nnames + 1) & ~1)); + + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = len; + reply->numAliases = nnames; + reply->numFilters = nnames; + if (ps) + { + + /* fill in alias values */ + for (i = 0; i < ps->nfilters; i++) + aliases[i] = FilterAliasNone; + for (i = 0; i < ps->nfilterAliases; i++) + { + for (j = 0; j < ps->nfilters; j++) + if (ps->filterAliases[i].filter_id == ps->filters[j].id) + break; + if (j == ps->nfilters) + { + for (j = 0; j < ps->nfilterAliases; j++) + if (ps->filterAliases[i].filter_id == + ps->filterAliases[j].alias_id) + { + break; + } + if (j == ps->nfilterAliases) + j = FilterAliasNone; + else + j = j + ps->nfilters; + } + aliases[i + ps->nfilters] = j; + } + + /* fill in filter names */ + for (i = 0; i < ps->nfilters; i++) + { + j = strlen (ps->filters[i].name); + *names++ = j; + strncpy (names, ps->filters[i].name, j); + names += j; + } + + /* fill in filter alias names */ + for (i = 0; i < ps->nfilterAliases; i++) + { + j = strlen (ps->filterAliases[i].alias); + *names++ = j; + strncpy (names, ps->filterAliases[i].alias, j); + names += j; + } + } + + if (client->swapped) + { + register int n; + + for (i = 0; i < reply->numAliases; i++) + { + swaps (&aliases[i], n); + } + swaps(&reply->sequenceNumber, n); + swapl(&reply->length, n); + swapl(&reply->numAliases, n); + swapl(&reply->numFilters, n); + } + WriteToClient(client, total_bytes, (char *) reply); + xfree (reply); + + return(client->noClientException); +} + +static int +ProcRenderSetPictureFilter (ClientPtr client) +{ + REQUEST (xRenderSetPictureFilterReq); + PicturePtr pPicture; + int result; + xFixed *params; + int nparams; + char *name; + + REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess, + RenderErrBase + BadPicture); + name = (char *) (stuff + 1); + params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3)); + nparams = ((xFixed *) stuff + client->req_len) - params; + result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams); + return result; +} + +static int +ProcRenderCreateAnimCursor (ClientPtr client) +{ + REQUEST(xRenderCreateAnimCursorReq); + CursorPtr *cursors; + CARD32 *deltas; + CursorPtr pCursor; + int ncursor; + xAnimCursorElt *elt; + int i; + int ret; + + REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); + LEGAL_NEW_RESOURCE(stuff->cid, client); + if (client->req_len & 1) + return BadLength; + ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1; + cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32))); + if (!cursors) + return BadAlloc; + deltas = (CARD32 *) (cursors + ncursor); + elt = (xAnimCursorElt *) (stuff + 1); + for (i = 0; i < ncursor; i++) + { + cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor, + RT_CURSOR, DixReadAccess); + if (!cursors[i]) + { + xfree (cursors); + client->errorValue = elt->cursor; + return BadCursor; + } + deltas[i] = elt->delay; + elt++; + } + ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client, + stuff->cid); + xfree (cursors); + if (ret != Success) + return ret; + + if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor)) + return client->noClientException; + return BadAlloc; +} + +static int +ProcRenderAddTraps (ClientPtr client) +{ + int ntraps; + PicturePtr pPicture; + REQUEST(xRenderAddTrapsReq); + + REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess, + RenderErrBase + BadPicture); + if (!pPicture->pDrawable) + return BadDrawable; + ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); + if (ntraps % sizeof (xTrap)) + return BadLength; + ntraps /= sizeof (xTrap); + if (ntraps) + AddTraps (pPicture, + stuff->xOff, stuff->yOff, + ntraps, (xTrap *) &stuff[1]); + return client->noClientException; +} + +static int ProcRenderCreateSolidFill(ClientPtr client) +{ + PicturePtr pPicture; + int error = 0; + REQUEST(xRenderCreateSolidFillReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateLinearGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateLinearGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateRadialGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateRadialGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer, + stuff->inner_radius, stuff->outer_radius, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateConicalGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateConicalGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + + +static int +ProcRenderDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < RenderNumberRequests) + return (*ProcRenderVector[stuff->data]) (client); + else + return BadRequest; +} + +static int +SProcRenderQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRenderVector[stuff->renderReqType])(client); +} + +static int +SProcRenderQueryPictFormats (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryPictFormatsReq); + swaps(&stuff->length, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryPictIndexValues (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryPictIndexValuesReq); + swaps(&stuff->length, n); + swapl(&stuff->format, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryDithers (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderCreatePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreatePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->drawable, n); + swapl(&stuff->format, n); + swapl(&stuff->mask, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderChangePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderChangePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swapl(&stuff->mask, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureClipRectangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderSetPictureClipRectanglesReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->xOrigin, n); + swaps(&stuff->yOrigin, n); + SwapRestS(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFreePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderComposite (ClientPtr client) +{ + register int n; + REQUEST(xRenderCompositeReq); + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->mask, n); + swapl(&stuff->dst, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + swaps(&stuff->xMask, n); + swaps(&stuff->yMask, n); + swaps(&stuff->xDst, n); + swaps(&stuff->yDst, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderScale (ClientPtr client) +{ + register int n; + REQUEST(xRenderScaleReq); + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->dst, n); + swapl(&stuff->colorScale, n); + swapl(&stuff->alphaScale, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + swaps(&stuff->xDst, n); + swaps(&stuff->yDst, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTrapezoids (ClientPtr client) +{ + register int n; + REQUEST(xRenderTrapezoidsReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriStrip (ClientPtr client) +{ + register int n; + REQUEST(xRenderTriStripReq); + + REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriFan (ClientPtr client) +{ + register int n; + REQUEST(xRenderTriFanReq); + + REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderColorTrapezoids (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderColorTriangles (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderTransform (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderCreateGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreateGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->gsid, n); + swapl(&stuff->format, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderReferenceGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderReferenceGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->gsid, n); + swapl(&stuff->existing, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFreeGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreeGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddGlyphs (ClientPtr client) +{ + register int n; + register int i; + CARD32 *gids; + void *end; + xGlyphInfo *gi; + REQUEST(xRenderAddGlyphsReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + swapl(&stuff->nglyphs, n); + if (stuff->nglyphs & 0xe0000000) + return BadLength; + end = (CARD8 *) stuff + (client->req_len << 2); + gids = (CARD32 *) (stuff + 1); + gi = (xGlyphInfo *) (gids + stuff->nglyphs); + if ((char *) end - (char *) (gids + stuff->nglyphs) < 0) + return BadLength; + if ((char *) end - (char *) (gi + stuff->nglyphs) < 0) + return BadLength; + for (i = 0; i < stuff->nglyphs; i++) + { + swapl (&gids[i], n); + swaps (&gi[i].width, n); + swaps (&gi[i].height, n); + swaps (&gi[i].x, n); + swaps (&gi[i].y, n); + swaps (&gi[i].xOff, n); + swaps (&gi[i].yOff, n); + } + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddGlyphsFromPicture (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderFreeGlyphs (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreeGlyphsReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCompositeGlyphs (ClientPtr client) +{ + register int n; + xGlyphElt *elt; + CARD8 *buffer; + CARD8 *end; + int space; + int i; + int size; + + REQUEST(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: size = 1; break; + case X_RenderCompositeGlyphs16: size = 2; break; + case X_RenderCompositeGlyphs32: size = 4; break; + } + + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->dst, n); + swapl(&stuff->maskFormat, n); + swapl(&stuff->glyphset, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + buffer = (CARD8 *) (stuff + 1); + end = (CARD8 *) stuff + (client->req_len << 2); + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + swaps (&elt->deltax, n); + swaps (&elt->deltay, n); + + i = elt->len; + if (i == 0xff) + { + swapl (buffer, n); + buffer += 4; + } + else + { + space = size * i; + switch (size) { + case 1: + buffer += i; + break; + case 2: + while (i--) + { + swaps (buffer, n); + buffer += 2; + } + break; + case 4: + while (i--) + { + swapl (buffer, n); + buffer += 4; + } + break; + } + if (space & 3) + buffer += 4 - (space & 3); + } + } + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFillRectangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderFillRectanglesReq); + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + swaps(&stuff->length, n); + swapl(&stuff->dst, n); + swaps(&stuff->color.red, n); + swaps(&stuff->color.green, n); + swaps(&stuff->color.blue, n); + swaps(&stuff->color.alpha, n); + SwapRestS(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateCursor (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreateCursorReq); + REQUEST_SIZE_MATCH (xRenderCreateCursorReq); + + swaps(&stuff->length, n); + swapl(&stuff->cid, n); + swapl(&stuff->src, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureTransform (ClientPtr client) +{ + register int n; + REQUEST(xRenderSetPictureTransformReq); + REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swapl(&stuff->transform.matrix11, n); + swapl(&stuff->transform.matrix12, n); + swapl(&stuff->transform.matrix13, n); + swapl(&stuff->transform.matrix21, n); + swapl(&stuff->transform.matrix22, n); + swapl(&stuff->transform.matrix23, n); + swapl(&stuff->transform.matrix31, n); + swapl(&stuff->transform.matrix32, n); + swapl(&stuff->transform.matrix33, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryFilters (ClientPtr client) +{ + register int n; + REQUEST (xRenderQueryFiltersReq); + REQUEST_SIZE_MATCH (xRenderQueryFiltersReq); + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureFilter (ClientPtr client) +{ + register int n; + REQUEST (xRenderSetPictureFilterReq); + REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->nbytes, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateAnimCursor (ClientPtr client) +{ + register int n; + REQUEST (xRenderCreateAnimCursorReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq); + + swaps(&stuff->length, n); + swapl(&stuff->cid, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddTraps (ClientPtr client) +{ + register int n; + REQUEST (xRenderAddTrapsReq); + REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->xOff, n); + swaps(&stuff->yOff, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateSolidFill(ClientPtr client) +{ + register int n; + REQUEST (xRenderCreateSolidFillReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swaps(&stuff->color.alpha, n); + swaps(&stuff->color.red, n); + swaps(&stuff->color.green, n); + swaps(&stuff->color.blue, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static void swapStops(void *stuff, int num) +{ + int i, n; + CARD32 *stops; + CARD16 *colors; + stops = (CARD32 *)(stuff); + for (i = 0; i < num; ++i) { + swapl(stops, n); + ++stops; + } + colors = (CARD16 *)(stops); + for (i = 0; i < 4*num; ++i) { + swaps(stops, n); + ++stops; + } +} + +static int +SProcRenderCreateLinearGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateLinearGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->p1.x, n); + swapl(&stuff->p1.y, n); + swapl(&stuff->p2.x, n); + swapl(&stuff->p2.y, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateRadialGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateRadialGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->inner.x, n); + swapl(&stuff->inner.y, n); + swapl(&stuff->outer.x, n); + swapl(&stuff->outer.y, n); + swapl(&stuff->inner_radius, n); + swapl(&stuff->outer_radius, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateConicalGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateConicalGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->center.x, n); + swapl(&stuff->center.y, n); + swapl(&stuff->angle, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < RenderNumberRequests) + return (*SProcRenderVector[stuff->data]) (client); + else + return BadRequest; +} + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" + +#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\ + pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\ + if (!pPicture) { \ + client->errorValue = pid; \ + return err; \ + } \ +} + +#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\ + if (pid == None) \ + pPicture = 0; \ + else { \ + VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \ + } \ +} \ + +int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr); + +unsigned long XRT_PICTURE; + +static int +PanoramiXRenderCreatePicture (ClientPtr client) +{ + REQUEST(xRenderCreatePictureReq); + PanoramiXRes *refDraw, *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass( + client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess))) + return BadDrawable; + if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes)))) + return BadAlloc; + newPict->type = XRT_PICTURE; + newPict->info[0].id = stuff->pid; + + if (refDraw->type == XRT_WINDOW && + stuff->drawable == WindowTable[0]->drawable.id) + { + newPict->u.pict.root = TRUE; + } + else + newPict->u.pict.root = FALSE; + + for(j = 1; j < PanoramiXNumScreens; j++) + newPict->info[j].id = FakeClientID(client->index); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + stuff->drawable = refDraw->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + xfree(newPict); + + return (result); +} + +static int +PanoramiXRenderChangePicture (ClientPtr client) +{ + PanoramiXRes *pict; + int result = Success, j; + REQUEST(xRenderChangePictureReq); + + REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess, + RenderErrBase + BadPicture); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); + if(result != Success) break; + } + + return (result); +} + +static int +PanoramiXRenderSetPictureClipRectangles (ClientPtr client) +{ + REQUEST(xRenderSetPictureClipRectanglesReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess, + RenderErrBase + BadPicture); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client); + if(result != Success) break; + } + + return (result); +} + +static int +PanoramiXRenderSetPictureTransform (ClientPtr client) +{ + REQUEST(xRenderSetPictureTransformReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess, + RenderErrBase + BadPicture); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); + if(result != Success) break; + } + + return (result); +} + +static int +PanoramiXRenderSetPictureFilter (ClientPtr client) +{ + REQUEST(xRenderSetPictureFilterReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess, + RenderErrBase + BadPicture); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); + if(result != Success) break; + } + + return (result); +} + +static int +PanoramiXRenderFreePicture (ClientPtr client) +{ + PanoramiXRes *pict; + int result = Success, j; + REQUEST(xRenderFreePictureReq); + + REQUEST_SIZE_MATCH(xRenderFreePictureReq); + + client->errorValue = stuff->picture; + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess, + RenderErrBase + BadPicture); + + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); + if(result != Success) break; + } + + /* Since ProcRenderFreePicture is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return (result); +} + +static int +PanoramiXRenderComposite (ClientPtr client) +{ + PanoramiXRes *src, *msk, *dst; + int result = Success, j; + xRenderCompositeReq orig; + REQUEST(xRenderCompositeReq); + + REQUEST_SIZE_MATCH(xRenderCompositeReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + + orig = *stuff; + + FOR_NSCREENS_FORWARD(j) { + stuff->src = src->info[j].id; + if (src->u.pict.root) + { + stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x; + stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y; + } + stuff->dst = dst->info[j].id; + if (dst->u.pict.root) + { + stuff->xDst = orig.xDst - panoramiXdataPtr[j].x; + stuff->yDst = orig.yDst - panoramiXdataPtr[j].y; + } + if (msk) + { + stuff->mask = msk->info[j].id; + if (msk->u.pict.root) + { + stuff->xMask = orig.xMask - panoramiXdataPtr[j].x; + stuff->yMask = orig.yMask - panoramiXdataPtr[j].y; + } + } + result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderCompositeGlyphs (ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderCompositeGlyphsReq); + xGlyphElt origElt, *elt; + INT16 xSrc, ySrc; + + REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + + if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) + + sizeof (xGlyphElt))) + { + elt = (xGlyphElt *) (stuff + 1); + origElt = *elt; + xSrc = stuff->xSrc; + ySrc = stuff->ySrc; + FOR_NSCREENS_FORWARD(j) { + stuff->src = src->info[j].id; + if (src->u.pict.root) + { + stuff->xSrc = xSrc - panoramiXdataPtr[j].x; + stuff->ySrc = ySrc - panoramiXdataPtr[j].y; + } + stuff->dst = dst->info[j].id; + if (dst->u.pict.root) + { + elt->deltax = origElt.deltax - panoramiXdataPtr[j].x; + elt->deltay = origElt.deltay - panoramiXdataPtr[j].y; + } + result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); + if(result != Success) break; + } + } + + return result; +} + +static int +PanoramiXRenderFillRectangles (ClientPtr client) +{ + PanoramiXRes *dst; + int result = Success, j; + REQUEST(xRenderFillRectanglesReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq); + if (extra_len && + (extra = (char *) xalloc (extra_len))) + { + memcpy (extra, stuff + 1, extra_len); + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) + { + int x_off = panoramiXdataPtr[j].x; + int y_off = panoramiXdataPtr[j].y; + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) (stuff + 1); + int i = extra_len / sizeof (xRectangle); + + while (i--) + { + rects->x -= x_off; + rects->y -= y_off; + rects++; + } + } + } + stuff->dst = dst->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); + if(result != Success) break; + } + xfree(extra); + } + + return result; +} + +static int +PanoramiXRenderTrapezoids(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTrapezoidsReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + + extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); + + if (extra_len && + (extra = (char *) xalloc (extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = panoramiXdataPtr[j].x; + int y_off = panoramiXdataPtr[j].y; + + if(x_off || y_off) { + xTrapezoid *trap = (xTrapezoid *) (stuff + 1); + int i = extra_len / sizeof (xTrapezoid); + + while (i--) { + trap->top -= y_off; + trap->bottom -= y_off; + trap->left.p1.x -= x_off; + trap->left.p1.y -= y_off; + trap->left.p2.x -= x_off; + trap->left.p2.y -= y_off; + trap->right.p1.x -= x_off; + trap->right.p1.y -= y_off; + trap->right.p2.x -= x_off; + trap->right.p2.y -= y_off; + trap++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); + + if(result != Success) break; + } + + xfree(extra); + } + + return result; +} + +static int +PanoramiXRenderTriangles(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTrianglesReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + + extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq); + + if (extra_len && + (extra = (char *) xalloc (extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = panoramiXdataPtr[j].x; + int y_off = panoramiXdataPtr[j].y; + + if(x_off || y_off) { + xTriangle *tri = (xTriangle *) (stuff + 1); + int i = extra_len / sizeof (xTriangle); + + while (i--) { + tri->p1.x -= x_off; + tri->p1.y -= y_off; + tri->p2.x -= x_off; + tri->p2.y -= y_off; + tri->p3.x -= x_off; + tri->p3.y -= y_off; + tri++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); + + if(result != Success) break; + } + + xfree(extra); + } + + return result; +} + +static int +PanoramiXRenderTriStrip(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTriStripReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTriStripReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + + extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq); + + if (extra_len && + (extra = (char *) xalloc (extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = panoramiXdataPtr[j].x; + int y_off = panoramiXdataPtr[j].y; + + if(x_off || y_off) { + xPointFixed *fixed = (xPointFixed *) (stuff + 1); + int i = extra_len / sizeof (xPointFixed); + + while (i--) { + fixed->x -= x_off; + fixed->y -= y_off; + fixed++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); + + if(result != Success) break; + } + + xfree(extra); + } + + return result; +} + +static int +PanoramiXRenderTriFan(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTriFanReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTriFanReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess, + RenderErrBase + BadPicture); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess, + RenderErrBase + BadPicture); + + extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq); + + if (extra_len && + (extra = (char *) xalloc (extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = panoramiXdataPtr[j].x; + int y_off = panoramiXdataPtr[j].y; + + if(x_off || y_off) { + xPointFixed *fixed = (xPointFixed *) (stuff + 1); + int i = extra_len / sizeof (xPointFixed); + + while (i--) { + fixed->x -= x_off; + fixed->y -= y_off; + fixed++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); + + if(result != Success) break; + } + + xfree(extra); + } + + return result; +} + +static int +PanoramiXRenderAddTraps (ClientPtr client) +{ + PanoramiXRes *picture; + int result = Success, j; + REQUEST(xRenderAddTrapsReq); + char *extra; + int extra_len; + INT16 x_off, y_off; + + REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); + VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess, + RenderErrBase + BadPicture); + extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); + if (extra_len && + (extra = (char *) xalloc (extra_len))) + { + memcpy (extra, stuff + 1, extra_len); + x_off = stuff->xOff; + y_off = stuff->yOff; + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + stuff->picture = picture->info[j].id; + + if (picture->u.pict.root) + { + stuff->xOff = x_off + panoramiXdataPtr[j].x; + stuff->yOff = y_off + panoramiXdataPtr[j].y; + } + result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); + if(result != Success) break; + } + xfree(extra); + } + + return result; +} + +void +PanoramiXRenderInit (void) +{ + int i; + + XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource); + for (i = 0; i < RenderNumberRequests; i++) + PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; + /* + * Stuff in Xinerama aware request processing hooks + */ + ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; + ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; + ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform; + ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter; + ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles; + ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; + ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; + ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; + + ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; + ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; + ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; + ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; + ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; +} + +void +PanoramiXRenderReset (void) +{ + int i; + for (i = 0; i < RenderNumberRequests; i++) + ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; +} + +#endif /* PANORAMIX */ diff --git a/xorg-server/render/renderedge.c b/xorg-server/render/renderedge.c new file mode 100644 index 000000000..d0ee30716 --- /dev/null +++ b/xorg-server/render/renderedge.c @@ -0,0 +1,91 @@ +/* + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "renderedge.h" + +/* + * Compute the smallest value no less than y which is on a + * grid row + */ + +_X_EXPORT xFixed +RenderSampleCeilY (xFixed y, int n) +{ + return pixman_sample_ceil_y (y, n); +} + +#define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b))) + +/* + * Compute the largest value no greater than y which is on a + * grid row + */ +_X_EXPORT xFixed +RenderSampleFloorY (xFixed y, int n) +{ + return pixman_sample_floor_y (y, n); +} + +/* + * Step an edge by any amount (including negative values) + */ +_X_EXPORT void +RenderEdgeStep (RenderEdge *e, int n) +{ + pixman_edge_step (e, n); +} + +/* + * Initialize one edge structure given the line endpoints and a + * starting y value + */ +_X_EXPORT void +RenderEdgeInit (RenderEdge *e, + int n, + xFixed y_start, + xFixed x_top, + xFixed y_top, + xFixed x_bot, + xFixed y_bot) +{ + pixman_edge_init (e, n, y_start, x_top, y_top, x_bot, y_bot); +} + +/* + * Initialize one edge structure given a line, starting y value + * and a pixel offset for the line + */ +_X_EXPORT void +RenderLineFixedEdgeInit (RenderEdge *e, + int n, + xFixed y, + xLineFixed *line, + int x_off, + int y_off) +{ + pixman_line_fixed_edge_init (e, n, y, (pixman_line_fixed_t *)line, x_off, y_off); +} + diff --git a/xorg-server/render/renderedge.h b/xorg-server/render/renderedge.h new file mode 100644 index 000000000..644d9d9e5 --- /dev/null +++ b/xorg-server/render/renderedge.h @@ -0,0 +1,105 @@ +/* + * Copyright © 2004 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _RENDEREDGE_H_ +#define _RENDEREDGE_H_ + +#include "picturestr.h" + +#define MAX_ALPHA(n) ((1 << (n)) - 1) +#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) - 1) +#define N_X_FRAC(n) ((1 << ((n)/2)) + 1) + +#define STEP_Y_SMALL(n) (xFixed1 / N_Y_FRAC(n)) +#define STEP_Y_BIG(n) (xFixed1 - (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n)) + +#define Y_FRAC_FIRST(n) (STEP_Y_SMALL(n) / 2) +#define Y_FRAC_LAST(n) (Y_FRAC_FIRST(n) + (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n)) + +#define STEP_X_SMALL(n) (xFixed1 / N_X_FRAC(n)) +#define STEP_X_BIG(n) (xFixed1 - (N_X_FRAC(n) - 1) * STEP_X_SMALL(n)) + +#define X_FRAC_FIRST(n) (STEP_X_SMALL(n) / 2) +#define X_FRAC_LAST(n) (X_FRAC_FIRST(n) + (N_X_FRAC(n) - 1) * STEP_X_SMALL(n)) + +#define RenderSamplesX(x,n) ((n) == 1 ? 0 : (xFixedFrac (x) + X_FRAC_FIRST(n)) / STEP_X_SMALL(n)) + +/* + * An edge structure. This represents a single polygon edge + * and can be quickly stepped across small or large gaps in the + * sample grid + */ +typedef pixman_edge_t RenderEdge; + +/* + * Step across a small sample grid gap + */ +#define RenderEdgeStepSmall(edge) { \ + edge->x += edge->stepx_small; \ + edge->e += edge->dx_small; \ + if (edge->e > 0) \ + { \ + edge->e -= edge->dy; \ + edge->x += edge->signdx; \ + } \ +} + +/* + * Step across a large sample grid gap + */ +#define RenderEdgeStepBig(edge) { \ + edge->x += edge->stepx_big; \ + edge->e += edge->dx_big; \ + if (edge->e > 0) \ + { \ + edge->e -= edge->dy; \ + edge->x += edge->signdx; \ + } \ +} + +xFixed +RenderSampleCeilY (xFixed y, int bpp); + +xFixed +RenderSampleFloorY (xFixed y, int bpp); + +void +RenderEdgeStep (RenderEdge *e, int n); + +void +RenderEdgeInit (RenderEdge *e, + int bpp, + xFixed y_start, + xFixed x_top, + xFixed y_top, + xFixed x_bot, + xFixed y_bot); + +void +RenderLineFixedEdgeInit (RenderEdge *e, + int bpp, + xFixed y, + xLineFixed *line, + int x_off, + int y_off); + +#endif /* _RENDEREDGE_H_ */ |